| RFC-0095:在樹狀結構外建構及組裝工作站 | |
|---|---|
| 狀態 | 已接受 |
| 區域 |
|
| 說明 | 建立工作流程,讓使用者在 fuchsia.git 外部建構及組裝 Workstation 產品。 |
| Gerrit 變更 | |
| 作者 | |
| 審查人員 | |
| 提交日期 (年-月-日) | 2021-03-24 |
| 審查日期 (年-月-日) | 2021-05-19 |
摘要
注意:這項 RFC 已由 RFC-0220 取代,後者已淘汰工作站產品。這項 RFC 會保留供後代參考,但我們不會再繼續實作。
工作站產品 (定義為 workstation_session、ermine、終端機和簡單瀏覽器) 目前是在 Fuchsia 來源樹狀結構中建構及組裝。Fuchsia 平台與工作站產品之間沒有明確區別。這表示平台和產品必須同時建構,才能組裝成最終產品。我們建議打破這種耦合關係,讓 Workstation 元件與平台分開建構,並在 Fuchsia 來源樹狀結構外組裝最終產品。這項提案並非要從 Fuchsia 來源樹狀結構中移除 Workstation 產品的實作項目,而是著重於樹狀結構外的產品設定和組裝作業,這也是相關問題。這項工作將為最終完全移出樹狀結構的 Workstation 產品奠定基礎,但這超出本文範圍。
請務必留意,終端機是 Workstation 產品的基本元件,但終端機也用於 Workstation 產品以外的其他產品。因此,終端元件的開發作業仍會保留在 fuchsia.git 中,並由 Workstation 做為平台的一部分使用,直到我們對這個元件的未來做出進一步決定為止。
提振精神
目前,您無法在 Fuchsia 上建構及組裝產品,必須同時建構整個 Fuchsia 平台。我們可以使用 SDK 在 fuchsia.git 外部建構個別元件,但這些構件必須回流至 Fuchsia Global Integration,才能組裝成最終產品。我們希望能夠提供穩定的平台版本,讓產品建構於其上,而不需存取 Fuchsia Global Integration。
在樹狀結構外建構產品時,仍有許多未知因素,因此我們想先從 Workstation 產品著手。Workstation 產品並非支援生產環境的面向使用者產品,而是開發人員的參考資料,以及平台功能早期採用和測試的環境,因此在這個階段,我們對效能變慢的容忍度較高。Workstation 產品也旨在成為愛好者探索 Fuchsia 的環境;移除建構整個平台的需求後,開發人員就能更輕鬆地使用 Fuchsia。
設計
以 Standalone Image Assembly Tool RFC-0072 為基礎,將工作站移出樹狀結構建構程序,這項提案假設這項工具存在。
存放區
Workstation 存放區的原始碼將託管於 git-on-borg。將程式碼託管在 git-on-borg 上,可讓我們使用現有的 Fuchsia 基礎架構和工具,專注於建構及組裝產品。
在本文件其餘部分,工作站.git 將參照代管工作站產品程式碼的存放區。
基礎架構
本專案的重點是建構及組裝樹狀結構外的 Workstation 產品,因此在我們找出做法之前,不會將元件開發作業移出 fuchsia.git。由於元件開發作業仍會保留樹狀結構內,我們可以依賴現有的測試和建構基礎架構,確認 Workstation 產品不會回歸。平台、SDK、experiences.git 和其他依附元件的新版本將透過指令碼手動推出,讓團隊專注於當前問題。當我們開始將元件的開發作業樹狀結構外時,需要重新檢討持續整合的作業方式。
平台每日建構作業需要自動化,但我們可以沿用現有的 Fuchsia 基礎架構。您需要建立每日建構工具,建構組裝工作站產品所需的套件,並將這些構件上傳至某個儲存空間存放區。這項工作流程的技術設計仍待確定。我們會先諮詢基礎架構和安全團隊,再開始處理這項工作。
建構 Workstation 產品 (而非核心) 可確保我們擁有產品組裝所需的所有構件,即使我們目前未建構這些構件也沒關係。我們在樹狀結構外建構的構件,會取代隨平台推出的構件。這樣一來,我們也能使用現有的工作站建構工具,盡量減少需要管理的額外基礎架構。
依附元件管理
工作站存放區會結合使用 Git 子模組和 Bazel 工作區,進行依附元件管理。Git 子模組會用於提取外部存放區,而 Bazel 則會用於下載建構作業所需的預先建構項目和工具鍊。
Bazel 的工具鍊會搭配工作區規則使用,下載各個建構規則所需的適當預先建構項目。目前的一項限制是,許多預先建構的項目都儲存在 CIPD 中,且需要使用 cipd 指令列工具。初始原型需要 cipd 工具位於開發人員路徑的某處。我們正在積極尋找替代方案,且認為這不會是長期要求。
目錄結構
工作站存放區的目錄結構與 fuchsia.git 目錄結構非常相似,可確保 Fuchsia 開發人員的一致性。根目錄會包含專案所需的各種中繼資料檔案,以及下列頂層目錄。
- //src - Source code used to build the Workstation 產品.
- //tools - scripts and tooling to support the build.
- //src/experiences - 現有的 experiences.git 存放區。
- //prebuilt - any prebuilts that are needed.
- //third_party - third party code that is used by the src directories.
建構系統
工作站產品將使用 Bazel 建構系統建構。使用 Bazel 的決定與 fuchsia.git 不同,後者使用 gn/ninja。這項決定代表我們無法運用 Fuchsia 團隊累積的專業知識,也無法重複使用現有的建構規則。不過,目前的 gn SDK 不含任何建構或測試 Flutter 應用程式的邏輯,而這類應用程式占 Workstation 產品的大宗。無論選擇哪種建構系統,團隊都必須編寫這些規則。樹狀結構內現有的 Bazel SDK 範例確實有一些基本邏輯,可用於建構 Dart 和 Flutter 應用程式。
工作站團隊選擇使用 Bazel 而非 gn/ninja,主要有幾個原因,他們認為 Bazel 是更具吸引力的建構系統。
採用開放原始碼:Bazel 並非最熱門的建構系統,但採用率高於 gn/ninja,因此開放原始碼社群應該會比較熟悉。
規則生態系統:Bazel 擁有豐富的現有規則生態系統,有助於促進重複使用。
依附元件管理:Bazel 可以管理外部依附元件。
Fuchsia SDK Bazel SDK 產品化:使用 Bazel 開發 Workstation 產品,可讓我們將變更推送至 Fuchsia Bazel SDK,供其他專案使用。
單一建構/分析階段:開發人員轉用 Fuchsia 時,常見的抱怨是不知道為何建構作業未納入某個套件或工具。這通常是因為使用者未在 gn 參數中加入目標。Bazel 會要求使用者明確指定要建構、執行或測試的內容,藉此移除這類失敗模式。
密封建構:Bazel 預設會密封建構,但 gn 不會。
在這個階段,我們需要編寫建構規則,以針對 workstation.git 建構根目錄建構體驗存放區。我們會使用 Bazel 的 new_local_repository 功能。使用這項規則,我們就能將 Bazel 專屬的建構規則保留在 workstation.git 中,以便根據從體驗存放區對應的來源進行建構。請注意,由於 Bazel 建構規則與實際原始碼位於不同的存放區,因此這種設定容易導致建構作業中斷。這些中斷只會影響負責推出樹狀結構外組件的團隊,不會影響任何樹狀結構內開發人員。我們瞭解這項取捨,但認為中斷樹狀結構外開發人員的工作流程,比中斷樹狀結構內開發人員的工作流程更好。樹狀結構外開發人員將負責修正發生的中斷問題。
//WORKSPACE
new_local_repository(
name = "ermine",
path = "vendor/experiences/session_shells/ermine/shell/",
build_file = "src/ermine/BUILD.ermine",
)
//src/ermine/BUILD.ermine
flutter_component(name = "ermine_component", ...)
flutter_package(name = "ermine", deps = ":ermine_component")
語言支援
工作站元件目前是以 Dart 和 Rust 編寫,其中 Dart 是目前唯一支援樹狀結構外開發的語言。工作站_session 和終端機元件是以 Rust 和 Ermine 編寫,而 simple-browser 則是以 Dart 編寫。我們將先著重於建構 Dart 元件,同時繼續樹狀結構內建構 Rust 元件,並將這些元件納入平台。
目前有兩個阻礙,導致無法在樹狀結構外建構 workstation_session。首先,workstation_session 使用多個私有 API,因此即使我們有語言支援,也無法在樹狀結構外建構。第二個阻礙是缺少樹狀結構外 Rust 支援。工作站工作階段目前正在分解為較小的平台層級元件,以消除對私有介面的依附元件,並探索樹狀結構外的 Rust 支援。隨著這兩項專案的進展,我們將決定 workstation_session 的命運。如果工作站工作階段完全從私人介面移出,但 Rust 支援不會很快推出,我們會以 C++ 重寫工作階段;如果 Rust 支援在之前或不久後推出,我們會保留以 Rust 撰寫的工作階段。
消毒殺菌劑
fuchsia.git 樹狀結構支援各種清除器,可用於本機開發和基礎架構建構工具。由於我們不會將原始碼移出 fuchsia.git,直到證明建構和組裝系統可搭配對應的存放區運作,因此我們不會立即在 workstation.git 存放區中支援這些系統。不過,在我們支援清除器之前,應該要禁止將程式碼移出 fuchsia.git,因為這會導致目前設定發生回歸。
我們將先確保本機建構作業正常運作,再加入支援功能,將建構時間標記傳遞至本機,啟用各種清除工具。這樣我們就能根據已對應的來源建構,並啟用清除工具。我們開始將程式碼移出 fuchsia.git 時,會設定建構工具,以符合目前提交至 fuchsia.git 的體驗。
程式碼搜尋
目前可以在程式碼搜尋中搜尋 Fuchsia 程式碼。 工作站的 .git 存放區會以獨立專案的形式新增至這個專案,方便您在線上搜尋及查看。
程式碼涵蓋率
我們不打算在專案初期為 workstation.git 啟用程式碼涵蓋範圍,近期也沒有相關計畫。主要原因是,大多數 Workstation 程式碼都是以 Dart 編寫,但目前程式碼涵蓋範圍支援不足,因此我們無法投入足夠時間啟用這項功能。
由於目前會顯示遞增的程式碼涵蓋範圍,但要在 workstation.git 中啟用這項功能的工作範圍太大,因此我們目前無法承擔,這會導致我們失去與目前 C++ 程式碼撰寫體驗的同等地位。不過,這也是與 Fuchsia 建構團隊合作的好機會,讓樹狀結構外開發人員更容易取得這些工具。
第三方支援
在 workstation.git 中編寫的所有原始碼都必須共用相同的第三方程式庫。支援這項功能的工具已在其他大型存放區多次解決,因此我們不必從頭開始,但這確實代表我們必須完成大量工作,並支援整個專案。
授權合規性將與 Fuchsia 專案使用的授權一致。在程式碼審查程序中,頂層 OWNERS 會監控第三方存放區的法規遵循情形,並將這些依附元件納入程序。
我們目前沒有任何具體計畫,在建構和程式碼檢查期間檢查授權並產生 NOTICE 檔案。我們需要研究 fuchsia.git 存放區中完成這項作業的方式,並將該邏輯移植到這個存放區。
二進位檔大小監控
監控二進位檔大小對專案的長期健康狀態至關重要。Fuchsia 建構系統中存在工具,可監控每次提交期間產生的二進位檔大小。在專案初期,我們不會為 Workstation 產品重新建構這些系統,但最終還是需要新增。
我們需要調查這些系統與目前 fuchsia.git 建構系統的緊密程度,看看是否能直接整合這些系統,還是需要進行解耦作業。如果我們需要將工具與建構系統分離,應著重於讓這些工具可重複使用,以便日後擴展至其他產品整合人員。
效能測試
目前正在進行一項專案,要將效能監控功能新增至 Workstation 產品。這項專案已著重於僅使用公開 SDK 中提供的工具,讓樹狀結構外的使用者也能進行監控。我們計畫將這些測試移至 workstation.git 存放區,因為程式碼會移出 fuchsia.git。
擁有者
與 fuchsia.git 的貢獻者相比,工作站.git 存放區的初始貢獻者人數較少。因此,在專案的初期階段,我們不會優先強制執行 OWNERS 檔案,但我們會繼續將這些檔案新增至適當的目錄,以利溝通。我們開始將程式碼移出 fuchsia.git 時,會導入 OWNERS 檔案,並強制執行與 fuchsia.git 相同的程式碼審查規則。
工作站的 .git 存放區貢獻內容,將與 fuchsia.git 貢獻內容適用相同的政策,因為兩者會託管在同一個專案下。
錯誤追蹤
這個存放區會使用現有的 Fuchsia Issue Tracker 追蹤錯誤。使用 Fuchsia Issue Tracker 的原因在於,該工具已設定為追蹤 Fuchsia 錯誤,且 Workstation 產品的板級支援仍會保留在 fuchsia.git 中。頂層工作站元件可用於一般分類,現有幾個元件則可用於追蹤工作站產品的各種功能。
構件流程
如要在 fuchsia.git 以外組裝 Workstation 產品,我們需要提供 Fuchsia 平台預先建構的項目,供 Workstation 產品使用。這表示我們會有兩類構件:構成平台的構件,以及疊加在頂端以組裝最終工作站產品映像檔的構件。平台映像檔會預先建構,供工作站的 git 存放區使用,而工作站元件則會在組裝最終產品映像檔時建構。由於平台不斷演進,目前尚未明確定義組成平台的構件集,但工作站元件會包含 workstation_session、Ermine 和 simple-browser。請注意,即使是僅支援 Workstation 產品的驅動程式庫,我們也不會建議將任何驅動程式庫開發作業樹狀結構外,因為這是提案的一部分。
如要允許 workstation.git 使用預先建構的構件,我們需要設定 fuchsia.git 的建構工具來建立預先建構的構件,並設定自動捲動器,將構件拉入 workstation.git。我們或許可以延長今天執行的其中一個建構工具,但尚未完全調查是否可行。
fuchsia.git 建構工具每天會執行一次,並建構 Fuchsia 平台。 我們需要瞭解確切的建構內容,因此尚未決定如何設定這個建構工具。建構工具會將所有適當的構件上傳至自動捲動器可使用的位置。上傳這些構件的確切位置和機制尚未確定。構件會隨附資訊清單檔案,其中包含用於建立平台的所有依附元件版本。包括但不限於 SDK 版本、experiences.git 版本、Flutter 和 Dart 版本、Fuchsia 工具鍊版本等。
自動捲動器每天會執行多次,檢查平台是否有新版本。多次執行可確保我們擷取最新版本,無論不穩定的推出或建構作業在一天中不同時間發生,都能順利完成。自動捲動器會輪詢平台的最新版本,並提取這些構件。滾動器也會讀取資訊清單檔案,其中包含所有相依版本,並更新這些版本。這樣可確保平台和各種依附元件之間不會有版本差異。
所需資料大多是包含檔案系統分區的檔案,例如 fuchsia.zbi 和 fvm.sparse.blk。這些檔案包含啟動所需的所有資料,以及「base」和「cache」清單中的所有套件。這些檔案會收集到 .far「產品套件」中,而這個套件網址中的中繼資料,會包含所有必要中繼資料,以便使用相符的 SDK 建構元件套件。針對這項中繼資料建構的套件可附加至基礎和快取,方法是修改「產品套件」中包含的系統分割區。建立獨立的樹狀結構外映像檔組裝工具是平行作業,因此「產品套件」中綁定的特定構件清單可能會變更,具體視新工具的 API 而定。
每日建構工具會上傳構件,讓我們能透過特定版本存取「產品套件」。固定存放區會包含平台所有版本的參照,讓 Roller 識別最新或適合 ABI 相容性的特定建構版本。我們目前正在這個提案以外的地方,研究如何啟用這項功能。
組裝最終產品時,建構系統應先下載「產品套件」,該套件由網址識別。系統隨即會下載相符的 SDK。(SDK 也可與「產品套件」一併封裝)。SDK 應根據該 SDK 建構套件,為每個套件建立 meta.far 檔案,並將所有必要 Blob 收集到單一位置。組裝工具隨後會將這些 Blob 和套件附加至「產品套件」,產生完整的產品建構版本。產生的構件也應包含生成 OTA 套件的所有必要資訊。
ABI 注意事項
如果將 Workstation 產品與平台分開編譯,可能會導致 ABI 不相容的問題。我們必須確保一律使用 SDK 發布版本編譯工作站元件,該版本必須等於或舊於,但符合 RFC-0002 的相容性範圍,且是工作站產品組裝時所用的平台發布版本。為確保我們維持這項不變量,我們會將 SDK 版本納入與平台一起推出的中繼資料,並更新 workstation.git 存放區,以使用這個版本的 SDK。
請注意,這項 ABI 考量因素必須擴及其他為 Workstation 產品提供程式碼的「花瓣」,例如 Flutter 和 Dart 執行器。為盡量降低這些花瓣造成的 ABI 中斷風險,我們一開始會將這些花瓣做為平台的一部分推出,這表示這些花瓣已在 Fuchsia 的全域整合中經過驗證。
我們開始將花瓣移出平台介面時,需要確保花瓣與產品相容。對於返回 Fuchsia 全球整合的 Petal,我們可以在建構平台本身時,傳播有關版本的相關中繼資料。不過,我們有些依附元件日後可能不會納入 Fuchsia 全球整合,這表示平台推出時不會包含版本資訊。我們需要使用平台版本管理功能,確保納入正確版本,並找出處理過時版本的方法。
實作
從 fuchsia.git 建構及組裝 Workstation 產品的過程會分為幾個階段,每個階段都以先前的階段為基礎。由於支援樹狀結構外開發的系統元件目前仍在開發中,因此必須採取分階段做法。
階段 1
如要讓工作站建構樹狀結構外的項目,首先要設定開發環境。我們將建立 workstation.git 存放區來託管程式碼。 這個存放區會包含啟動程序指令碼,可供使用者啟動及執行。存放區會使用 Bazel 工作區和 Git 子模組,管理 third_party 程式碼、預先建構的項目,以及 vendored in experiences 存放區。
階段 2
第二階段的重點是設定建構系統,以建構 Flutter 元件。我們會以 fuchsia.git 中的現有 Bazel 規則為基礎,編寫建構規則。最終狀態是成功建構 Flutter 元件,並在已執行的裝置上啟動。
在設定建構 Flutter 元件的規則時,我們將探索如何使用產品組裝工具,在樹狀結構外進行組裝。這個程序會手動完成,只要將 fuchsia.git 中建構的所有構件複製到 workstation.git 存放區的輸出目錄,然後嘗試建立可開機的映像檔即可。最終狀態是我們可以使用在樹狀結構外組裝,但在樹狀結構內建構的映像檔,佈建裝置。
第 3 階段
第三階段的目標是整合所有這些部分,組裝成完整的產品。包括設定建構平台構件所需的所有基礎架構,並定期將構件上傳至 TUF 存放區。這個建構工具會在 Fuchsia 基礎架構中執行。工作站的 .git 存放區會透過自動捲動器推出新版本。自動捲動器會更新 workstation.git 存放區中的資訊清單檔案、執行整合測試,並提交這項變更。這與 fuchsia.git 不同,後者會將版本更新提交至整合存放區,以協調版本變更。
建構和組裝的工作流程如下:
- 更新資訊清單項目,識別平台版本和所有相依版本,即可推出新版平台。您需要設計版本讀取和識別方式。
- 使用 Bazel 和 git 下載建構樹狀結構內元件所需的適當預先建構項目和第三方存放區。
- 使用平台下載工具,從 TUF 存放區下載所有平台構件。
- 建構樹狀結構內元件。
- 將建構的元件和預先建構的元件組合成最終映像檔。
效能
這項專案只負責建構和組裝,因此不會對 Workstation 產品的效能造成任何影響。不過,由於工作站開發人員不需要建構平台,因此建構時間應該會大幅縮短。
安全性考量
我們沿用 fuchsia.git 使用的許多基礎架構,但需要確保 Workstation 的建構和發布方式安全無虞。我們會與安全和基礎架構團隊合作,建立安全的發布程序和建構管道。
Workstation 產品僅做為參考產品,但我們仍須確保遵循適當的安全防護通訊協定。一旦我們接近發布任何類型的版本,就需要與安全團隊合作,確保我們以符合安全規定的方式建構版本。
隱私權注意事項
目前無需考慮隱私權影響。我們將使用不會收集使用者資料的開放工具。
測試
Workstation 產品有一套測試,會在每次提交時執行。這些測試包括單元測試、整合測試、端對端測試和效能測試。這些測試的程式碼會匯入 workstation.git 存放區,而 Workstation 元件的程式碼則會匯入 worksation.git。
這些測試的邏輯位於 experiences.git 中,因此我們將這個存放區對應至 workstation.git 後,就能執行這些測試,直到實際移動程式碼為止。所有這些測試都使用公開 SDK 中提供的程式碼和工具,因此我們可以在樹狀結構外執行測試,但需要更新建構系統,確保測試可以在 fuchsia.git 以外建構及執行。
系統會在每次提交至 workstation.git 存放區時執行測試,以防發生回歸。這需要與基礎架構團隊合作,找出在 CQ 中建構及執行這些測試的方法。目前的基礎架構假設存在 fuchsia.git,因此我們需要開發與建構系統和存放區版面配置無關的方法。
說明文件
我們只需要在 workstation.git 中新增說明文件,說明如何設定存放區以進行開發。工作站開發作業仍會保留樹狀結構內,因此我們應繼續將文件指向該工作流程。
缺點、替代方案和未知事項
另一種做法是只在 Fuchsia 樹狀結構中完成所有這些工作,但使用完全位於 SDK 中的工具。我們已捨棄這種做法,因為這樣太容易隱藏私有介面的使用情形。將組件完全樹狀結構外,會迫使我們只依賴 SDK。
我們仍不清楚需要上傳至 TUF 存放區的內容、上傳的形狀,以及與構件一起上傳的中繼資料格式。我們認為這些細節會在開始處理程序時確認,並視需要修訂本 RFC。