RFC-0095 - 從樹狀結構外建構及組合工作站

RFC-0095:建構及組合工作站樹狀結構外工作站
狀態已接受
區域
  • 一般
說明

建立工作流程,讓使用者能夠在 fuchsia.git 外建立及組合 Workstations 產品。

變更
作者
審查人員
提交日期 (年/月)2021-03-24
審查日期 (年/月)2021-05-19

摘要

注意:這項 RFC 已由 RFC-0220 取代,原因是已淘汰工作站產品。此 RFC 將保留以後再備,但我們將不再採取實作程序。

目前在 Fuchsia 來源樹狀結構中建構及組合工作站產品 (定義為 worker_session、ermine、終端機和簡易瀏覽器)。Fuchsia 做為平台和工作站產品沒有明顯的不同之處。這會要求平台和產品必須同時建構,才能組合最終產品。我們建議這個耦合程序中斷,讓工作站元件從平台中分開建構,並且最終產品會在 Fuchsia 來源樹狀結構外組合。本提案並未解決從 Fuchsia 來源樹狀結構移除工作站產品的實作問題,而只會著重於樹狀結構外產品設定和組件的相依問題。此工作可為最終將工作站產品完全移出樹狀結構,但超出本文件的範圍。

請特別注意,系統會將終端機視為 Workstations 產品的基本元件,但 Workstations 產品外的其他產品也會用到終端機。因此,終端機元件的開發作業將保留在 fuchsia.git,而且工作站會做為平台的一部分使用,直到對這個元件的未來做出進一步決定。

提振精神

目前無法在 Fuchsia 上建構及組合產品,卻需要同時建構整個 Fuchsia 平台。我們可以使用 SDK 在 fuchsia.git 外建構個別元件,但這些構件需要傳回 Fuchsia Global 整合,才能組合成最終產品。我們希望能針對用於建構的產品提供穩定版,而無需存取 Fuchsia Global 整合。

目前在建構樹狀結構外產品時仍有許多未知數,因此我們要開始使用 Workstations 產品。工作站產品並非正式環境,且受支援的使用者端產品,是開發人員和環境的參考資料,用於早期採用平台功能及測試,因此在這個階段的執行速度較慢,提供更多容忍度。Workstations 產品的用途是讓愛好者能探索 Fuchsia 的環境;不再需要建構整個平台,可讓開發人員更輕鬆地使用 Fuchsia 玩遊戲。

設計

將工作站超出樹狀結構外的建構程序是以獨立映像檔組合工具 RFC-0072 為基礎,本提案會假設該工具存在。

存放區

Workstations 存放區的原始碼將託管於 git-on-borg。將程式碼託管於 git-on-borg 之後,我們就能使用現有的 Fuchsia 基礎架構與工具,專心建構及組合產品。

本文件的其餘部分將是指代管 Workstations 產品程式碼的存放區。

基礎設施

本專案的重點在於建構及組合工作站產品,且在探索方法之前,我們不會將元件的開發作業移出 fuchsia.git。由於元件開發作業將保留樹狀結構內,因此我們可以依賴現有的測試和建構基礎架構來驗證 Workstations 產品不會迴歸。系統會利用指令碼手動完成平台、SDK、 Experience.git 和其他依附元件的推出程序,讓團隊能夠專心處理目前的問題。當我們開始將元件的開發工作樹狀結構外,就需要重新審視如何進行持續整合。

平台的每日建構必須自動執行,但可以使用現有的 Fuchsia 基礎架構。您需要建立每日建構工具,建構組合 Workstations 產品所需的套件,並將這些構件上傳至某些儲存空間存放區。仍需瞭解這項工作流程的技術設計。開始之前,我們先諮詢基礎架構和安全性方面的問題。

建立 Workstations 產品 (而非核心) 時,可確保我們擁有產品組件所需的所有構件,即使目前未建構產品也沒問題。我們透過樹狀結構外建構的構件會取代透過平台擲出的構件。這樣也能讓我們使用現有的 Workstations 建構工具,以減少我們需要管理的額外基礎架構量。

依附元件管理

工作站存放區將使用 Git 子模組和 Bazel 工作區的組合來管理依附元件。Git 子模組將用於提取外部存放區,而 Bazel 將用於下載建構作業所需的預先建構元件和工具鍊。

Bazel 的工具鍊會和工作區規則搭配使用,以下載每個建構規則所需的適當預先建構項目。此時,我們有一項限制是許多預先建構項目都儲存在 CIPD 中,且需要使用加密指令列工具。初始原型需要 Cpd 工具位於開發人員路徑上的某處。我們正在積極尋找變造,認為這是長期要求。

目錄結構

Workstationsia 存放區的目錄結構與 fuchsia.git 目錄結構類似,可確保 Fuchsia 開發人員保持一致。根目錄包含專案所需的各種中繼資料檔案以及下列頂層目錄。

  • //src - 用來建構 Workstations 產品的原始碼。
  • //tools - 支援版本的指令碼和工具。
  • //src/experiences - 現有的 experiences.git 存放區。
  • //預建 - 任何必要的預建。
  • //third_party - 由 src 目錄使用的第三方程式碼。

建構系統

工作站產品將使用 Bazel 建構系統建構。決定使用 Bazel 與使用 gn/ninja 的 fuchsia.git 的決定。這項決策意味著我們無法善用 Fuchsia 團隊已經取得或重複使用現有建構規則的專業知識。不過,目前的 gn SDK 不包含任何用於建構或測試大多數工作站產品的 Flutter 應用程式的邏輯。無論他們選擇哪種建構系統,團隊都必須編寫這些規則。樹狀結構內的範例 Bazel SDK 會有一些用來建構 Dart 和 Flutter 應用程式的實際邏輯。

工作站團隊選擇在 gn/ninja 上使用 Bazel,此舉會讓這個建構系統更吸引人使用。

  • 採用開放原始碼:Bazel 不是最熱門的建構系統,但比 gn/ninja 更多,因此應該對開放原始碼社群更熟悉。

  • 規則生態系統:Bazel 擁有豐富的現有規則生態系統,有助於促進重複使用。

  • 依附元件管理:Bazel 可以管理外部依附元件。

  • Fuchsia SDK Bazel SDK 生產:使用 Bazel 處理工作站產品,讓我們有機會將變更推送到其他專案可以使用的 Fuchsia Bazel SDK。

  • 單一建構/分析階段:一般而言,開發人員要到 Fuchsia 開發時,並不瞭解版本未包含特定套件或工具的原因。這個原因通常發生在使用者並未將目標納入妊娠中。Bazel 會要求使用者明確指定想要建構、執行或測試的內容,藉此移除這個故障模式。

  • 典型的建構項目:Bazel 預設擁有密封建物,而 gn 則不需要。

在這個階段中,我們需要撰寫建構規則,才能針對 worker.git buildroot 建構體驗存放區。我們會使用 Bazel 的 new_local_repository 功能。使用這項規則可讓我們將 Bazel 專屬建構規則保留在 worker.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 是唯一支援樹狀結構外開發的語言。worker_session 和終端機元件都是以 Rust 和 Ermine 編寫,且採用簡易瀏覽器加以編寫。首先,我們會專注於建構 Dart 元件,同時繼續樹狀結構內建構 Rust 元件,並做為平台的一部分提供。

目前有兩個攔截器用於建構 worker_session-樹狀結構外。第一個是工作站_session 使用多個私人 API,這表示即使我們支援語言,也無法從樹狀結構外建構。第二項阻礙是沒有樹狀結構外的 Rust 支援。worker_session 目前正分解為較小的平台層級元件,該元件解除其私人介面和樹狀結構外 Rust 支援。我們將根據這兩個專案的進度,決定 worker_session 的命運。如果 workstation_session 已完全從私人介面移出,但 Rust 支援即將從後消失,我們會在 C++ 中重新編寫工作階段,但如果 Rust 支援會在前後抵達,我們會保留以 Rust 編寫的工作階段。

消毒液

fuchsia.git 樹狀結構支援本機開發和基礎架構建構工具的各種消毒液。對工作站.git 存放區中系統的支援並非立即的目標,因為在我們確認版本和組合系統能與存放區中對應的程式碼搭配運作之前,我們不會將原始碼移出 fuchsia.git。但是,我們應該阻止將程式碼移出 fuchsia.git,直到我們支援掃毒程式支援,因為目前的設定會產生迴歸。

當本機版本能正常運作時,我們會新增傳遞建構時間標記的支援,在本機啟用各種清理器。這樣我們就能在已啟用消毒液功能的來源中,建構對應的對應資料。開始將程式碼移出 fuchsia.git 時,我們會設定建構工具,以因應目前向 fuchsia.git 進行的承諾。

您目前可以透過程式碼搜尋搜尋 Fuchsia 代碼。系統會將 worker.git 存放區新增至這項專案,做為獨立專案,讓使用者可在線上搜尋及查看。

程式碼涵蓋率

我們不打算在專案一開始就啟用 worker.git 程式碼涵蓋率,也還沒有針對短期計畫制定任何計畫。之所以會這樣,主要原因是大部分工作站程式碼都是以 Dart 編寫而成,而 Dart 所提供的程式碼涵蓋率不足,因此不保證我們投入了進行啟用所需的時間。

由於 c++ 程式碼會顯示漸進式的程式碼涵蓋率,但目前在 workstation.git 中啟用這項功能的工作範圍過大,而無法支援目前的編寫 c++ 程式碼。然而,這確實是與 Fuchsia 建構團隊合作的絕佳機會,希望讓樹狀結構外開發人員更容易使用這些工具。

第三方支援

所有在 worker.git 中編寫的原始碼都必須共用相同的第三方程式庫。支援此功能的工具已經在其他大型存放區中數次解決,所以我們不必從頭開始,但它代表必須為整個專案執行的工作量,並提供支援。

授權法規遵循情形與 Fuchsia Project 使用的服務一致。在導入這些依附元件的程式碼審查程序中,存放區的頂層 OWNERS 會監控有關 third_party 存放區的法規遵循情況。

目前,我們無法在建構期間和程式碼檢查期間檢查授權及產生 NOTICE 檔案。我們需要研究如何在 fuchsia.git 存放區中執行這項操作,然後將該邏輯移植到這個存放區。

監控二進位檔大小

監控二進位檔的大小對於專案的長期健康狀態來說十分重要。Fuchsia 建構系統中有一項工具,可監控每個修訂版本產生的二進位檔大小。為 Workstations 產品再次建構這些系統並不在本專案的初期階段,但我們最終必須新增相關內容。

我們需要調查這些系統與現有 fuchsia.git 建構系統的緊密耦合程度,看看能否直接以目前形式整合,或者是否需要採取行動來分離這些系統。如果我們需要努力將工具與建構系統分離,我們應著重於讓這些工具可重複使用,以便日後向其他產品整合商擴充。

效能測試

目前有一個專案正在為工作站產品新增效能監控功能。這項專案已開始著重於透過僅使用公用 SDK 提供的工具,讓樹狀結構外的使用者取得監控作業。我們計劃將這些測試移至 worker.git 存放區,因為程式碼會從 fuchsia.git 移出。

擁有者

與 fuchsia.git 的貢獻者組合相比,工作站的初始貢獻者組合規模較小。因此,在這項專案初期的階段,強制執行 OWNERS 檔案並不會優先執行,但我們會持續將這些檔案加入適當的目錄,以促進通訊。開始將程式碼移出 fuchsia.git 時,我們會介紹 OWNERS 檔案,並強制執行我們在 fuchsia.git 中執行的程式碼審查規則。

對 worker.git 存放區做出貢獻將適用與 fuchsia.git 貢獻作業相同的政策,因為這些內容將託管於同一個專案。

錯誤追蹤

存放區將使用現有的 Fuchsia Issue Tracker 追蹤錯誤。使用 Fuchsia Issue Tracker 的原因,原因是它已經設定成追蹤 Fuchsia 錯誤,而且由於工作站產品的白板支援仍留在 fuchsia.git。有一個頂層 Workstations 元件可用於一般分類,接著還有數個現有元件,可用於追蹤 Workstations 產品的各種功能。

構件流程

為了在 fuchsia.git 外組合 Workstations 產品,我們需要提供 Fuchsia 平台的預先建構,以供工作站產品使用。這表示我們會有兩個構件類別:組成 Platform 的構件,以及疊加在上方的構件,以組合最終 Workstation 產品映像檔。平台映像檔會在提早建構時間提供給工作站.git 存放區使用,而系統會在組合最終產品映像檔時建構工作站元件。由於平台會持續演進,因此構成 Platform 的構件組合尚未明確定義,但工作站元件將包含 worker_session、Ermine 和簡易瀏覽器瀏覽器。請注意,我們不提議將任何驅動程式庫開發作業從樹狀結構外移出,即使該驅動程式庫僅支援工作站產品也一樣。

為了讓工作站.git 使用預先建構的構件,我們需要設定 fuchsia.git 的建構工具,來建立預先建構的版本,以及將構件提取至工作站.git。我們或許可以擴充目前執行中的其中一個建構工具,但可能還沒有全面調查。

fuchsia.git 建構工具將每天執行一次,並建構 Fuchsia 平台。我們需要瞭解確切的建構內容,因此尚未確定這個建構工具的設定方式。建構工具會將所有適當的構件上傳到自動累計工具可使用的位置。系統仍會判斷這些構件的確切上傳位置和機制。構件會隨附資訊清單檔案,其中包含用於建立平台的所有依附元件版本。這包括但不限於 SDK 版本、 Experience 版本、Flutter 和 Dart 版本、Fuchsia 工具鍊版本等。

系統會每天多次執行自動推車,以檢查平台的新版本。只要多次執行,就能確保我們能擷取最新版本,無論一天中可能出現的不穩定滾動作業或版本為何。自動推車會輪詢平台的最新版本,並提取這些構件。滾輪也會讀取資訊清單檔案,其中包含所有依附版本,並一併更新這些版本。這樣做可以確保平台和各種依附元件之間不會發生版本偏移。

必要資料主要是包含檔案系統分區的檔案,例如 fuchsia.zbi 和 fvm.sparse.blk。這些檔案含有啟動所需的所有資料,以及「基本」和「快取」清單中所有套件。這些檔案會收集到 .far「產品套件」中,而這個套件網址中找到的中繼資料會包含所有必要中繼資料,以使用相符的 SDK 建構元件套件。針對這項中繼資料建構的套件,可以修改「產品套件」中包含的系統分區,附加到基礎和快取中。由於建立獨立樹狀結構外映像檔組合器的平行處理工作,因此「產品套件」組合中的特定構件清單可能會隨新工具的 API 而變動。

每日建構工具上傳構件的方式,可讓我們透過指定版本存取「產品套件」。固定的存放區會包含所有平台版本的參照,以便讓滾輪能夠識別最新版本或適合 ABI 相容性的特定版本。處理這項作業的特定程序,目前正在這個提案外部探索。

組合最終產品時,建構系統應先下載以網址識別的「產品套件」。然後下載相符的 SDK。(您也可以在「產品套件」中隨附 SDK),然後根據該 SDK 建構套件,為每個套件建立中繼.far 檔案,並將所有必要的 blob 收集到單一位置。接著,組合工具會將這些 blob 和套件附加到「產品套件」中,進而產生完整的產品版本。產生的構件也應含有產生 OTA 套件的所有必要資訊。

ABI 考量事項

將工作站產品與平台分開編譯,會讓我們遇到 ABI 不相容的問題。我們需要確保一律使用等於或早於版本 SDK 的發布工作站元件編譯工作站元件,每個 RFC-0002 (根據工作站產品組合的平台發布版本) 內的版本。為確保保持不變,我們會在與平台一起發布的中繼資料中加入 SDK 版本,同時更新 workstation.git 存放區,使其使用這個 SDK 版本。

請注意,此 ABI 考慮事項需延伸至為工作站產品提供程式碼的其他的小件,例如 Flutter 和 Dart Runner。為了盡可能降低來自這些寵物的 ABI 故障風險,我們一開始會在平台中推出這些動物,表示這些花瓣已通過 fuchsia 的全球整合驗證。

隨著我們開始將花瓣從平台介面中移除,我們必須確保這些花瓣與我們的產品相容。對於 Fuchsia 全球整合,我們可以在建構平臺本身時傳播關於版本的中繼資料。不過,我們的部分依附元件日後不會納入 Fuchsia Global 整合,也就是說,系統不會在平台復原中加入版本資訊。我們需要使用平台版本管理功能,才能確保納入正確的版本,而且也必須設法處理過時的版本。

實作

從 fuchsia.git 建構及組合 Workstations 產品的程序將進行多個階段,每個階段各有一個建構。這種階段式做法具有必要性,因為目前支援樹狀結構外開發的系統部分仍在開發階段。

第 1 階段

如要取得工作站樹狀結構外建構,初始的階段是設定開發環境。我們會建立 worker.git 存放區來託管程式碼。這個存放區會包含 Bootstrap 指令碼,讓使用者可以快速上手。存放區將使用 Bazel 工作區和 Git 子模組來管理 third_party 程式碼、預先建構,以及在體驗存放區中廠商納入的程式碼。

第 2 階段

第二階段的重點是設定建構系統以建構 Flutter 元件。我們會使用位於 fuchsia.git 的現有 Bazel 規則做為建構規則的起點。結束狀態就是當我們成功建構可在執行中裝置上啟動的 Flutter 元件。

同時,我們也會探索設定 Flutter 元件的建構規則,並探索如何使用產品組合工具進行樹狀結構外的組合。您可以手動完成這項程序,方法是將 fuchsia.git 建構的所有構件複製到 worker.git 存放區的目錄中,然後嘗試建立可開機的映像檔。結束狀態就是我們可以使用樹狀結構外組合但以樹狀結構建構的映像檔來佈建裝置。

第 3 階段

此轉換的第三階段,我們要努力整合所有部分,以便組合整個產品。這包括設定建構平台構件所需的所有基礎架構,並依照排程將這些構件上傳至 TUF 存放區。這個建構工具會在 Fuchsia 基礎架構中執行。worker.git 存放區將會滾動新版本。Autoroller 會更新 worker.git 存放區中的資訊清單檔案、執行整合測試,並修訂這項變更。這與 fuchsia.git 不同,後者會將版本更新提交至整合存放區來協調版本變更。

建構及組裝作業的工作流程如下:

  1. 更新資訊清單項目以識別平台版本和所有相依版本,藉此滾動平台新版本。版本的讀取及識別方式必須設計。
  2. 使用 Bazel 和 Git 下載適當的預先建構工具和第三方存放區,以便建構樹狀結構內結構元件。
  3. 使用平台下載工具,從 TUF 存放區下載所有平台構件。
  4. 建構樹狀結構內結構元件。
  5. 將建構的元件和預先建構的元件組成最終映像檔。

效能

這項專案只是建構及組合作業,因此應該不會對工作站產品的效能造成任何影響。不過,由於工作站開發人員不需建構平台,因此應開始感受到工作站開發人員的建構時間大幅提升。

安全性考量

我們正在重複使用 fuchsia.git 使用的許多基礎架構,但必須確保工作站的建構與發布方式安全無虞。我們會與安全性和基礎架構團隊合作,建立安全的發布程序和建構管道。

Workstations 產品僅供參考產品使用,但我們希望確保仍遵循適當的安全性通訊協定。在即將發布任何類型的版本後,我們需要搭配安全性做法,確保以安全的方式建構版本。

隱私權注意事項

目前隱私權不會受到任何影響。我們將使用不會收集使用者資料的開放式工具。

測試

Workstations 產品提供一系列測試,對每個修訂版本執行。這些測試包含單元測試、整合測試、e2e 測試和效能測試。這些測試的程式碼會移植至 worker.git 存放區,因為 Workstations 元件的程式碼會移植到 workation.git。

這些測試的邏輯位於 Experience.git,因此由於我們將這個存放區對應至工作站.git,因此能夠執行測試,直到實際移動程式碼為止。這些測試都是使用公用 SDK 中提供的程式碼和工具,因此能夠在樹狀結構外執行這些測試,但需要更新建構系統,以確保這些測試可以在 fuchsia.git 以外的地方建構及執行。

系統會在每個工作站.git 存放區修訂版本上執行測試,以防止迴歸。這需要與基礎架構團隊合作,一起瞭解如何在 CQ 中建構及執行這些測試。目前的基礎架構假設 fuchsia.git 已存在,因此我們必須開發一種方法,確保建構系統和存放區配置完全不受影響。

說明文件

我們只需要在 worker.git 中新增說明文件,並說明如何將存放區設為進行開發。工作站開發仍樹狀結構內,因此我們應繼續將說明文件指向該工作流程。

缺點、替代方案和未知

其中一種替代方案是在 Fuchsia 樹狀結構中完成所有這項工作,但使用 SDK 完全現有的工具。我們捨棄了這個方式,因為它的隱私介面使用起來太容易隱藏。將組件完全移至樹狀結構外,迫使我們只依賴 SDK。

不過,對於需要上傳至 TUF 存放區的確切內容、上傳型態,以及用成果上傳的中繼資料格式,都還有一些不明資訊。我們認為,這些具體細節將在我們逐步完成這項程序時加以識別,並會視需要修訂這個 RFC。