| RFC-0115:建構類型 | |
|---|---|
| 狀態 | 已接受 |
| 區域 |
|
| 說明 | 產品建構類型的標準定義。 |
| Gerrit 變更 | |
| 作者 | |
| 審查人員 | |
| 提交日期 (年-月-日) | 2021-07-06 |
| 審查日期 (年-月-日) | 2021-07-21 |
摘要
本文說明 Fuchsia 的不同產品建構類型:eng、userdebug 和 user。
Fuchsia 中的建構類型是指產品設定的建構時間和執行階段設定:
建構時間設定包括套件、工具、簽署設定,以及定義系統行為的標記。
執行階段設定包括傳遞至執行中核心的標記,或根據建構類型調變執行階段行為的軟體。
本文旨在正式核准已為 Fuchsia 產品做出的設計決策,這些產品已使用這些建構類型。同時也是 Fuchsia 平台中不同建構類型的正式定義。
提振精神
Fuchsia 定義了多種建構類型,供開發人員、測試人員和一般使用者等不同類型的使用者使用。這些使用者群組對執行中的 Fuchsia 系統行為都有一定的期望。
特定建構類型會針對不同用途 (例如開發或運送給使用者的產品),編碼並保證特定 Fuchsia 系統行為。
此外,您還可以根據產品建構類型,做出建構時間決策,例如是否要納入特定套件風味。詳情和範例請參閱「套件變種版本」一節。
因此,不同的建構類型為 Fuchsia 平台及其使用者提供必要的彈性,可支援 Fuchsia 產品的完整生命週期。
設計
本節將說明 Fuchsia 目前常見的建構類型慣例。並詳細說明每種型別的不同屬性,以及適用的執行階段限制。
此外,由於複雜度和實作成本,定義的建構類型數量也有限制。詳情請參閱「缺點」一節。
就 Fuchsia 目前的要求而言,有三種建構類型:
useruserdebugeng
如要新增其他建構類型,必須先提出提案,並通過 RFC 程序,且獲得 Fuchsia 工程委員會 (FEC) 核准。
目標
設計的主要目標如下:
- 為建構類型制定通用慣例,以支援開發人員需求和最終產品出貨規定。
- 建構類型會盡可能以類似的方式實作,避免產品行為出現額外差異。
- 建構類型的發布和資格條件相同,且頻率一致。
定義
user
user 建構類型用於出貨給使用者的正式版裝置。
對於 user 建構作業,平台會在執行階段強制執行最高安全保障,並在建構期間僅納入產品的必要元件。
userdebug
根據預設,userdebug 建構類型與 user 的行為相同,但允許額外的偵錯和檢測行為。
userdebug 版本主要用於開發裝置,供使用者測試及驗證產品。
eng
eng 建構類型主要適用於開發人員和測試人員,並會啟動產品工作階段定義的完整產品體驗。
各種產品設定的 eng 建構版本都可樹狀結構內取得,並與 Fuchsia SDK 一併做為預建系統映像檔。
產品設定
建構類型定義為產品專屬設定。為確保建構類型之間的相似性,設定會從 Fuchsia 的核心產品繼承並納入,並選擇性地新增或移除套件和設定。
建構類型關係可歸納如下:

圖 1:建構類型做為產品設定。
注意:
eng 建構類型會繼承 core,並可納入產品專用的其他套件。
使用者建構類型會直接繼承 核心,但會移除所有額外套件、偵錯功能和其他檢測屬性。
userdebug 接著會繼承 user,兩者只有些微差異,可啟用偵錯和檢測所需的額外功能。
userdebug 和 user 之間的逆向繼承可確保使用者產品所需的 user 變更,會自動反映在 userdebug 建構版本中。
設計大致反映了產品週期,其中
eng是第一個定義的產品設定,以coreFuchsia 產品為基礎。然後,當產品進入生命週期的下一個階段時,系統會定義userdebug和user,以反映這些用途和需求。
實作
下節將記錄各建構類型的實作詳細資料,並依平台主要領域分類。
斷言
Zircon 是 Fuchsia 的核心平台,由核心和一小組使用者空間服務、驅動程式和程式庫組成。
程式碼庫中使用了幾種不同的類似斷言機制。核心和使用者模式斷言會根據建構類型啟用或停用。舉例來說,ZX_ASSERT 一律適用於所有建構類型,且必須較便宜,以免影響效能。
在另一個範例中,assert_level 是 eng 建構中的 2,並啟用所有斷言,而這是 userdebug 和 user 建構中的 0,會停用標準 C assert() 和 ZX_DEBUG_ASSERT。
下表列出核心中的斷言:
| 屬性 | eng | userdebug、user |
|---|---|---|
| ASSERT | 開啟 | 開啟 |
| DEBUG_ASSERT | 開啟 | 關閉 |
| assert() | 開啟 | 關閉 |
復原分割區
Fuchsia 終端使用者產品採用 A/B/R 更新和復原機制。
總而言之,系統會透過無線 (OTA) 機制更新,並採用 A/B 更新方案,其中包含兩個系統副本(一個為啟用狀態,另一個為停用狀態)。這樣可確保系統在更新失敗時有備援機制。但如果無法啟動備用系統,系統會使用儲存在復原磁碟分割區的復原映像檔,嘗試復原系統。
每項產品都可以定義自己的復原映像檔。根據預設,在 eng 建構作業中,系統會使用 zedboot。由於 zedboot 用於鋪設 Fuchsia 系統,因此提供偵錯埠和其他設施來復原系統。
在 userdebug 和 user 中,使用的復原映像檔不同,但都符合終端使用者產品的安全規定。
| 屬性 | eng | userdebug、user |
|---|---|---|
| 復原 (R) | zedboot | 最精簡的復原映像檔 |
套件和更新
自動更新套件
在 eng 建構類型中,auto_update_packages 預設為啟用。因此,在解析元件時 (即透過執行元件),系統會先嘗試透過 fuchsia.pkg.PackageResolver 更新元件的套件。
在日常開發作業中,這項功能有助於確保系統一律執行開發人員環境中的最新元件。
這項功能不適用於 userdebug 和 user 版本。如要變更元件和套件,必須透過系統更新,這會變更 base 系統中的套件,並觸發重新啟動。
| 屬性 | eng | userdebug、user |
|---|---|---|
| auto_update_packages | true | 否 |
套件風味
套件風味用於指定套件的 eng 風味,然後包含元件的 eng 風味。然後,套件會納入產品設定,定義 eng 建構類型。
例如:
package_flavor_selections += [
{
name = "my_component_pkg"
flavor = "eng"
},
]
同樣地,套件的 user 變種版本會納入產品的 user 建構作業。
系統更新
Fuchsia 採用無線 (OTA) 更新機制進行作業系統更新。有兩個進入點,分別是 omaha-client 或 system-update-checker 元件:
| 屬性 | eng | userdebug、user |
|---|---|---|
| 自動系統 OTA | 否 | true |
| 更新檢查工具 | system-update-checker |
omaha-client |
| Omaha 設定 | 不適用 | 已定義 |
Omaha 設定定義了執行系統更新的伺服器端設定,適用於 userdebug 和 user 等使用者版本。
Omaha 設定包含儲存在 VBMeta 的資訊,可確保軟體執行前會先驗證完整的信任根。
套件組合、可執行的元件和允許清單
Fuchsia 開發板和產品定義會擴充三份依附元件清單:Base、Cache 和 Universe。因此,這些集合中定義的套件會決定在 Fuchsia 中如何管理。
舉例來說,base 集中的套件只能透過系統 OTA 更新變更。因此需要重新啟動系統。
由於 universe 集可存取整個 Fuchsia 軟體集,因此 user 建構作業不允許使用。
| 屬性 | eng | userdebug | 使用者 |
|---|---|---|---|
| 可用的集合 | base、cache、universe | base、cache、universe | base |
| 許可清單 | 允許所有套件 | 基本費率 + 許可清單 | 僅限底座 |
許可清單是一項政策,可根據元件網址判斷要執行哪些元件,或在執行階段判斷哪些元件可以存取特定服務。這項功能有助於確保 user 建構作業不會執行專為 eng 建構作業設計的開發元件或服務。
在另一個範例中,userdebug 建構版本允許執行一組有限的工具來檢查系統,例如 iquery,可檢查執行中元件的屬性。
在 user 中,只允許產品執行所需的軟體。在目前的設計中,這項軟體僅限於 base 集內含的內容。
軟體來源
Fuchsia 軟體是透過軟體存放區代管的套件提供。Fuchsia 必須知道這些軟體來源,並透過信任鏈以密碼編譯方式驗證。
對於 eng 版本,可新增至系統的軟體來源沒有任何限制。
如果是 userdebug 建構作業,只有在目標系統透過直接介面連線至開發人員的主機工作站時,才能新增軟體來源。
user 建構版本中的軟體來源是固定的,無法修改。
偵錯、記錄和 Shell
eng 建構版本可完整存取 Fuchsia 系統,並提供所有偵錯埠和記錄。user 版本會限制所有存取權和記錄,而 userdebug 版本則只會啟用有限的存取權,以利進行偵錯。
| 屬性 | eng | userdebug | 使用者 |
|---|---|---|---|
| ssh | 已啟用 | 已啟用 | 已停用 |
| serial | 已啟用 | 唯讀系統啟動載入程式和核心 | 系統啟動載入程式中的 r/o |
| debug_agent | 已啟用 | 已停用 | 已停用 |
| k 指令 | 已啟用 | 已停用 | 已停用 |
| ffx 執行階段 | 已啟用 | 已啟用 | 已停用 |
當機回報
系統會透過 fuchsia.feedback
API 提供當機報告服務。根據預設,系統會為 eng 版本停用當機上傳功能。如果是 user 和 userdebug 版本,使用者必須明確同意,才能上傳當機報告。
根據預設,所有建構版本仍會擷取當機報告,並儲存在本機當機報告資料庫中。
| 屬性 | eng | userdebug、user |
|---|---|---|
| 當機回報 | 已啟用 | 已啟用 |
| 上傳當機記錄 | 已停用 | allowed on user consent |
上傳的當機記錄包含系統和核心記錄檔,以及元件檢查資料,有助於問題分類。這些資料檔案可能含有個人識別資訊 (PII),因此上傳前會經過清除處理。
遙測
Fuchsia 平台提供服務,可記錄、收集及分析指標。這項服務由「fuchsia.metrics」提供。
Cobalt 的兩大支柱是保護使用者隱私權,以及提供高品質的匯總指標,以滿足系統和元件軟體開發人員的需求。
| 屬性 | eng | userdebug、user |
|---|---|---|
| 指標收集 | 已啟用 | 已啟用 |
| 上傳指標 | 已啟用 | allowed on user consent |
已驗證的執行作業
經過驗證的執行作業是 Fuchsia 安全性的核心設計,可確保所有執行的程式碼都值得信賴。可信度是透過驗證雜湊和可信實體的數位簽章,從不可變更的信任錨點開始,以遞迴方式斷言。
驗證開機程序
驗證開機程序是驗證執行階段,啟動載入程式會驗證 Fuchsia zbi 是否受啟動載入程式信任,可供執行。
本機建構作業 (無論是 eng、userdebug 或 user) 都會使用樹狀結構內開發金鑰,而為發布作業產生的建構作業則會使用從安全金鑰管理服務取得的更安全金鑰簽署。
預先建構的系統映像檔
預先建構的 eng 映像檔可在 Fuchsia SDK 中取得,而 userdebug 和 user 建構版本則可直接從 Fuchsia Global Integration 建構工具下載。
建構時間最佳化
Fuchsia 平台的一般建構最佳化標記在所有建構類型中都相同,可確保建構作業一致。
在 eng 建構作業中,is_debug 會設為 true,這會將預設旗標設為 debug,而不是 user 和 userdebug 建構作業中設定的 speed。這些旗標會用於全域 BUILD.gn 檔案中的各種設定。
如果是元件,eng 套件風味可以包含使用特殊標記編譯的元件。舉例來說,開發人員通常會在建構版本和機器人設定中啟用DCHECK斷言,以利偵測 C++ 元件中發生的非預期問題。
效能
據瞭解,與 userdebug 建構版本相比,eng 建構版本可能會導致效能降低,但實際降低程度會因產品和主機板類型而異。主要影響來自於在平台中啟用額外的斷言。這項測試是使用 /zircon/system/ulib/perftest 進行。
在元件中,啟用 DCHECK 的 eng 變體也會在基準測試和測試期間大量使用這些元件時,對效能造成顯著影響。
userdebug 和 user 建構作業的效能差異極小。評估效能時,請優先使用 userdebug 建構版本,而非 eng 建構版本。這種做法有缺點,詳情請見下方的「缺點」一節。
安全性考量
在設計 Fuchsia 建構類型時,我們已充分考量安全性影響。我們在整個過程中採用下列方法,確保所有使用者都能享有最高等級的安全保障:
利用經過驗證的執行程序,從啟動程序開始建立完整的驗證信任鏈結,並使用獨立的簽署金鑰進行加密簽章。
在元件架構中運用允許清單安全政策,確保只有允許的元件會解析及執行。
只包含適用於終端使用者建構作業的必要套件和元件。
在使用者建構版本中停用所有存取埠和設施。
隱私權注意事項
在設計 Fuchsia 建構類型時,我們也將隱私權考量納入考量。系統會清除使用者建構版本中的所有記錄,確保不含 PII,且必須取得使用者同意聲明,才能上傳當機記錄、記錄和指標。
說明文件
建構類型將在 Fuchsia > Concepts > Build System 中進一步說明,因此不同屬性和行為適用於 Fuchsia 產品時,會有標準參考資料。
測試
模擬器
如要測試不同建構類型的行為,最簡單直接的方法就是使用 Fuchsia 模擬器。
開發人員可使用模擬器模擬建構類型,比較及測試平台和應用程式的不同行為。缺點是目前無法在模擬器環境中測試系統的特定區域,例如系統更新或驗證開機屬性。
發布程序
Fuchsia 採用 CI (持續整合) 和 CQ (提交佇列) 管道,確保程式碼變更在 CL (變更清單) 登陸前建構及測試,並在 CL 合併時進行最終整合。
CQ 管道會在 CL 登陸前,針對不同產品設定和環境建構及測試 CL。
CI 管道會針對在同一次整合提交中簽入的程式碼,在不同產品設定中建構及測試程式碼。
由於建構類型也是以產品設定的形式實作,因此所有建構類型設定都會透過相同的 CI/CQ 管道,同時建構、測試及發布。
請注意,系統只會測試 eng 建構類型產品設定,做為 CI/CQ 的一部分。不過,user 和 userdebug 仍是持續建構程序的一部分。
設施
測試架構和設施位於 eng 和 userdebug 建構作業中設定的環境。這些服務預設不會啟用,但會加入允許清單,以便在執行階段解析及執行。
對於 user 建構版本,安全政策不會啟用或允許測試設施。
舉例來說,Fuchsia 有適用於端對端測試的 SL4F 架構,以及適用於元件架構測試的 test_runner。
如要進行自動化測試,可以使用上述架構。但如果需要其他套件或其他工具,建議使用 eng 建構版本。
缺點、替代方案和未知事項
這份 RFC 中記錄的設計已實作完成,並反映 Fuchsia 產品建構類型的現況。
透過產品設定實作建構類型,即可運用並重複使用現有實作項目。主要缺點是這種做法缺乏擴充性和彈性。舉例來說,每個新產品至少需要三種產品設定,分別對應三種建構類型。這種做法會產生相關費用,因為實作作業會出現多餘情況,且 Fuchsia 基礎架構需要額外資源,才能為這些新設定啟動建構工具。
另一個缺點是需要測試 userdebug 建構版本。由於「userdebug」版本包含特定類型的套件、不同的系統更新設定,且不會啟用偵錯標記,因此適合執行端對端測試。但由於安全限制,無法在正式 userdebug 版本中執行 SL4F。
或者,您也可以使用獨立系統組裝修改組裝的映像檔,並組裝本機 userdebug 版本,以便存取測試架構,且限制較少。
日後,我們應採用更具擴充性的方法,以便在不同產品設定中套用 eng、userdebug 和 user 建構類型設定檔。這樣可避免線性擴充問題,也就是新產品需要多個產品設定才能容納建構類型。
此外,目前實作方式混合了產品和平台,這並非 Fuchsia 平台的長期目標。如前所述,建議您日後考慮採用更彈性的設計。
既有技術和參考資料
Android 作業系統:
- 定義
eng、userdebug和user建構作業。 - 發布指南,說明修改
userdebug建構作業的最佳做法。