RFC-0093:元件資訊清單的設計原則 | |
---|---|
狀態 | 已接受 |
區域 |
|
說明 | 關於用於元件資訊清單的 `.cml` 和 `.cm` 格式的設計備註。 |
問題 | |
Gerrit 變更 | |
作者 | |
審查人員 | |
提交日期 (年-月-日) | 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 為基礎的設定語言,可做為產生 ComponentDecl 的簡易 DSL。透過使用 JSON5,CML 可運用許多開發人員熟悉的語言,並廣泛用於 Fuchsia 的其他部分。與 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,其歷史記錄有助於我們瞭解命令式和宣告式語法的取捨。