RFC-0093 - 元件資訊清單的設計原則

RFC-0093:元件資訊清單的設計原則
狀態已接受
區域
  • 元件架構
說明

設計元件資訊清單所用「.cml」和「.cm」格式的注意事項。

問題
變更
作者
審查人員
提交日期 (年/月)2021-04-26
審查日期 (年/月)2021-05-05

摘要

本文件擷取了針對元件資訊清單使用的 .cml.cm 格式所做的設計解譯、原則和決策。

下列大多數決策是在 2018 至 2019 年間做出的。

  1. 元件資訊清單具有前端和後端
  2. 由資訊清單定義元件
  3. 元件資訊清單是以宣告式
  4. 元件資訊清單可能來自各種來源

詞彙解釋

  • .cml元件資訊清單來源檔案的常用副檔名。CML 檔案是 JSON5 DSL,用於宣告元件。
  • ComponentDecl 是 FIDL 資料表,也是元件資訊清單的標準線路和儲存格式。
  • .cm 是常見的副檔名檔案,檔案中包含 FIDL 信封型二進位檔格式的 ComponentDecl
  • cmc 是指令列工具,可從 .cml 檔案產生 .cm 檔案。此工具建構於 Fuchsia 原始碼樹狀結構,並透過 Fuchsia SDK 發布為預建的執行檔。

#1:元件資訊清單具有前端和後端

人類和機器有不同的需求和偏好,設計元件資訊清單語法和格式時,關鍵設計原則是為元件架構建立單一後端格式以供讀取,以及為開發人員編寫的獨立前端 (第一個類型)。這項設計決策具有以下優點:

  1. 您可以根據不同的設計目標分別對後端和前端進行最佳化調整。
  2. 即使不修改後端,也可以改進前端,反之亦然。
  3. 雖然目前只有一個前端,但也可能推出其他前端,例如為不同的目標對象滿足不同的設計目標,或是配合便利性、熟悉度或風格的需求。

為支援這些目標,SDK 提供 [cmc] (「元件資訊清單編譯器」),這是將元件資訊清單來源檔案 (.cml) 轉換為資訊清單二進位檔案 (.cm) 的標準工具。cmc 通常會與建構系統以公開透明的方式整合,也就是說,除非開發人員在資訊清單上進行偵錯或執行分析,否則通常會與來源檔案互動。

ComponentDecl:元件資訊清單後端

ComponentDecl 是元件資訊清單的標準儲存空間和傳輸格式。其設計應由元件管理員、元件解析器和資訊清單分析工具 (例如 fx scrutiny) 編寫及解譯。這類格式必須符合下列目標:

  1. 必須不明確且自述。您應能夠從其內容直接衍生資訊清單的意義。
  2. 其必須能隨時間不斷演進,且能夠支援前瞻性與回溯相容性。
  3. 必須易於剖析,避免無謂的格式轉換。 否則,處理元件資訊清單 (包括元件管理員) 的程式碼會出現錯誤或攻擊的風險。
  4. 必須能夠輕鬆與與元件資訊清單互動的執行階段、元件和工具整合。

這些設計目標促成了系統自然選擇的格式:FIDL。FIDL 是 Fuchsia 中 IPC 的標準線路格式。FIDL 值類型 (即沒有帳號代碼) 可保存,並做為儲存格式使用。具體來說,使用 FIDL 信封會略過不明欄位的附加優點,這對回溯和前瞻相容性來說很實用。由於在 Fuchsia 上執行的任何執行階段都含有 FIDL 繫結,因此您可以輕鬆與程式碼整合,且不需要額外支援剖析或轉換。

ComponentDecl 的結構如下:沒有預設值,只有在不適用的欄位,或欄位來自沒有該欄位的資訊清單版本時,系統才會未填入欄位。此外,為了支援正向及回溯相容性,ComponentDecl 以及其巢狀結構為 FIDL 資料表FIDL 彈性聯集

CML:元件資訊清單前端

CML (「元件資訊清單語言」) 是元件資訊清單的來源格式。它可讓使用者讀取及寫入,但也能由格式設定工具和語言伺服器等開發工具讀取及寫入。

  1. 也應方便瞭解基本元件架構概念的新手閱讀。
  2. 因此應易於呈現常見模式,且無須過多樣板。
  3. 我們建議不需要變更資訊清單的二進位檔表示法,而變更會影響語法但不影響資訊清單語意含義的變更。舉例來說,若從單例模式陣列變更為單一值,就不會影響輸出內容。
  4. 促進可維護性。尤其是允許註解。
  5. 它應該足以支援自動化轉換作業,例如支援大規模重構。

CML 的發明是為了達成這些目標。CML 是一種以 JSON5 為基礎的設定語言,可做為簡單的 DSL 產生,並可產生 ComponentDecl。透過使用 JSON5,CML 利用許多開發人員熟悉的語言,且在福奇尼亞其他地方廣泛使用。與 ComponentDecl 不同的是,CML 提供一些預設用途,可讓您更簡潔地編寫資訊清單:

  • 這可讓部分欄位預設為略過。
  • 可將多項功能組成單一宣告,前提是這些功能具有相同的選項。
  • 這可讓資訊清單包含資訊清單資料分割,為資訊清單提供內容。例如,您可以依附程式庫並納入該程式庫的資料分割,以取得該程式庫所需的所有功能。

最後,從 CML 到 ComponentDecl 的翻譯,但不是一對一的翻譯,使用者應直接瞭解,而無須學習規則。

#2:元件由資訊清單定義

由資訊清單描述元件。資訊清單會在啟動時透過元件的網址解析。舉例來說,透過 fuchsia-pkg:// 網址啟動的元件,將擁有含 .cm 擴充功能的資訊清單,其中包含序列化的 ComponentDecl,而且該資訊清單是從套件「解析」。除了資訊清單之外,元件也可以納入來自相同套件的資源。舉例來說,使用 ELF 執行器的元件會指定該套件中 ELF 二進位檔的位置。另一方面,使用 https:// 網址的元件可能會有由 https 解析器產生,但並非由可透過網址取得的資源支援的 ComponentDecl

元件的資訊清單會完整說明其輸入、輸出內容和內部組合。目前,元件資訊清單不得包含在執行階段填入的任何參數或「懸疑」值1

這並不代表元件的行為完全由資訊清單說明。第一,提供給元件的功能是由父項決定;元件無法控管提供這些功能的人員。此外,每個元件都是環境的一部分,可為元件提供特定類型的設定,例如使用哪些解析器解析元件網址。

只要遵循資訊清單之間的網址,就會產生元件執行個體樹狀結構。元件執行個體樹狀結構是構成 Fuchsia 映像檔軟體的完整說明。如此一來,您就能對特定系統映像檔 (例如 [fx scrutiny](https://fuchsia.dev/reference/tools/fx/cmd/scrutiny)) 充滿信心執行安全性稽核。

#3:元件資訊清單為宣告式

雖然具有命令式功能的設定語言非常強大,但還是會導致可讀性、可預測性和可稽核性下降。前例顯示,使用過多命令式設定語言較容易使用且容易使用2。在元件架構中,元件定義必須可供稽核且易於理解,因此會導致命令式樣式設定語言成為非選項。

因此 CML 是一種「宣告式」語言。如果 CML 支援產生資訊清單的部分產生,這項功能僅適用於結果非常可預測的情況。舉例來說,資訊清單支援預設值和納入項目,但不提供範本化或參數化功能。

CML 是一種以人類為閱讀及編寫的語言。除了開發人員工具整合 (例如格式設定工具或 IDE 範本) 之外,CML 並非透過工具產生。產生 CML 檔案可能會導致資訊清單的基礎內容遭到遮蓋,因為目前牽涉到三個層:CM、CML 和工具。如果基於某些原因必須產生資訊清單,您應另外編寫前端以產生 CM。

#4:元件資訊清單可來自各種來源

一般來說,元件資訊清單不會繫結至任何單一發布機制。最終,元件解析器必須負責擷取網址的元件資訊清單。解析器如何針對特定網址配置完成這項作業。舉例來說,fuchsia-pkg:// 解析器會擷取套件,並從網址片段 ID 部分指定的容器中讀取資訊清單。網路解析器可能會產生資訊清單,其內容可能會因網域、安全性政策和使用者偏好設定而異。

目前發布元件最常見的方法是使用 Fuchsia 套件。這類元件會以 fuchsia-pkg:// 網址識別。元件的資訊清單會以 blob 的形式在這個套件中傳送,通常位於 meta/

激發靈感

  • Kubernetes 中的宣告式應用程式管理:用於設計 Kubernetes 設定語言的原則,以及替代方案研究。
  • 命令式與宣告式:延伸至重點主題。
  • Starlark:以 Python 為基礎的 DSL 與命令式設定語言。
  • Jsonnet:JSON 的擴充功能,為資料範本語言的擴充功能,任何程式都會產生 JSON 文件。
  • borgcfgGCLborgmon:Google 使用的功能設定語言大致與 Kubernetes 相似,而其記錄有助於我們判斷命令式語法和宣告語法之間的優缺點。

附註


  1. 未來,資訊清單必須支援某種參數化功能,才能支援變化版本和產品設定。採取這個做法時,我們應採用這個做法,避免發生與可參數化設定相關的常見問題。 

  2. 如要進一步瞭解這個時間點,Kubernetes 提供詳盡的說明文件,解釋非宣告式設定的各個缺點。