【精華貼】開源大神總結的openEuler 5步入門法
引言
openEuler社區已經建立起來了,也有不少合作伙伴, OSV, ISV等參與進來。整個社區的治理結構也初步建立了起來。但畢竟是一個年輕的社區,因此有一些流程方面還有待優化,很多文檔還有待于完善。
鑒于有很多希望參與到社區里的工程師對整個社區的運作流程,開發流程還比較陌生,我總結了一個文檔來幫助一個工程師更容易的參與到社區中。
openEuler社區概要
openEuler的主站點是https://openeuler.org/
主站點主要是提供一些入口,對于工程師來說,最重要的應該是下載鏈接:
https://openeuler.org/zh/releases.html
除了下載以外,對工程師來說,真正的社區開始之旅的起點:
https://openeuler.org/zh/developer.html
這個鏈接給大家做了一個簡要的引導,但是不幸的是,對于一個新人來說,信息量依然非常大,可能有些摸不到頭腦。下面,就讓我帶著大家一步步的化繁為簡的做一次openEuler參與之旅吧。
法律合規是第一步,也是最重要的一步
“開源”這兩個字眼雖然在很大程度上代表了自由,奔放,隨心所欲,符合碼農天生追求“自由飛翔”的特質。但是開源并不是法外之地,因此法律合規是一個社區健康發展最重要的前提,沒有之一。因此,任何一個人,如果想要參與到openEuler項目中,第一步就是要簽署CLA協議。協議的簽署網址是:
https://openeuler.org/en/cla.html
雖然協議并不復雜,但是作為一個碼農,通常我都對這類法律文書都是免疫的,我們連需要給自己賠錢的保險合同都不會多花上一分鐘時間看上一眼,對于這種需要自己奉獻的條款又怎會關注呢?還有更關鍵的是,如果碼農看懂了法律文書,那還是碼農么? 雖然這很大程度是我們碼農的現狀,但是我還是建議大家認真閱讀一下協議,了解一下權益范圍并沒有壞處。
我們是開源的
openEuler社區原則上只接受開源協議的軟件,哪些開源協議是社區認可的開源協議呢?大家可以參考下面的網址。這個網站上所列舉的開源協議都是openEuler社區所能接納的協議。
https://opensource.org/licenses/alphabetical
對于社區本身,我們默認使用mulan V2協議,https://opensource.org/licenses/MulanPSL-2.0,這是一個非常友好的開源協議,也歡迎大家更多的使用這個協議來開發開源軟件。
我能做點什么
在簽署完CLA協議,了解我們所認可的開源協議范圍以后,需要完成社區的注冊。
由于openEuler本身是開放到gitee.com上,因此需要大家在gitee上擁有賬號。我們也衷心希望gitee能成長為世界級的代碼托管平臺。
當大家完成了這些過程以后,就需要考慮在社區里具體能做點什么了。參與社區有很多種方法和形式,如果總結起來,大體有下面的四類:
- 提交一些需求,或者bug,簡單來說就是發覺哪里用的不爽,直接提要求。 或者在用openEuler的過程中發現了一些問題,然后需要在社區把這個問題提出來。
- 為社區修正bug,這是更高一個層面的參與社區了,在這個層面,參與者實質上是以一個開發者的姿態進入到了社區中。一般我們都提倡,除了提出問題,更期待大家能解決問題。
- 貢獻軟件包,發現openEuler缺失了一個軟件包,幫openEuler把這個軟件包補上。實際上貢獻軟件包的過程就是幫助openEuler提供更豐富功能的過程。希望隨著大家的參與,openEuler能夠成為一個“無所不有”的軟件生態系統。
- 開發新軟件,有自己的一些想法,獨立開發一個全新的軟件,并將這個軟件貢獻到openEuler社區,成為openEuler發行版本中的一份子。
我們就一個個來看看這4種參與方式如何進行把。
網站和社區
在具體討論這四類參與方法之前,我先給出三個網址鏈接。
第一個網址是openEuler的門戶網站,是供大家獲取一些通用信息的地方,前面已經提到過了。而真正我們所謂的“社區”則是體現在2,3這兩個網址上。
這兩個網址互相有鏈接,它們分別長這個樣子:
長得這么像,為什么要分兩個網址呢? 兩者有什么分工呢?我們在后續講解中會慢慢的給大家說清楚。
不論怎么樣,這兩個網址,以及里面的內容將會是社區工作的主要場所。雖然人機界面并不友好,但我相信對于碼農來說這不是一個大問題,因為碼農們的世界從來都不曾經友好過。
參與方式一:提交需求&bug
最基本參與社區的方式當然是要先用一用社區的物件,看看還有哪些需要改進的地方。提出一些有價值的建議和意見了。這幾乎是最簡單參與社區的方式了。
在社區中,我們提交問題都是通過“issue”機制來進行。但是在提交之前,提交人得先明確這個issue要提交給誰。在社區里,我們是一個個“repo”來對功能進行分組的。比如我們著名的Linux操作系統的“內核”(kernel)就有一個獨立的“repo”(通常我們稱之為“倉”)。
如果你發現了一個內核的問題,或者需求,那么就需要找到內核相關的repo地址:https://gitee.com/openeuler/kernel
它的界面這個樣子。
其中紅圈里大家可以看到Issues這個字樣,這就是我們所有問題&bug&需求的入口了。點進去以后可以看到:
紅圈位置的按鈕就是我們建立一個新的Issue的入口。
進入以后,就可以提交issue了,有分類欄來說明這個issue屬于什么類別。
在這里,可能會有一些同學們會問:為什么沒有一個bugzilla?這是一個拷問靈魂的問題,是呀,為啥沒有建立一個工程師們更為熟悉的bugzilla呢?我沒有辦法給出一個合理的解釋,不過目前看越來越多的項目都逐步通過issue,PR等機制來管理項目,如果再獨立構建一個bugzilla系統,那么和PR,Merge合入等的工作就需要進行交聯,復雜度會增加,因此目前我們還是選擇通過issue來管理bug和需求。
這里有一個小問題,我的問題需要提交到哪里去呢?
Issue的歸宿
總體來說,提交issue分如下幾類:
- 具體軟件的問題直接提交到相關的軟件repo中,比如上面所提到的kernel的repo中。
- 社區中的一些基礎設施用的不爽,比如網頁看起來不順眼等,提交到https://gitee.com/openeuler/infrastructure,基礎設施組。
- 如果是一些社區治理方面問題,例如技術選型,軟件的增加,刪除,gnome和KDE哪個更圖形界面原教旨主義一些等問題可以提到https://gitee.com/openeuler/community里。
- 如果你實在不知道該提到什么地方,就統統提交到https://gitee.com/openeuler/community-issue,這里會為你排憂解難。
更為詳細的issue提交流程可以參見如下的專業講解。
https://gitee.com/openeuler/community/blob/master/zh/contributors/issue-submit.md
參與方式二:修復bug
在社區里,通常我們希望提出問題并同時解決問題,如果有一個問題,當然最好的情況是同時提供問題解決的patch補丁。我們以社區的輕量化容器引擎iSulad為例,https://gitee.com/openeuler/iSulad,假定我們需要為iSulad提交一個patch補丁,基本流程如下:
第一步:建立自己的分支
在紅圈處先要Fork一個“分支”到自己的賬號下。如果大家不清楚fork的含義,建議學習一下git的使用方法。在這里要提一句,無論如何,現代工程師要理解git的開發模式,不了解git在當代幾乎會寸步難行。
第二步,修改代碼并生成Pull Request(簡稱PR)
當fork完畢以后,大家可以在下圖的紅圈1中發現,目錄已經從openEuler切換成了自己的賬戶。
接下來,就可以在自己的“分支”上進行代碼的修改了。
修改完以后,點擊紅圈2中的+Pull Request,這可能是提交代碼中最關鍵的一個步驟,這里會正式生成一個patch并送到https://gitee.com/openeuler/iSulad這個原始社區。
比如我修改了一個函數,增加了一行printf(“hello, world”)這行代碼。那么PR看起來就是這樣的:
你需要為這個PR起一個名字,同時填寫一個說明。分別是紅圈1和2,最后確定patch沒有問題以后,點擊紅圈3中的“創建”按鈕提交。
你會在openEuler/iSulad上看到你所提交的PR,紅圈一表明你提交的PR已經進入了iSulad的社區,紅圈2中的數字228是這個PR的編號。同時這個PR的URL是:https://gitee.com/openeuler/iSulad/pulls/228
至此,作為一個patch提交者的工作就做完了,你剩下所要做的事情就是耐心的等待iSulad開發組的maintainer來審核你的patch,比如我相信今天晚上他會非常詫異,誰提交了這么一個stupid的patch,而且公然用useless demo這樣的PR題目來挑戰他脆弱而敏感的maintainer神經。
因此,你的PR可能有三種命運:
- 被iSulad社區接受。
- 被iSulad社區殘忍的拒絕。
- 提出修改意見,修改后再提交PR。goto 1
不僅僅是可以提交代碼的PR,任何修改,甚至是為readme修正了一個拼寫錯誤,所遵循的流程都一摸一樣。
更細致,更專業的介紹請參考:
https://gitee.com/openeuler/community/blob/master/zh/contributors/Gitee-workflow.md
這里有一步步的教程引導大家來提交。
另外,PR的提交也在很大程度上體現了提交者的專業能力和親和力。Be nice很重要,下面的鏈接可以幫助大家理解如何更優雅的提交一個PR。
https://gitee.com/openeuler/community/blob/master/zh/contributors/pull-request.md
好了,恭喜您,至此,您的第一次真正意義上的社區開發之旅就畫上了一個完美的句號。
讓我們進入下一個挑戰環節,為openEuler增加一個新的軟件包。
參與方式三:貢獻軟件包
在能夠為openEuler貢獻一個軟件包之前,需要我們的開發者理解兩個基本的概念:
- 什么是Linux的軟件包。或者說Linux操作系統是怎么組織的。
- 如何制作一個軟件包。
OS是怎么組織的
顯然這是一個非常巨大的話題,可能需要寫一本書來講OS是怎么組織,怎么構建出來的。在這里我只能簡要的給大家介紹一下。
實際上,一個OS系統的組成既復雜,也簡單。
何所謂簡單呢,其實OS本質上就是一堆安裝包的大雜燴,就類似我們不論使用Windows也好,使用Android也罷,或者使用Linux,我們都經歷過“安裝”這個概念,就是從網上,或者是從“倉庫”中下載一個安裝包,然后安裝到系統上,所以大家可以看到安裝的“進度條”。實際上,一個OS的安裝過程和在andorid上安裝微信的道理一摸一樣。只不過所謂的安裝OS是需要一次性的要把幾千個軟件包按照一定的順序安裝到機器中。
那么OS所謂的組織很復雜呢,大家可以想象以下,幾千個軟件,他們之間會有很多的交聯關系,通常我們叫做“依賴關系”,就好比,如果你想用微信小程序,那么前提是必須先得有微信,那么安裝微信小程序的前提就是必須要先安裝微信。因此,即使我們考慮一個OS的安裝過程,其實也是非常復雜的,必須要精確的計算哪些軟件需要先安裝,哪些需要后安裝。隨著系統的膨脹,那么這些軟件包之間就形成了復雜的網狀關系。即使我們這些行業內的人都為此頭痛不已。
講了這么多,和我們的openEuler社區開發有啥關系呢?其實,上面的講解是要讓大家理解,任何OS的基本零件就是軟件包,就類似組成人體的基本零件是細胞一樣。這一個個軟件包就是構成OS的一個個基本零件。
在Linux的世界,有兩種基本的安裝包格式:
RPM
這個格式是redhat, suse, WindRiver, openEuler等所選用,目前在企業市場,基本是以這些廠家為主,因此rpm格式在商用企業市場用的比較多。
Deb
這個格式是debian, Ubuntu, android使用的,目前在desktop,終端側用的比較廣泛。
這兩種格式本身沒有什么優劣之分,只是不用廠商的選擇而已。當然,對于客戶,開發者來說,世界被割裂成為兩個互不兼容的部分總歸是一種不必要的殘忍。對于這個問題社區也有不同的嘗試,但目前為止還沒有出現某個大一統的軟件包格式能夠終結這個分裂的世界。
不過幸好我們有容器,很大程度上,容器的出現緩解了這個問題。那未來能不能找到一條優雅的技術道路將這些不兼容,將這些復雜的軟件包的依賴帶來的諸多痛苦一并解決掉呢?我把這個問題留給本文的愛好者吧,也許在你們中間就會出現這樣的“歷史終結者”。
所以,一個軟件從源代碼到能進入到我們的OS安裝光盤中,要經歷三個步驟。
第一步:
源代碼開發階段,也就是寫程序的階段。這個階段可以在任何地方,可以在github,gitlab, gitee等代碼托管平臺上,也可以是自己的筆記本電腦上。
第二步:
將代碼編譯,生成二進制可執行程序。并且制作RPM軟件包,其中“制作RPM”的過程實際上也是一種“編程”,只不過使用的是一種定義好的腳本語言,“程序”是一種叫做spec的文件。講真,spec的編寫是非常不符合老派程序員思維的,那種分段式的,跳躍式的,宏式的寫法絕對挑戰老派程序員的神經。所以,我們有很多很好的程序員,但是卻很少有程序員能將一個程序真正制作成一個rpm包(或者deb包)。希望大家能挑戰一下自己,成為一個RPMer。真的,不難,但是夠你手忙腳亂一陣的。
我們有一個rpm的編寫規范,可以供大家參考。
https://gitee.com/openeuler/community/blob/master/zh/contributors/packaging.md
第三步
將這些rpm包放在iso中,做成安裝光盤。這一步一般的工程師不用感知,后臺有自動化的系統來完整整個工作,而且相關的工具我們也會開源到openEuler中。也就是說,后續任何人都可以簡單的為自己構建一個My Linux。
那就讓我們看看如果你有一個項目在github上,我們如何將它最終轉變成為安裝光盤上的一個軟件包吧。
首先,你得有一個組織
人生活在社會中,無時無刻不屬于某個組織,并受到一些人的領導,比如白天,你需要屬于某一個公司組織,晚上,你需要屬于一個家庭組織。
社區也一樣,在你想要把一個軟件做成軟件包放到openEuler系統中之前,你需要明確兩件事情:
- 你自己屬于哪個組織?
- 你要加入的這個軟件包屬于哪個組織?
在openEuler社區中,它的基本“組織”單元是SIG組,也就是special interest group,我至今沒有弄明白為什么“興趣”要加上“特殊”這個極易產生歧義和聯想的前綴。不過anyway,如果你想有歸屬感,你有兩種選擇:
- 尋找到和你具有同樣“特殊愛好”的小組,然后申請加入。
- 你的愛好太“特殊”以至于目前還沒有志同道合的人,自己申請建一個。
openEuler所有的SIG組都在https://gitee.com/openeuler/community/tree/master/sig列出來,大家可以參考。
如果你有意愿,同時也展示了對某些“特殊愛好”有著深厚的積累或者驚人的天賦,那么歡迎你參照https://gitee.com/openeuler/community/blob/master/zh/technical-committee/governance/README.md完成一個新的SIG組的申請。我不得不說,這個流程不光看起來有一些復雜,也不友好,實際操作起來也是這樣的。但我相信這難不倒碼農,我們不就是為了制造這些復雜和不友好而生的嗎!
最后一步,當創建完SIG的PR申請以后,需要到技術委員會(TC)的例行會議上進行評審,在https://gitee.com/openeuler/community/tree/master/zh/technical-committee可以找到TC委員會的基本信息,還有聯系方式,大家可以訂閱TC的郵件列表來獲取一些動態,特別是例會的信息。
既然說到了TC(技術委員會),我們就簡要講一下openEuler的組織結構吧。
組織結構
openEuler是一個完全開放的組織架構,而且非常簡單,https://gitee.com/openeuler/community這里可以看到基本的情況。
我想這副圖已經說的很清楚了。
開始干活,先要弄明白干什么
當然,即使你完全不屬于任何一個SIG組,理論上也能提交一個軟件包到openEuler中,只是被接受的概率相對較低而已。其主要原因是很難來評估相關提交的質量,SIG組很大的意義就在于一些專業方面的人能夠為每次提交做出質量的保證。
軟件包本身必須是要屬于某一個SIG的。以我自己常用的一個軟件包為例,我每次寫完程序以后,都總會執行一下cloc這個命令,看一下今天又新增了多少行代碼,以期獲得一下碼農與生俱來的成就感,并中和一下寫PPT帶來的空虛和乏力感。
顯然cloc是一個開發類的工具,幫助碼農統計代碼行,幸運的是,擁有同樣“特殊愛好”的人并不在少數,他們建立了一個dev-utils的SIG組,https://gitee.com/openeuler/community/tree/master/sig/dev-utils,我們可以將cloc這個軟件歸屬于這個SIG組。
如何把大象放到冰箱里
一般來說,增加一個軟件包到openEuler中,需要如下的幾個大步驟
- 讓系統為你的cloc軟件包建立一個“倉”,也就是git倉。
- 上傳制作cloc軟件包所需要的“零件”
- 將這個軟件系統加入到openEuler的自動化編譯系統中,由系統自動化構建出軟件。
建倉
建倉其實就是提交一個PR,一般來說需要修改三個文件。
- https://gitee.com/openeuler/community/blob/master/sig/dev-utils/README.md
- https://gitee.com/openeuler/community/blob/master/sig/sigs.yaml
- https://gitee.com/openeuler/community/blob/master/repository/src-openeuler.yaml
修改第一個文件README.md將你要加入的cloc軟件的名字和地址放上去。
修改sigs.yaml文件,將cloc軟件增加到dev-utils這個SIG分組下面。
修改src-openeuler.yaml將cloc增加到src-openeuler里。
你要做的就是照貓畫虎的把這三個文件修改了,然后提交PR就可以了。剩下的就是等待“命運的裁決”。
當申請的結果被批準以后,你所需要的“倉”就會被系統自動建立起來,對于cloc來說,它的代碼倉的位置在https://gitee.com/src-openeuler/cloc,這是PR被批準以后由系統自動為我建立的。
剩下的時間,你就可以開始真正上傳制作cloc軟件的原材料了。
上傳軟件包
一般來說,一個軟件只需要上傳兩個“原材料”就足夠制作一個軟件包了。如下圖所示:
第一個材料:首先要上傳這個軟件包的spec文件,也就是告訴構建系統如何編譯,制作cloc這個軟件包。
第二個材料:cloc的源代碼壓縮包。
其它零件:如果spec中需要有patch,那么也需要把相關的patch文件上傳到倉中。
上傳完畢一個軟件包所需要的原材料,下一步就是要把這些原材料加入到構建系統中,使之能夠被真正編譯,生成一個實際的軟件包。
加入構建系統
openEuler現在使用obs作為構建工具系統,大家可以參考下面的這個鏈接把自己的軟件加入到obs中
https://gitee.com/openeuler/community/blob/master/zh/contributors/create-obs-package.md
加入到構建系統中,就意味著你的軟件可以被系統自動編譯,自動生成rpm包,繼而在后續的openEuler發行版本中出現。
TIPS
在整個過程中有幾點需要開發者要注意:
- 能夠本地構建:提交的軟件包首先要在自己的筆記本,或者服務器上能夠編譯通過。也就是如果你的軟件包在本地無法構建成功,那么上傳到openEuler社區也不會構建成功。因此。我們建議最好能下載最新的openEuler版本,安裝以后通過rpmbuild等命令來進行構建驗證。
- 保證軟件包可用:軟件除了能夠被編譯和生成軟件包,還要能正確運行,因此,在本地環境要保證制作出來的軟件包能夠:
- 正確的安裝
- 正確的卸載
- 正確的升級
- 軟件的功能是正常的。
- 保證多體系架構支持:openEuler目前支持x86_64和ARM64兩種指令集,因此在構建過程中需要能夠保證軟件包在這兩種環境下都能被正確編譯和運行。雖然ARM64環境可能并不那么容易獲取,但幸運的是,一般性軟件在這兩個系統上沒有那么大的差異。
- 保證正確的依賴關系:一個軟件通常都需要依賴其它的一些軟件才能運行,比如所有軟件都需要依賴glibc這個庫來執行,一些復雜的軟件可能會依賴很多軟件包來提供功能。這些軟件包可能已經在openEuler社區中有了,也可能沒有。如果沒有,那么就需要同時在openEuler社區中將這這些軟件包補齊才行。比如cloc這樣一個小軟件,缺需要依賴如下的幾個perl的軟件包:
也就是說在提交cloc軟件包的同時,也需要同時提交這幾個軟件包,這樣才能保證cloc能夠被系統正確的編譯和構建出來。
- 保證spec文件的規范性:要保證spec文件是“規范”的,避免將外部的spec直接引入到openEuler中,因為如前所述,因為選擇包的范圍,依賴關系,版本等都不相同,同時保證所有軟件包spec是一致的,請依照前面的rpm制作規范中的內容來書寫spec文件。
因此,制作一個軟件包,有的時候遠比想象中的要復雜一些。但好在這并不是一個難度很大的事情,只需要提交一個軟件包,走一遍流程,后續就會輕車熟路了。
參與方式四:開發新軟件
上面講的過程都是怎么給“別人”的軟件提意見,怎么把“別人”做的軟件添加到openEuler社區。但是每一個真正做軟件的人內心都希望能擁有屬于自己的作品,那么如何建立自己的作品,如何將自己的作品融入到openEuler社區呢?
將自己的作品融入到openEuler社區有如下兩種方法:
方法一:在其它社區開發,集成到openEuler中
假定你已經在github,gitlab或者gitee上擁有了自己的項目,那么只需要按照參與方式三那樣,將軟件加入到src-openeuler這個repo倉就可以了。
方法二:在openEuler社區中開發,在openEuler中集成
另外一種方法是,直接在https://gitee.com/openeuler中建立項目,類似將項目“托管”到openEuler社區。比如現在社區中的iSula和A-Tune這樣的項目就是這樣的模式。
至此,我相信所有人都能明白了為什么openEuler會建立兩個倉:
https://gitee.com/src-openeuler
openeuler這個倉是存儲所有“原生態”的軟件,也就是為原創性的軟件提供一個展示的舞臺,或者是一個孵化器平臺。
而src-openeuler則是為openEuler的release發行版提供生成rpm包等構建信息等的地方。
因此,當一個很有夢想,很有情懷的工程師突然有一天有了一個很棒的idea,那么他可以依照下面的過程來深度參與到openEuler中。
- 在TC委員會的例會meeting中申請一個開源項目,比如項目名稱叫做“broken_dream”。
- 如果TC委員會認為這是一個很好的idea,并且認為值得為破碎的夢想提供一個機會,那么我們會在https://gitee.com/openeuler中建立一個repo,網址就是https://gitee.com/openeuler/broken_dream
- 這個項目在openeuler中持續開發和孵化,直到有一天,大家認為broken_dream已經足以成熟到為所有人提供破碎的夢想服務了,那么就可以在src-openeuler中建立一個倉,為broken_dream提供相關的spec文件,制作成為一個rpm。
- 最終broken_dream.rpm會隨著openEuler的發布版本走遍全世界,為世界人民提供broken_dream功能。
我始終認為,一個工程師,在他的職業生涯中,至少要有一個,哪怕只有一個項目和他自己的名字是息息相關的。只有這樣,才能在孫子,孫女騎在我們背上,問我們這輩子做的最棒的事情是什么的時候,我們可以讓他們爬下來,然后直起身,看著他們天真無邪,對未來充滿憧憬的大眼睛,認真的問他們:你知道broken_dream的作者是誰嗎?
最后,我要感謝openEuler社區中每一個貢獻者,特別是文檔的撰寫者們,文檔對于碼農們來說永遠是痛苦的源泉,但正是各位文檔的撰寫者的辛勤工作,才使得本文能夠有一個機會為大家呈現一個完整的openEuler參與之旅。
openEuler社區歡迎大家!