RFC-0235:元件字典

RFC-0235:元件字典
狀態已接受
領域
  • 元件架構
說明

將字典類型引入元件架構的提案,以用於能力整合。

問題
毛皮變化
作者
審查人員
提交日期 (年-月-日)2023-10-16

摘要

這個 RFC 提議提出執行階段和宣告式 API 建立及轉送功能組合 (稱為「字典」)。

提振精神

目前元件架構僅支援「指向點」轉送 為了將能力 C 從元件 A 轉送到 B 元件,每個中繼元件都必須有路徑片段,才能轉送 C。

在許多使用案例中,將路徑轉送到 將多項功能視為單一邏輯單元如果沒有這項功能 客戶必須改用昂貴、缺乏彈性和 極硬以下列舉幾個應用實例:

  • 診斷功能,例如 LogSinkInspectSink 和追蹤記錄 幾乎每個元件都會用到這個供應器,這樣就可以簡化 明顯無法轉送拓撲
  • fuchsia.debugdata.Publisher 等分析器功能 都屬於診斷功能,只是啟用了 某些版本目前還沒有完善的方式可以設定建構作業 新增需要橫跨整個拓撲的能力這是 是因為今天,測試運作範圍才會啟用原因分析器。
  • 測試領域 Proxy 會向測試用於測試的測試案例公開介面 執行測試中的元件目前這是自訂介面 與元件連線 API 十分類似這個介面 可與測試領域 Proxy 的功能替換 如此一來,測試領域 Proxy 就不必 自行定義抽象層 功能,供測試使用
  • 任何位置都會透過多層轉送 但分為以下兩者:
    • session_manager:從 core 轉送到 「session_manager」必須重新規劃路線「session_manager.cml」。這是 功能眾多,難以維護 非平台功能外洩至 session_manager.cml
    • chromium:Chromium cml 檔案含有大量重複項目, 這樣就能輕鬆將功能分組,並轉送到 一個名稱https://fxbug.dev/42072339)
  • 元件架構環境是 擷取執行器和 可將resolvers設為使用 並隱含轉送到整個子樹狀結構如果我們可以用 但為了完成這項工作 並緩解元件架構轉送 API 的其餘部分 以環境為基礎的隱含轉送功能最低權限問題。

下列是能力統合的應用情境, 但除了考量到 這個 RFC 的提案內容

  • 某些特定板機的驅動程式想公開自訂服務, 專為平台定義的不同定義這些服務應該由 bootstrap 領域,因為所有驅動程式庫元件都存在,但並非如此 因此最好在平台拓撲中明確命名這些元件三 如果 XML 能將這些服務組合成組合,就能處理上述問題。
  • 使用 driver_test_realm 的測試出現類似問題。這些測試 將不同服務從驅動程式庫轉送至測試。在這些測試中 驅動程式庫測試領域元件會位於驅動程式和測試之間 我們希望能在這些測試中,重複使用驅動程式庫測試運作領域 而無需修改

最後,目前已有幾種現有的元件架構 API 包括分組功能但這些是各自獨立的,僅適用於 或特定情況。以下是一些例子:

  • 命名空間是所有 轉送至計畫的功能 (在其 use 宣告中)。
  • 公開目錄是一組 的功能,也就是能將元件轉送至父項的路徑,也就是 存取 API
  • 服務功能是一種分組方式 可將通訊協定和服務功能本身分組 進而形成「匯總」服務功能

我們有這麼多 API 提示,使用者 可定義自己的字典和路徑 具體做法是指示 Kubernetes 建立並維護 一或多個代表這些 Pod 的物件

相關人員

根據用途,下列團隊已識別為利害關係人 :

  • 建築
  • 診斷
  • 測試
  • 工具鏈
  • 驅動程式架構
  • 安全性

講師:hjfreyer@

審查者:

  • abarth@ (架構)
  • crjohns@ (測試)
  • Markdittmer@ (安全性)
  • miguelfrde@ (診斷)
  • surajmalhotra@ (駕駛)
  • ypomortsev@ (元件架構)

諮詢:

  • phosek@
  • kjharland@
  • anmittal@
  • wittrock@
  • novinc@

社交功能:

符合本 RFC 的兩份內部文件:使用案例與需求文件 以及核心設計文件這些文件已獲得非正式核准, 利害關係人

這些文件中的資訊已納入此 RFC,其中 以及相關內容

需求條件

這些是「必須」支援的作業字典 分析用途並從現有的分組 API 中一般化:

  • 第一級:字典是 CF API 中一流的概念。 應以能力表示。
  • 匯總:系統會選取「匯總」可用來建構字典 當中包含一系列功能
  • 擷取:經過「擷取」擷取個別事件的 能夠轉送及使用字典能力,就像任何一樣 技術。這大致是匯總的相反詞。
  • 委派:可在元件之間傳送字典。
  • 巢狀結構:由於字典是一種能力,因此字典可以包含 其他字典中
  • 結構:字典會標上中繼資料,方便指明 容器有哪些功能
  • 擴充功能:有一個作業可以建構新的字典 B', 繼承 B 的內容,並新增其他功能。
  • 易用性:字典內容可能會隨時間改變。不過 可能會存在限制對內容的可變動性 專屬於您的字典

設計

定義

字典的定義為一包鍵/值組合的包,其中鍵為 功能名稱 (例如fuchsia.example.Echo),而值是 CF 技術。

「功能名稱」是指一或多個序列 字元集 [A-Za-z0-9_-.] ,大小為 1 到 N (目前 N = 100, 我們日後可能會擴大這項功能的適用範圍。

執行階段的字典

我們將引入一個公用 FIDL 通訊協定,為 字典中。作為 FIDL-虛擬程式碼:

library fuchsia.component;

type DictionaryEntry = resource struct {
    key DictionaryKey;
    value Capability;
};

protocol Dictionary {
    Insert(DictionaryEntry) -> ();
    Remove(DictionaryKey) -> (Capability);
    Lookup(DictionaryKey) -> (Capability);
    Enumerate() -> Iterator<DictionaryKey>;
    Clone();
};

我們也將推出可公開搜尋的 FIDL 通訊協定, 呼叫端來建立空白字典。

後續設計工作會決定 Capability

元件宣告中的字典

我們先從一些正式程序開始,以便定義 作業。我們要定義四個 元件:元件輸入字典元件輸出字典程式輸入字典程式輸出字典。這些成果 根字典

元件輸入字典是包含所有功能的字典 按父項 offer 到元件;也就是所有功能 元件可轉送 from parent 的流量

元件輸出字典是包含所有功能的字典 將元件 expose 套用至其父項;也就是所有需要 父項可以轉送 from #component

程式輸入字典是包含所有功能的字典 透過元件 use

程式輸出字典是包含元件所有 capability 宣告。

我們可根據下列定義來表達能力轉送作業:

  • useofferexposecapabilities轉送作業, 轉送字典之間的功能
    • use 將能力從根字典轉送至程式輸入 字典
    • expose 會將能力從根字典轉送至元件 輸出字典
    • offer 會將能力從根字典轉送至子項的 。
    • capabilities 會在程式輸出字典中提供能力 可供轉送

透過這項設計,我們將一般化,讓轉送作業能夠 將任意字典當做來源,而不僅是根:

  • use 將能力從字典轉送至程式輸入 字典
  • expose 將能力從字典轉送至元件輸出 字典
  • offer 將能力從字典轉送至子項元件 輸入字典 或其他字典

宣告

如何定義全新的空白字典:

capabilities: [
    {
        dictionary: "diagnostics-bundle",
    },
],

如要定義會沿用現有字典內容的字典, 透過 extends 提供該字典的路徑 (請參閱 擴充功能):

    {
        dictionary: "diagnostics-bundle",
        extends: "parent/logging-bundle/sys",
    },

匯總

如要將能力匯總至字典中,請將功能轉送至字典中, offer 中的 to 關鍵字。由於字典是由 元件,其包含該元件的根字典為 self。相同的關鍵字 都支援一般 offer。舉例來說,您可以將 使用 as 關鍵字,在目標字典中加入能力的名稱。

capabilities: [
    {
        dictionary: "diagnostics-bundle",
    },
],
offer: [
    {
        protocol: "fuchsia.logger.LogSink",
        from: "#archivist",
        to: "self/diagnostics-bundle",
    },
    {
        protocol: "fuchsia.inspect.InspectSink",
        from: "#archivist",
        to: "self/diagnostics-bundle",
    },
    {
        directory: "publisher",
        from: "#debugdata",
        to: "self/diagnostics-bundle",
        rights: [ "r*" ],
        as: "coverage",
    },
],

委派

委派代表轉送字典:

offer: [
    {
        dictionary: "diagnostics-bundle",
        from: "parent",
        to: "#session",
    },
],

與其他能力路徑一樣,您可以使用 as 關鍵字。

offer: [
    {
        dictionary: "logging-bundle",
        from: "parent",
        to: "#session",
        as: "diagnostics-bundle",
    },
],

對等的執行階段 API 將 動態優惠

建立巢狀結構

字典可以透過轉送到其他字典,以包含其他字典 使用 aggregate 語法建立另一個字典:

capabilities: [
    {
        dictionary: "session-bundle",
    },
],
offer: [
    {
        dictionary: "driver-services-bundle",
        from: "parent",
        to: "self/session-bundle",
    },
],

擷取

按照正式程序進行,我們會擴充 from 關鍵字,不僅只接受根字典,也是以巢狀結構形式 根層級字典

如要從字典中擷取能力,請在 from 中為字典命名。這個 字典相對於根字典 (parent#child 等)

offer: [
    {
        protocol: "fuchsia.ui.composition.Flatland",
        from: "parent/session-bundle",
        to: "#window_manager",
    },
],

這個方法也適用於 use

use: [
    {
        protocol: "fuchsia.ui.composition.Flatland",
        from: "parent/session-bundle",
    },
],

如果字典會嵌入其他字典中,也可以使用擷取功能:

use: [
    {
        protocol: "fuchsia.ui.composition.Flatland",
        from: "parent/session-bundle/gfx",
    },
],

擴充功能

在字典定義中使用 extends 選項,從另一個資料夾繼承 字典:

capabilities: [
    {
        dictionary: "session-bundle",
        // `session-bundle` is initialized with the dictionary the parent
        // offered to this component, also called `session-bundle`.
        extends: "parent/session-bundle",
    },
],
offer: [
    {
        dictionary: "session-bundle",
        from: "self",
        to: "#session-manager",
    },
    {
        protocol: "fuchsia.ui.composition.Flatland",
        from: "#ui",
        to: "self/session-bundle",
    },
],

可變動性

以宣告方式建構的字典無法變更,因此非常實用 security 屬性。才能修改字典 就必須在 runtime 中建立。

字典中功能的中繼資料

將功能放入字典中時,他們會保留所有類型 和中繼資料,這兩者與 如字典本身

例如,如果能力具有 optional 可用性,就屬於這種情況。 會由元件 A 新增至字典,而 B 元件會擷取 能力,在擷取時將有 optional 可用性 即使字典本身的可用性為 required

我們可能會在匯總時對可用性施加某些限制。 舉例來說,禁止將 required 能力放入 optional 字典,因為這屬於一般的不變體, 從目標轉送到來源時,可用性一律不會降低。

執行階段與宣告式字典之間的互通性

在執行階段建立的字典必須與以下項目的字典互通: 元件宣告如果不是的話,就會強制使用者進入 只選擇其中一種,因為這樣才能證明 然而,組合的基礎不足以解決這兩種使用情境 以類似的方式展示

互通性的設計細節將做為後續追蹤 提案。

這項功能的主要已知用途是轉送的驅動程式庫架構 已填入執行階段的 Service Bundle。

實作

Cml 中的到達網頁字典會遵循一般管道來導入 Cml 功能首先,在 cml 和 component.decl 中新增字典 結構定義。接著,我們會更新 cmccm_fidl_validatorcm_rust,以及 realm_builder 用於編譯、驗證及代表字典。堅持將 這個外掛程式也能更新辨識字典 字典路徑

系統已在處理相關工作,以將字典 (做為信任類型) 整合至 和轉送引擎字典 API 的實作 應根據這項工作建立字典,將這些字典做為後端 以及用於轉送字典功能的傳輸工具。

成效

沒有任何特殊的效能注意事項。轉送字典應為 就能更快或更快 個別。

人體工學

改善建築物元件拓撲的人體工學是 這項設計。

導入新功能會自然提高 API 的複雜度 我們相信這不只是因為日益降低的複雜性, 透過在拓撲中納入字典

回溯相容性

但 cmc 尚未針對元件資訊清單功能提供版本管理支援,因此 必須注意,避免與預建資訊清單的相容性問題發生。 幸好,為字典引進的所有新語法都能與 所以也能更輕鬆執行工作例如:目前的名稱 from 的語法成為新路徑語法的特殊案例。

如果能力路徑的一部分通過字典,則任何安全性政策 所有相關的能力仍須適用。

安全性考量

在字典中轉送功能時,會失去部分透明度,因為 字典中功能的身分的身分會隱藏 路徑中的中繼元件不過,他們仍可透過 沿著路線向供應商查詢。這是故意的行為 以實現字典的彈性和功能。

宣告式建立的字典無法變更。針對這些字典 可以執行 進行深度優先搜尋,從目標到 。

如果在字典替換環境時,這項功能會強化安全性 系統的防護機制與環境不同 方法與其他功能相同

隱私權注意事項

此提案對隱私權沒有任何影響。

測試

我們會像多數元件管理員功能一樣進行測試,在 component_managercmc,以及 component_manager/tests。我們也會加入整合測試,以便檢查 會對含有字典的路徑套用練習字典和政策。

說明文件

我們會更新 //tools/lib/cml 中的 rustdoc。

新增頁面至 //docs/concepts/components 說明字典。

新增範例至 //examples/components

缺點、替代方案和未知

替代方法 1:字典中的「in」和「into」關鍵字

宣告

「字典功能」是一種會授予 cml/component.decl 能力類型 字典的存取權限。

宣告字典的方式與其他元件架構能力相同。是兩個 字典建立方式的變化版本,取決於是否有 extends 字詞。

首先,您可以定義全新的空白字典:

capabilities: [
    {
        dictionary: "diagnostics-bundle",
    },
],

或者,您也可以定義字典,其內容會沿用現有 方法是在 extends 中指定字典路徑和 from (請參閱擴充功能):

    {
        dictionary: "diagnostics-bundle",
        extends: "logging-bundle/sys",
        from: "parent",
    },

匯總

如要將能力匯總至字典中,請使用 into 關鍵字:

capabilities: [
    {
        dictionary: "diagnostics-bundle",
    },
],
offer: [
    {
        protocol: "fuchsia.logger.LogSink",
        from: "#archivist",
        into: "diagnostics-bundle",
    },
    {
        protocol: "fuchsia.inspect.InspectSink",
        from: "#archivist",
        into: "diagnostics-bundle",
    },
    {
        protocol: "fuchsia.debugdata.Publisher",
        from: "#debugdata",
        into: "diagnostics-bundle",
    },
],

委派

與主要設計相同。

建立巢狀結構

只要將字典轉送到其他字典,即可包含這些字典 轉換為字典:

capabilities: [
    {
        dictionary: "session-bundle",
    },
],
offer: [
    {
        dictionary: "driver-services-bundle",
        from: "parent",
        into: "session-bundle",
    },
],

擷取

我們引進新的 in 關鍵字,以指定字典以擷取 所有文字

in 存在時,能力關鍵字 (protocol 等) 指的是 能力,而不是由工作人員直接提供的能力 「from」中命名的元件

in 可以是名稱或路徑 (名稱可以視為去產生大小寫形式)。如果 這個名稱,指的是 from 顯示的字典。如果是路徑, 路徑的第一個區段會指定由 from 提供的字典,而 路徑的其餘部分會指定連至在此字典中的字典路徑。

useofferexpose 支援 in。內容一律為選填欄位。

offer: [
    {
        protocol: "fuchsia.ui.composition.Flatland",
        from: "parent",
        in: "session-bundle/gfx",
        to: "#window_manager",
    },
],
expose: [
    {
        protocol: "fuchsia.ui.composition.Flatland",
        from: "#scenic",
        in: "gfx-bundle",
    },
],
use: [
    {
        protocol: "fuchsia.ui.composition.Flatland",
        in: "session-bundle/gfx",
    },
],

擴充功能

在字典定義中使用 extends 關鍵字,從另一個資料夾繼承 字典:

capabilities: [
    {
        dictionary: "diagnostics-bundle",
        extends: "parent/logging-bundle/sys",
    },
],
offer: [
    {
        dictionary: "diagnostics-bundle",
        from: "self",
        to: "#session-manager",
    },
    {
        protocol: "fuchsia.tracing.provider.Registry",
        from: "#trace_manager",
        into: "diagnostics-bundle",
    },
],

替代方法 2:能力 ID 中的路徑

您不必在 from 中指定字典的路徑,路徑可能會是 部分能力 ID 的一部分 (protocoldirectory 等)

匯總

與主要設計相同。

委派

與主要設計相同。

建立巢狀結構

與主要設計相同。

擷取

如要從字典中擷取能力,請指定能力的路徑 在能力 ID 的字典中 (protocoldirectory、 等)。

offer: [
    {
        protocol: "session-bundle/fuchsia.ui.composition.Flatland",
        from: "parent",
        to: "#window_manager",
    },
],

目標中的名稱會預設為最後一個路徑元素或「dirname」。 (fuchsia.ui.composition.Flatland).或者,您也可以使用 as 重新命名:

offer: [
    {
        protocol: "session-bundle/fuchsia.ui.composition.Flatland",
        from: "parent",
        to: "#window_manager",
        as: "fuchsia.ui.composition.Flatland-windows",
    },
],

這也適用於 use,其可提供字典中的能力 加入計畫與其他 use 宣告一樣,預設目標路徑 在 /svc 上重新基準名稱 (最後一個路徑元素):

use: [
    {
        protocol: "session-bundle/fuchsia.ui.composition.Flatland",
        path: "/svc/fuchsia.ui.composition.Flatland",  // default
    },
],

路徑語法也適用於其他字典中的字典:

use: [
    { protocol: "session-bundle/gfx/fuchsia.ui.composition.Flatland" },
],

擴充功能

在字典定義中使用 origin: #... 選項,從另一個資料夾繼承 字典:

capabilities: [
    {
        dictionary: "session-bundle",
        // Source of the dictionary to extend (in this case, the one named
        // "session-bundle" from the parent)
        origin: "#session",
        from: "parent",
    },
],
offer: [
    {
        dictionary: "session-bundle",
        from: "self",
        to: "#session-manager",
    },
    {
        protocol: "fuchsia.ui.composition.Flatland",
        from: "#ui",
        into: "session-bundle",
    },
],

替代方法 3:功能 ID 成為路徑

名稱 ->路徑

確切來說,cml 中的能力 ID 是名稱,這類 ID 沒有本質上 巢狀結構例如:

offer: [
    {
        protocol: "fuchsia.fonts.Provider",
        from: "#font_provider",
        to: "#session-manager",
    },
],

但功能 ID 確實能對應至 capabilities 中的路徑 和 use 區段以通訊協定來說,這通常屬於隱含的: 則 cmc 會填入 /svc/${capability-name} 的預設路徑。例如:

use: [
    {
        protocol: "fuchsia.fonts.Provider",
        // path in namespace
        path: "/svc/fuchsia.fonts.Provider",
    },
],
capabilities: [
    {
        protocol: "fuchsia.fonts.Provider",
        // path in outgoing directory
        path: "/svc/fuchsia.fonts.Provider",
    },
],

這個替代方案會能力中的路徑。更正式:

  • 功能 ID 是一或多個名稱 字元集 [A-Za-z0-9_-.],包含 1 至 100 個半形字元,並以半形逗號分隔 由 / 個字元組成。不允許開頭是 /
    • 或規則運算式語法:[A-Za-z0-9_-]{1,100}(/[A-Za-z0-9_-]{1,100})*
    • 現有的能力 ID 與新的 語法。

下文將說明這個語法如何自然奠定組合的基礎。

匯總

如要將功能匯總成字典,請以相同路徑轉送這些功能 前置字串:

offer: [
    {
        protocol: "fuchsia.logger.LogSink",
        from: "#archivist",
        to: "all",
        as: "diagnostics/fuchsia.logger.LogSink",
    },
    {
        protocol: "fuchsia.inspect.InspectSink",
        from: "#archivist",
        to: "all",
        as: "diagnostics/fuchsia.inspect.InspectSink",
    },
    {
        protocol: "fuchsia.debugdata.Publisher",
        from: "#debugdata",
        to: "all",
        as: "diagnostics/fuchsia.debugdata.Publisher",
    },
],

委派

委派功能只會按照以下方式轉送字典:

offer: [
    {
        dictionary: "diagnostics",
        from: "parent",
        to: "#session",
    },
],

建立巢狀結構

您可以透過建立巢狀結構的 字典的路徑前置字串:

offer: [
    {
        dictionary: "driver-services-bundle",
        from: "parent",
        to: "#session-manager",
        as: "session/driver-services",
    },
],

擷取

您只需在您要擷取的字典中命名能力即可:

offer: [
    {
        protocol: "session-bundle/fuchsia.ui.composition.Flatland",
        from: "parent",
        to: "#window_manager",
        as: "fuchsia.ui.composition.Flatland",
    },
],

這個方法也適用於 use

use: [
    {
        protocol: "session-bundle/fuchsia.ui.composition.Flatland",
        path: "/svc/fuchsia.ui.composition.Flatland",
    },
],

如果字典嵌入其他字典中 (TODO: 範例)

擴充功能

重新命名功能,使其路徑前置字串與字典一致:

offer: [
    {
        protocol: "session-bundle",
        from: "parent",
        to: "#session-manager",
    },
    {
        protocol: "fuchsia.ui.composition.Flatland",
        as: "session-bundle/fuchsia.ui.composition.Flatland",
        from: "#ui",
        to: "#session-manager",
    },
],

為什麼要使用字典而非目錄?

與其導入字典,不如使用 fuchsia.io 目錄做為 套裝組合的基本類型。從一個層面來說,這是一種吸引人:目錄 並提供專屬的階層架構。不過 有許多關於使用目錄的引數:

  • VFS 型別系統提供的資訊與 CF 類型系統不同。 例如服務、目錄和儲存空間 VFS 中的子目錄,即使在 CF 中屬於不同類型也是如此。
  • 目錄的介面比 所需的基礎架構功能包括 NODE_REFERENCE、連結 旗標、屬性、資料檔案等項目與合併用途無關。
  • VFS 程式庫的大小對某些應用程式而言太大,尤其是 驅動程式。因此 共享中有 //sdk/lib/component/outgoing 個相片庫連結 程式庫輔助程式 (//sdk/lib/svc),而非 VFS 程式庫 但須犧牲功能和透明度
  • 這沒有一種 VFS 實作,但有兩個獨立的 C++ 實作 以及一個 Rust 實作項目這些實作方式有些微差異 以及功能有落差這並不是字典問題,因為字典中 單一字典實作。
  • 目錄會增加編寫程式碼生成繫結的難度 表示程式以獨立方式提供或消耗的各項能力 語言元素。
  • 目錄自然不支援「匯總」或「擴充功能」 作業。必須藉由提供新目錄來模擬,而且其中有些 節點會重新導向至舊節點,這既容易實作又容易 。

日後的工作

針對驅動程式庫程式的用途,我們會單獨提出隨附設計建議。 僅憑本提案中的功能,無法完全解決這些問題。

這項設計開啟了更加經濟能力轉送的語法語法。 而不是能力名稱與 from 各自獨立的屬性 可以合併成單一路徑,在概念上,這個路徑就稱為字典 當中包含所有根字典例如:

offer: [
    {
        protocol: "#ui/fuchsia.ui.composition.Flatland",
        to: "#session-manager",
    },
],

這個語法有個好屬性:它會自然而然地使用一般化原則 轉送整個根字典:

offer: [
    {
        // Plumb all capabilities from parent to child #session-manager
        dictionary: "parent",
        to: "#session-manager",
    },
],

另外還有一個通用版本,將語法統一 更多:

route: [
    {
        // Path to source capability in dictionary
        src: "#ui/fuchsia.ui.composition.Flatland",
        // Path of target capability in dictionary
        dst: "#session-manager/fuchsia.ui.composition.Flatland",
    },
],

route: [
    {
        src: "parent",
        dst: "#session-manager/parent",
    },
],

既有藝術品和參考資料

功能組合已經舊的概念。有很多內部前文文件 提出類似概念的提案