RFC-0093:元件資訊清單的設計原則 | |
---|---|
狀態 | 已接受 |
區域 |
|
說明 | 設計元件資訊清單所用「.cml」和「.cm」格式的注意事項。 |
問題 | |
變更 | |
作者 | |
審查人員 | |
提交日期 (年/月) | 2021-04-26 |
審查日期 (年/月) | 2021-05-05 |
摘要
本文件擷取了針對元件資訊清單使用的 .cml
和 .cm
格式所做的設計解譯、原則和決策。
下列大多數決策是在 2018 至 2019 年間做出的。
詞彙解釋
.cml
是元件資訊清單來源檔案的常用副檔名。CML 檔案是 JSON5 DSL,用於宣告元件。- ComponentDecl 是 FIDL 資料表,也是元件資訊清單的標準線路和儲存格式。
.cm
是常見的副檔名檔案,檔案中包含 FIDL 信封型二進位檔格式的 ComponentDecl。cmc
是指令列工具,可從.cml
檔案產生.cm
檔案。此工具建構於 Fuchsia 原始碼樹狀結構,並透過 Fuchsia SDK 發布為預建的執行檔。
#1:元件資訊清單具有前端和後端
人類和機器有不同的需求和偏好,設計元件資訊清單語法和格式時,關鍵設計原則是為元件架構建立單一後端格式以供讀取,以及為開發人員編寫的獨立前端 (第一個類型)。這項設計決策具有以下優點:
- 您可以根據不同的設計目標分別對後端和前端進行最佳化調整。
- 即使不修改後端,也可以改進前端,反之亦然。
- 雖然目前只有一個前端,但也可能推出其他前端,例如為不同的目標對象滿足不同的設計目標,或是配合便利性、熟悉度或風格的需求。
為支援這些目標,SDK 提供 [cmc]
(「元件資訊清單編譯器」),這是將元件資訊清單來源檔案 (.cml
) 轉換為資訊清單二進位檔案 (.cm
) 的標準工具。cmc
通常會與建構系統以公開透明的方式整合,也就是說,除非開發人員在資訊清單上進行偵錯或執行分析,否則通常會與來源檔案互動。
ComponentDecl:元件資訊清單後端
ComponentDecl 是元件資訊清單的標準儲存空間和傳輸格式。其設計應由元件管理員、元件解析器和資訊清單分析工具 (例如 fx scrutiny
) 編寫及解譯。這類格式必須符合下列目標:
- 必須不明確且自述。您應能夠從其內容直接衍生資訊清單的意義。
- 其必須能隨時間不斷演進,且能夠支援前瞻性與回溯相容性。
- 必須易於剖析,避免無謂的格式轉換。 否則,處理元件資訊清單 (包括元件管理員) 的程式碼會出現錯誤或攻擊的風險。
- 必須能夠輕鬆與與元件資訊清單互動的執行階段、元件和工具整合。
這些設計目標促成了系統自然選擇的格式:FIDL。FIDL 是 Fuchsia 中 IPC 的標準線路格式。FIDL 值類型 (即沒有帳號代碼) 可保存,並做為儲存格式使用。具體來說,使用 FIDL 信封會略過不明欄位的附加優點,這對回溯和前瞻相容性來說很實用。由於在 Fuchsia 上執行的任何執行階段都含有 FIDL 繫結,因此您可以輕鬆與程式碼整合,且不需要額外支援剖析或轉換。
ComponentDecl 的結構如下:沒有預設值,只有在不適用的欄位,或欄位來自沒有該欄位的資訊清單版本時,系統才會未填入欄位。此外,為了支援正向及回溯相容性,ComponentDecl 以及其巢狀結構為 FIDL 資料表或 FIDL 彈性聯集。
CML:元件資訊清單前端
CML (「元件資訊清單語言」) 是元件資訊清單的來源格式。它可讓使用者讀取及寫入,但也能由格式設定工具和語言伺服器等開發工具讀取及寫入。
- 也應方便瞭解基本元件架構概念的新手閱讀。
- 因此應易於呈現常見模式,且無須過多樣板。
- 我們建議不需要變更資訊清單的二進位檔表示法,而變更會影響語法但不影響資訊清單語意含義的變更。舉例來說,若從單例模式陣列變更為單一值,就不會影響輸出內容。
- 促進可維護性。尤其是允許註解。
- 它應該足以支援自動化轉換作業,例如支援大規模重構。
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 文件。
- borgcfg、GCL 和 borgmon:Google 使用的功能設定語言大致與 Kubernetes 相似,而其記錄有助於我們判斷命令式語法和宣告語法之間的優缺點。