前幾天有個朋友問我:自己有一個idea不錯的項目,也把基本的框架寫好了,想貢獻到Openstack社區,卻不知道應該怎么做。正好之前我有過類似的經歷,那么來分享一下我是如何向Openstack社區提交一個新項目。
Openstack的整套系統就是一個開源項目的“大雜燴”,社區把所有項目划分為兩類:核心和孵化。除非出身特別牛逼或者從其他核心項目獨立出來的項目會在設計之初就被列為核心項目(例如Nuetron,Ironic等);其他項目一般划分到孵化類,在通過一個或多個大版本的發展后,如果變得成熟滿足預期並被社區接受,就會轉正成為核心項目(例如Savana,Designate等)。如果你想查看當前有哪些核心和孵化項目,可以前去github上查看,它們分別托管在github的openstack和stackforge兩大項目下:每個核心項目幾乎都是來自工業界IT巨頭們的貢獻,例如Swift項目來自於Rackspace,Nova項目來自於NASA,Horizon項目來自於HP…
簡單介紹一下我提交的新項目的來歷:由於我們的IaaS服務跨越多個Region,並且有較為復雜的DNS解析需求,因此我們很早就使用了當時仍在孵化中的designate項目(DNSaaS),用於管理UnitedStack內部的DNS服務。我發現社區並沒有提供用於管理Designate服務的puppet module,於是就寫了一個puppet-designate,隨着代碼的日益完善,已經可以滿足內部designate服務的管理,然而社區卻一直沒有開發puppet-designate module的計划。公司文化一直支持開源,我也一直活躍在社區中,但以往都是提交某個項目的bugfix或者blueprint,我心想何不嘗試提交一個新項目到社區?
前期准備工作
那么在試圖說服社區接受自己的項目前,第一步得先規范自己的代碼。
不同於個人項目,社區對於代碼的規范要求很高。我列出以下幾個注意點:
- 完善的代碼文檔:例如README,參數說明,每個自定義資源類型或者類的使用舉例,復雜邏輯的解釋,未來需要重構的加上todo標注等等;
- 規范的代碼格式:首先不能有語法錯誤,其次是代碼風格要和社區一致,這些都有工具來檢查,主要問題是在代碼風格上,空2格還是空4格,雙引還是單引,不是隨心所欲的;
- 合理的代碼結構:主類中該放哪些部署邏輯,各服務的組件的部署邏輯該怎么划分,數據庫初始化邏輯又該放在哪,都是有要求的;
- 完善的測試代碼:社區項目都是以測試驅動的,有的項目甚至先有的是測試代碼,如果你妄圖向社區提交一段沒有附帶測試的代碼,其后果就是:紅色粗體不解釋的-1。
溝通和反饋
大約花了一個周末的時間,終於把上述工作做完了,那接下來要做的就是說服社區:接受puppet-designate項目。 我分析了一下Openstack社區的一個新項目大致可以分為兩類:全新和已有項目。例如,Heat,Ceilometer就屬於全新項目,先在ML上開個頭,開始討論架構,API的設計等等諸多細節,然后眾人分領開發工作,接着開始編碼最終實現。而Swfit,Nova就屬於舊有項目,從其他公司貢獻出來的時候,已經比較成熟或者已經有比較完整的架構了。puppet-designate就屬於后者,Openstack社區所有相關的puppet項目歸屬於puppet-manager-core 組管理,當時的PTL是Puppetlabs的Dan Bode。
第一步,我需要發送一封郵件到社區的郵件列表中來告知參與這個項目的所有成員:我准備提交一個puppet-designate項目來管理designate服務。
這里有一點很重要,就是了解在這個郵件列表中,誰說了算:)。
簡單解釋一下,每個項目都有一個PTL以及相關的core members,他們是項目的主要貢獻者。那么如何查詢到具體有哪些人呢?可以在https://review.openstack.org的Groups分類中找到。
於是,我把郵件發送到社區的ML同時抄送給了PTL和其他幾位非常活躍的core members。郵件里我說清楚地說明了puppet-designate的目的和完成度,以及附帶一個github代碼地址,以便review。
鑒於國內和國外的時差,郵件第二天得到了回復,得到了PTL和幾位core member的肯定,不出所料的是,我的代碼被指出了一堆問題,接下來需要進一步地改進。
由於時差的關系,我與社區的協作效率是不高的,在經過大約一周時間的郵件溝通和多次修改后,代碼終於通過了這幫有強迫症的工程師的review。
提交到openstack-intra/config
雖然代碼通過了社區的批准,但這並不意味着puppet-designate項目就能立馬出現在stackforge中了。接着,我開始閱讀社區的CI文檔,了解到社區CI系統的管理工作是通過config項目來完成的,Openstack的整套CI系統以及我們所看到的Openstack主站以及其他相關站點都是通過puppet來管理的,該項目就包含了用於管理和配置的modules和manifests,屬於openstack-intra組負責。Openstack-intra組的主要工作是負責Openstack站點和CI系統的開發和維護。
因此,我需要向config項目提交一個新patch來添加puppet-designate項目,這個PatchSet看起來是這樣的:
首先,修改modules/gerritbot/files/gerritbot_channel_config.yaml文件,這個配置文件用於管理各項目的gerritbot,當發生指定的事件后,IRC上的gerritbot會發送通知:
接着需要修改modules/openstack_project/files/jenkins_job_builder/config/projects.yaml,告知Jenkins在處理來自gerrit的puppet-designate patchset時,需要執行哪些job:
然后還需要修改modules/openstack_project/files/zuul/layout.yaml,告知zuul在做check和gate工作的時候要執行哪些job。:
最后修改modules/openstack_project/templates/review.projects.yaml.erb文件,告知gerrit 新建一個stackforge/puppet-designate的項目,並且去github上拉去初始的puppet-designate代碼。
等待Approve
在提交了這個patchset后,我在IRC上去通知PTL和其他成員幫我+1,最后還要得到openstack-intra組core member的approve才行,於是我又去#openstack-intra頻道里找人,終於找到一位哥們來幫我Approve。好事多磨,結果最后Gerrit在做merge操作時,Zuul所運行得gate測試報了一些莫名的錯誤,始終不讓這個patchset merge。那哥們說:沒事,明天前我會解決的。終於,在HK的Havana Summit前,puppet-designate項目出現在了Openstack社區的孵化項目里:https://github.com/stackforge/puppet-designate。
小結
雖然參與Openstack的社區開發已經近三年,但這是我第一次向社區提交一個新項目,通過這次經歷,我有以下幾點感觸:
1. 對於社區的CI系統有了更進一步的了解,因為過去當我輸入git review時,整套CI是對我來說是透明的,我根本不知道底層的CI系統各服務之間是如何交互的;
2. 其次是學會和社區溝通,如何清晰地表明自己的觀點,如何說服他人,如何找到能拍板的人,若能做好這三點有事半功倍的作用;
3. 最后一點,對於代碼的質量要求和規范上有了更深刻的理解,有時候我的同事會不理解我在做code review時為什么會對格式要求那么苛刻,其實我是水瓶座,只是這些習慣是在做社區開發的時候被逼出來的 :)