RFC-0242:設定功能

RFC-0242:設定功能
狀態已接受
領域
  • 元件架構
說明

將設定功能新增至元件架構

更小鳥
作者
審查人員
提交日期 (年月分)2024-02-05
審查日期 (年-月-日)2024-04-11

摘要

概述元件架構中的設定capabilities使用方法,以及將會新增至 CML 檔案支援這些功能的語法。

請注意,本文件會取代先前的結構化設定 RFC 部分 (如先前的藝術章節所述)。

提振精神

Fuchsia 中的元件會使用結構化設定取得設定值。今天的設定值大多從元件的套件中載入。父項元件可在啟動動態元件時以命令方式設定設定值,但 Fuchia 中的大多數元件都是靜態的。

有許多動機可新增這項功能:

  • 允許靜態父項設定子項設定。
  • 將單一設定值轉送至多個元件。
  • 提供 CML 檔案中的設定值。

設定功能的第一位客戶是系統組合,因為這項功能可能會導致技術負債。因為除了編輯該元件的套件,目前無法為靜態元件提供設定,因此會造成技術債。系統組件目前會開啟 fuchsia 套件,編輯其設定檔,然後重新封裝。這會造成技術債,因為此操作會變更套件的雜湊值,而設定檔值檔案在技術上是為元件的「不公開」API,無法輕易演變。

如果是無法重建的樹狀套件,設定功能提供了一種方法來設定這些元件。目前無法在靜態拓撲中編輯這些元件的設定。

這項功能在日後的許多設定用途中可能很實用。

相關人員

講師:neelsa@google.com

審查者:

  • 系統組裝:aaronwood@google.com
  • 元件架構:geb@google.com
  • 安全性:Markdittmer@google.com
  • 駕駛架構:surajmalhotra@google.com
  • 元件架構:wittrock@google.com

社交化:在編寫 RFC 之前,我們已與元件架構團隊討論這個問題。

相關規定

設定功能可讓 CML 作者設定靜態元件的設定值。這些 API 可讓您透過拓撲轉送設定值,讓多個元件可以使用相同的值。透過拓撲允許間接祖係指定值,而現有的功能只能允許直接父項指定值。

設定功能應盡可能遵循現有的元件架構功能,以便與系統的其餘部分保持一致。

設計

大部分的設計都是用來宣告及轉送設定能力的 CML 語法。設定能力在 CML 中定義了類型的類型和值。設定能力會轉送至想要使用該功能的元件。在使用設定能力的元件透過現有的結構化設定程式庫啟動元件時,使用設定功能的元件將能看到該值。

以下是定義設定能力的範例:

// Configuration capabilities can be defined in any component.
// When a configuration capability is defined, a value must be set for it.
capabilities: [
  {
    // Define the name of the capability.
    config: "fuchsia.netstack.UseNetstack3",
    // Define the type of the configuration.
    type: "bool",
    // When defining a configuration capability, there *must* be a value.
    // If the route for the configuration capability ends at this definition, the
    // value of the capability will always be this value.
    value: "true"
  },
  // The below shows a string config.
  {
      config: "fuchsia.config.MyString",
      type: "string",
      max_size: 100,
      value: "test",
  },
  // The below shows a vector config.
  {
      config: "fuchsia.config.MyUint8Vector",
      type: "vector",
      element: { type: "uint8" },
      max_count: 100,
      value: [1, 2, 3 ],
  },
]

config 能力 typeelementmax_countmax_size 欄位的意義,與 config 段落中的用途相同。capabilities 區塊支援 config 段落支援的所有值。

type 欄位支援下列項目:

  • bool
  • uint8、uint16、uint32、uint64
  • int8、int16、int32、int64
  • string
  • 向量

使用區塊支援與功能區塊相同的 typeelementmax_countmax_size 欄位。

以下是使用設定能力的語法範例:

// Using a configuration capability means that this configuration will show
// up in the component's structured config at runtime with the specified `key`
// name.
// NOTE: Using a configuration capability will override the value in the Config
// Value File (CVF) and the value obtained from the "mutability" setting.
use: [
  {
    config: "fuchsia.netstack.LaunchProcess",
    // This is the name that the component will see in its Structured Config
    // struct. If the `use` is optional this must match a name in the "config"
    // block of the component's manifest.
    key: "can_launch_process",
    // The using field needs the type information so that the component's
    // Config Value File format can be created.
    type: "bool",
    // From is identical to other capabilities.
    from: "parent",
  },
  // The below shows a vector config.
  {
    config: "fuchsia.netstack.MyUint8Vector",
    key: "my_vector",
    type: "vector",
    element: { type: "uint8" },
    max_count: 100,
    from: "parent",
  },
  // The below shows a string config.
  {
    config: "fuchsia.netstack.MyString",
    key: "my_string",
    type: "string",
    max_size: 256,
    from: "parent",
  },
]

以下是轉送設定能力的語法範例:

// Expose and Offer behave the same as any other capability.
expose: [
  {
    config: "fuchsia.netstack.UseNetstack3",
    as: "fuchsia.mycomponent.UseVersion3",
    from: "self",
  },
]
offer: [
  {
    config: "fuchsia.config.MyString",
    as: "fuchsia.mycomponent.ProcessName",
    from: "self",
    to: "#mychild",
   },
]

選用功能

如果元件使用設定能力並將可用性設為 optional,且該能力是從 void 轉送,則元件會從設定值檔案 (CVF) 接收值。這項功能是用來支援軟遷移以更新設定的。

淘汰「config」區塊

在設定功能之前,系統會在 CML 的 config 表格中宣告設定欄位。這項資訊現在會由 use 權杖取代。也就是說,為元件產生的結構化設定結構定義會是 use 區塊和 config 節錄中的欄位宣告聯集。

一旦所有結構化設定用戶端都遷移至設定功能,系統就會移除 CML 中的設定區塊支援功能。

淘汰「可變動性:父項」功能

在設定功能之前,您可以將設定值宣告為 mutability: parent,讓該元件的父項可以變更值。

這項功能的使用者將自父項遷移至 use 的設定能力。所有使用者全數遷移後,系統就會移除這項功能。

實作

這些 CML 功能的實作相對直觀,可在幾個 CL 中以樹狀結構完成。用戶端可隨時改用設定功能,因此不會影響現有的結構化設定功能。

我們必須確保 Scrutiny 瞭解設定功能,並驗證特定產品有指定的設定。

效能

由於元件架構需要對元件使用的設定功能執行轉送,因此元件啟動速度可能會稍微變慢。如果功能來自未解決且需要下載的元件,就可能很明顯。對已解決的元件來說,這應該可以忽略不計。

人體工學

這個新 CML 能力的人體工學與現有功能相同。新增及轉送設定能力有點複雜,但我們選擇了該語法,以便盡可能比對現有的能力語法。系統也會盡可能選擇該語法來與現有的 config 區塊語法相符。如果兩種語法發生衝突,則建議使用現有的能力語法。比對現有的語法可以減少熟悉元件架構的使用者認知。

CF 團隊可決定將 config 區塊保留為用來宣告設定能力的語法糖,或在需要更適合人體工學的情況下添加額外的語法糖。

回溯相容性

這是新功能。它可與現有的結構化設定功能回溯相容。

值得注意的是,將設定能力轉送至元件的優先程度,一律高於 CVF 檔案中的值。如果元件有選用設定能力路徑,且沒有路徑,則系統會使用 CVF 檔案中的值。

安全性考量

這項功能不會影響安全性。暫時性的 CML 調查工具將適用於這個新的能力類型。

可能令人難以理解,以這種方式設定功能,會比在元件套件中編輯值的現有策略更明顯。

如果元件使用必要的設定能力,且沒有轉送到元件,則無法啟動元件。這應該不是安全性問題,因為元件的父項是受信任的元件,這些路徑可以透過靜態方式驗證是否正確。

隱私權注意事項

這項提案不會影響隱私權。

測試

這項功能需要單元和整合測試。一般測試範圍包括:

  • 剖析新的 CML 語法。
  • 透過拓撲轉送新能力。
  • 嘗試啟動缺少設定功能的元件。
  • 嘗試啟動具有錯誤類型設定能力的元件。
  • 以設定能力啟動動態元件。

這項功能需要新增下列測試至 Scrutiny:

  • 測試 Scrutiny 可解析設定功能的值。
  • 測試不同設定值來源的優先順序/覆寫邏輯。
  • 測試設定功能、設定區塊和可變動性之間的互動。

這些測試都不需要新的測試基礎架構。

說明文件

必須更新 Fuchsia.dev,才能使用設定功能的說明文件。系統會將現有的能力文件做為這份新說明文件的範本。

缺點、替代項目和未知

替代做法:實作設定覆寫服務

原始的結構化設定 RFC 建議直接採用元件套件的結構化設定。RFC 特別指出它並未嘗試處理「其他元件 (父項元件和管理員元件除外)」的設定資料。替代方法是繼續不支援以能力為基礎的設定配置。

相較於覆寫服務,「設定功能」的缺點之一是設定功能較為詳細且複雜。要在全球實作,一開始會比較簡單。然而,Fchsia 發現,從長遠來看,以能力為基礎的系統最終將變得較易於組合且易於理解。若能指出特定設定僅用於部分元件拓撲,或是在兩個不同元件中使用兩個不同的值,會很有幫助。設定功能可方便表達及納入 Fuchsia 其他地方使用的功能型系統。使用現有的 CML 語法進行設定,可讓貴賓開發人員更輕鬆地瞭解這項功能,並且使用元件架構的現有工具順利組合。

缺點:許多額外用途的欄位

如果保留 use 區塊中的類型資訊,系統會新增 6 個額外欄位,這些欄位僅適用於設定功能。

您可以將這 6 個欄位與一個欄位結合成一個欄位,但是新增欄位是建議使用的做法,因為它會保持語法靠近現有的 config 區塊語法。

缺點:協調類型資訊與轉送

將設定結構定義放在 use 宣告中的缺點之一,是 use 區塊會定義類型資訊,並定義轉送。有些元件可能希望在不指定轉送的情況下定義設定,然後在不同情境中以不同的方式轉送設定。如果類型資訊與「Use」區塊位於不同位置,這會變得更加簡單。

元件作者如果想要變更類型定義方式,就必須修改其 use 區塊,而不只是修改 config 區塊。

如果設定定義和轉送的組合成為開發人員的永久階段,元件架構團隊可能會重新審視這項決策。

替代方法:保留 config 區塊中的設定類型定義

另一種替代方法是,use 宣告中沒有「類型」欄位,而是改以現有「config」區塊中的類型資訊。在舊版 RFC 中就是如此。這個替代方法可以解決合併類型資訊與轉送衝突的問題。這可讓用戶端更輕鬆地在一個位置定義設定,並將設定轉送至其他位置 (可能包括根據不同設定而以不同方式轉送不同的 CML 資料分割)。

在目前的結構化設定實作中,元件管理員會在啟動元件時將設定「推送」到元件,元件管理員必須確保轉送能力的類型與目標結構化設定欄位的類型相符。因此決定將類型資訊放在 use 宣告中,因為此功能與功能宣告是對稱。當元件管理員執行轉送時,必須確保類型資訊對齊,也就是理論上來說,資訊應同時包含在路徑的兩端 (功能與使用) 中。

要在 use 宣告中保留類型資訊的另一個原因是,可以保留 use 宣告中的所有資訊,不需要相符的「config」區塊項目。這會將資訊集中儲存在 CML 檔案中,讓稽核更容易進行。

替代做法:use 宣告中的 as 欄位

config 區塊內封裝「結構化設定」欄位名稱和類型資訊後,即可使用 as 指定要提供能力的欄位。這與在 CML 中大多數非 path「重新命名」的做法一致。

而是改用 key 字詞,因為欄位的運作方式與其他 as 欄位不同。as 通常為選用項目,但 key 為必要項目。如果能力為選用功能,key 也必須與 config 區塊中的現有鍵相符。

不明:透過功能平衡現有的結構化設定不一致

現有的結構化設定,有很多方式與其他功能的運作方式不一致。

不一致的情況是,程式主要會依賴元件資訊清單中定義的結構化設定格式。通常是依附於程式的資訊清單,而結構化設定則可讓這個關係循環。事實上,結構化設定建構規則需要在元件、元件資訊清單和程式之間額外新增層。設定功能不會解決這種循環不一致的問題,但應可透過後續追蹤 RFC 解決。

另一個不一致的情況是,結構化設定在啟動時會「推送」至元件,在元件存取時,其他功能會「提取」到元件。這個 RFC 也不會解決這類不一致問題。此 RFC 的目的是在元件資訊清單內新增轉送和能力支援。此 RFC 不會變更程式和結構化設定之間的介面,因此所需的遷移作業數量有限。

實作設定功能並查看使用方式後,Fusia 將會更妥善地解決這些不一致的問題。更多的用戶端資料將有助於我們解決問題點,並實施後續變更。

優先藝術與參考資料

先前的結構化組態通訊協定: