RFC-0154:子套件

RFC-0154:子套件
狀態已接受
領域
  • 軟體推送
說明

允許套件在個別版本的子套件中宣告依附元件,以改善一致性和可重複使用性。

問題
毛皮變化
作者
審查人員
提交日期 (年-月-日)2022-01-25
審查日期 (年-月-日)2022-03-23

摘要

這是在 Fuchsia 提供的支援,有助於確立及解決相關問題 子套件。子套件是某個套件 (「A」) 至另一個套件 (「A」) 的具名參照 套件 (「B」),指定單向依附元件 (從「A」到「B」)。子檔案包 也可含有子套件,建立具有向非循環圖 (DAG) 從頂層套件取得相關的 版本固定版本套件使用子檔案包後 「A」套件中的資源即為「B」套件及其子套件名稱 是由包含的套件定義如果「B」是「A」的子套件,那麼 產生「A」的可用 (例如 Fuchsia 封存、圖庫) 也必須將「B」設為廣告。因此,子套件會啟用兩項重要功能 系統屬性:

  • 功用:將特定套件的程式 (或測試) 包裝在一起 依附元件
  • 原子性 - 如果套件含有子套件,系統應保證其 已成功解決此檔案的所有子套件 均已解決。(此 RFC 中提議的做法會急切保證此做法) 先解析整個子套件階層,再傳回 套件解決要求的結果)。
  • 可重新定位 - 可以發布的套件 (具備所有必要項目) 將資源發布到單一封存檔案 (例如下載) 或 Fuchsia 套件伺服器。

提振精神

這個 RFC 提議表示及支援巢狀概念的方法 跨套件依附元件 (子套件)而套件目前則 允許依附其他套件,此 RFC 修訂了限制 除了透過遏制之外,套件不得依賴其他套件。

請注意,本 RFC 中討論的初始激勵用途 和測試相關的子套件可能適用於其他情況 系統會先開放子檔案包進行測試,以便 幾個剪接角來進行測試? 除了排定工作時程外,我們的目的是全面支援 測試和實際執行情境

為何現在發行?

目前最常見的用途,是推動跨套件套裝方案的需求 依附元件在測試情境中測試需要執行特定元件 (通常為假或模擬) 身處其環境下,與其下調的元件 測試。必須仰賴及包含依附元件的確切版本 防止全域系統狀態 (例如,即將故障的套件組合 ),影響測試的正確性。我們稱之為這個屬性 「密封包裝」

我們在樹狀圖中納入所有元件依附元件,藉此將測試套件在樹狀結構中 單一套件樹狀結構外 (OOT),現狀在於存續 的值。這些測試並非完全以傳統方式封裝, 可以使平台套件網址成為隱含 ABI。

舉例來說,現在的 Flutter 整合測試宣告了 Fuchsia 的依附元件 查看元件網址 fuchsia-pkg://fuchsia.com/scenic#meta/scenic.cm。這樣就宣告了 Fuchsia 平台一些風景照 您可透過該網址參照使用 Google Cloud 產品如果是 View,或是其依附元件 ( 測試開發人員也必須發現並宣告、變更其介面。 或遭到移除,測試可能會在執行階段失敗。這已經是常見用途了 但隨著我們擴大規模,這種情況只會越來越嚴重。

相較之下,Flutter 整合測試作者可以:

  1. 在建構時取得包含特定景觀版本的套件。 (相關機制超出範圍)。
  2. 將該套件納入測試套件的子套件中。
  3. 在測試中使用網址 scenic#meta/scenic.cm 宣告子元件 元件資訊清單,而非 fuchsia-pkg://fuchsia.com/scenic#meta/scenic.cm

這個版本的測試比較美觀,運作原理都相同 無論裝置搭載的景觀版本 並開始執行

注意:子套件會啟用像這樣的 OOT 測試情境,但 要在測試中重複使用 Fuchsia 平台套件的發布情形 符合 RFC 規範要求 RFC 經過核准後 定義這項程序似乎是 Fuchsia SDK 的延伸,

我們鼓勵在現場和 OOT 之間提供一致的體驗 元件:單一測試套件,明確指出其所有她的 依附元件,以不可分割群組的形式進行測試。

而不是樹狀結構內重新套用現有策略 (這需要 建構包含多個元件的新套件 以子套件巢狀結構的形式提議支援跨套件依附元件。 如此一來,我們就能獨立套件和依附於元件 名稱使用速度也變得很複雜

相關人員

講師:hjfreyer@google.com

審查者:

名稱 重點領域
wittrock@google.com 瑞典文
jsankey@google.com 瑞典文
geb@google.com 元件架構
shayba@google.com 建構
etryzelaar@google.com 工具
aaronwood@google.com 組裝/包裹移動
cgonyeo@google.com RealmBuilder
ampearce@google.com 安全性

諮詢:Computerdruid@google.com

社交功能:

在發布之前,SWD 團隊參與了此 RFC 的初始草稿。 元件架構團隊已掌握工作進度 並在每週會議期間向成員提供與範圍和功能相關的意見回饋 作為 RFC 作者共同參與

設計

子套件影響的用途

  • 巢狀結構套件依附元件的套件內宣告
    • 套件「可能」含有列出其子套件的中繼資料檔案,然後建立 系統「必須」能根據 指定套件目標的依附元件
  • 相對元件解析度
    • 舉例來說,開發人員可以替換元件的參照 fuchsia-pkg://servername/some-package#meta/child_component.cm,其中包含 相對參照 child_package#meta/child_component.cm;在哪? child_package 是具名參照的參照網址 (或「父項套件」) 至 some-package,版本鎖定 (依套件雜湊)。
  • 套件依附元件樹狀結構遍歷
    • 例如發布單一頂層套件、套件伺服器 可以使用內嵌套件參照,自動尋找並載入 套件依附元件
  • 套件樹狀結構封存
    • 如要建構單一檔案,從指定頂層套件,該套件的 套件和所有依附元件

子套件表示法

套件會根據應用程式的套件名稱,宣告子套件的參照 子套件,對應至 所定義套件的套件雜湊 納入相同套件和套件組合中。(例如,假設家長為 透過「宇宙」解析套件集,則必須一併解析其子套件 「宇宙」套件組)。RFC 的其餘部分則說明瞭一種觀念 以檔案形式呈現這些宣告meta/subpackages 符合 meta/contents 目前使用的格式 (=)。

如果存在,這類檔案「必須」至少包含子套件的名稱及其名稱 套件雜湊 (所參照 meta.far 的「內容位址」 子套件)。

子套件名稱在單一 meta/subpackages 檔案中不得重複,但 可以重複。因此,一個套件 控制其子套件的命名,而多個套件可能包含 相同子套件的本地名稱。

子套件參照視為「私人資料」參照的套件 舉例來說,父項套件 A 可能包含兩個子套件:套件 BC (透過各自的套件雜湊參照)。「B」套件也可能也會 加入同一個套件雜湊 C 的子套件參照。無論 頂層父項 A 及其子套件 B 能瞭解 依附元件(也就是說,父項套件只能解析其子套件, 向下移動一個層父項無法 -- 直接 - 將套件網址解析為子套件 子套件事實上,這個 RFC 並未定義代表 子套件的子套件)。

注意: 個別的子套件也可獨立發布並以 頂層套件(舉例來說,正式版元件可以發布為 透過 fuchsia-pkg 網址識別的頂層元件 也可在一或多個密封測試中以子套件的形式提供)。 解析頂層套件時,由 Fuchsia 套件 URI 提供,預設行為 是要擷取該套件最新發布的版本子檔案包 另一方面,請一律使用「套件雜湊」來參照特定版本。

建立含有子套件的套件

在套件中新增子套件的做法與新增一般套件的模式相似 檔案,但有一些特殊事項

各種 Fuchsia SDK 建構系統 (現行、GN 和 Bazel) 通常都支援 建立「套件」可能會依賴其他目標 。在這些建構系統中,新增 套件會通知建構系統一併產生相依套件,但 目前不會在產生的套件中為這個依附元件編碼例如: 下列 GN 代碼只會導致套件「B」以便產生 「A」套件。

# GN format
fuchsia_package("A") {
  deps = [
    ":B",
    other_deps,
    ...
  ]
}

fuchsia_package("B") {
  ...
}

深入調查 fuchsia.git 中現有的跨套件依附元件 顯然,在大多數情況下,目標套件依附另一個套件。 目標套件中的元件預期載入相依套件。於 在這些情況下,依附元件套件可能會與目標組合一起使用, 子套件。但現有的 GN 規則並不會強制執行這項解讀作業 而無法推斷。

因此,此 RFC 建議使用明確變數 ---subpackages---be 並宣告子套件目標「subpackages」名單中的每個目標都必須 產生的 fuchsia_packagemeta/subpackages 中的對應項目 檔案。

這份清單中的目標也會推論建構依附元件,因此目標 subpackages 不需要顯示在 deps 中。如何透過 對含有子套件的套件所宣告的套件依附元件 將所有 (或已選取) 的套件目標從「deps」移至「subpackages」。值得一提的是 fuchsia_package 的變更可能顯示為:

# GN format
fuchsia_package("A") {
  subpackages = [ ":B" ]

  deps = [
    other_deps,
    ...
  ]
}

fuchsia_package("B") {
  ...
}

建構系統「必須」將子套件名稱預設為包含的目標 但可以透過常見的慣用語覆寫這個名稱。

如要使用現有工具透過子套件建立套件,請建構 「必須」更新 Fuchsia 樹狀結構內建構系統中的規則和指令碼。 應在 Fuchsia GN SDK 和下游建構環境中更新。 (就知道的程度而言,受影響的建構環境和必要變更) 相關說明請參閱「導入」一節)。

解析子套件

子套件解析度會解析相對於以下項目的已命名子套件的相對參照: 已知套件中的狀態

fuchsia.pkg.PackageResolver 通訊協定的 Resolve 方法會是 並傳回 ResolutionContextResolve 只會解析絕對值 套件網址。將新增額外的方法 ResolveWithContext 額外的 context 引數 (ResolutionContext),並傳回新的 ResolutionContext。「ResolveWithContext」將解析 絕對套件網址 (忽略 context) 或相對套件 網址。這些變更如以下概念 FIDL 程式碼片段表示:

   library fuchsia.pkg;

   ...

   const MAX_RESOLUTION_CONTEXT_LENGTH = <TBD>;
   type ResolutionContext = bytes:MAX_RESOLUTION_CONTEXT_LENGTH;

   protocol PackageResolver {

     /// Resolves an absolute component URL.
     /// ...
     Resolve(resource struct {
         package_url string;
         dir server_end:fuchsia.io.Directory;
     }) -> (struct {
         resolved_context ResolutionContext;
     }) error ResolveError;

     /// Resolves a component URL, which may be absolute or relative. If
     /// relative, the component will be resolved relative to the supplied
     /// `context`.
     ResolveWithContext(resource struct {
         package_url string;
         context ResolutionContext;
         dir server_end:fuchsia.io.Directory;
     }) -> (struct {
         resolved_context ResolutionContext;
     }) error ResolveError;

     ...
   }

注意:要選擇用於背景資訊的位元組陣列是多個結果 並嚴加看待 FIDL 的限制。適用對象 如需額外背景資訊,請參閱「替代方案」區段: 使用特定情境的 Resolver替代方法:解析度結構定義值的 FIDL 類型表示法

針對 package_url 中宣告子套件 (「父項」套件) 的套件: 傳回的 resolved_context 必須做為 context 輸入參數傳遞 解決子套件問題時,對 ResolveWithContext 的後續呼叫。(如果 呼叫端未解析已解析套件的子套件,呼叫端「可能」 請忽略傳回的 resolved_context)。

子套件實作項目「不得」降低穩定性和存續能力 現有服務和元件的概念也就是說,子檔案包 將非重要 (可重新啟動) 的元件標示為重大問題 無狀態通訊協定 (例如 fuchsia.pkg.Resolve(),以及建議的 ResolveWithContext,將取代部分呼叫 Resolve) 必須保持 無狀態

context 值的實作方式可能會受到這項限制影響。 ResolveWithContext 必須接受 Resolve 傳回的所有 context,或 ResolveWithContext,只要父項套件 有些人會將 Cloud Storage 視為檔案系統 但實際上不是(從概念上來說,父項套件的 套件雜湊值就足以因應 以無狀態解析同一個 Merkle 雜湊索引套件中的子套件 store.)

注意:判斷父項是否仍在「使用中」令人擔心 需要在實作期間處理的垃圾收集 子套件的組成。

針對絕對 package_urlResolveWithContextcontext 引數為 已忽略。

注意:這個 RFC 會將子套件的解析限制為宣告的子套件 父項 (向下),相對路徑「不得」包含斜線 (/)。

從子套件載入元件

元件解析器負責剖析元件網址並予以轉換 解析為經過解析的套件網址,然後載入元件資訊清單 解決套件。系統會使用載入的資訊清單和套件內容 並建立新的元件,包括透過 相對路徑

fuchsia.component.resolution.Resolver 通訊協定的 Resolve 方法 只會解析絕對元件網址另一種方法是 將會新增 ResolveWithContext,並使用額外的 context 引數 ( fuchsia.component.resolution.Context)。「ResolveWithContext」將解析 絕對元件網址 (忽略 context) 或相對 元件網址這些變更以下列概念 FIDL 表示。 程式碼片段:

   library fuchsia.component.resolution;

   ...

   // Note the context length, in bytes, must be at least the size of
   // fuchsia.pkg.MAX_RESOLUTION_CONTEXT_LENGTH, plus the size required to
   // accommodate additional component context information, if any.

   /// The maximum number of bytes for a `Context`.
   const MAX_RESOLUTION_CONTEXT_LENGTH uint32 = 8192;

   /// A byte array that persists a value used by the target `Resolver` to locate
   /// and resolve a component by relative URL (for example, by a subpackage
   /// name).
   alias Context = bytes:MAX_RESOLUTION_CONTEXT_LENGTH;

   protocol Resolver {

     /// Resolves a component with the given absolute URL.
     /// ...
     Resolve(struct {
         component_url string;
     }) -> (resource struct {
         component Component;
     }) error ResolverError;

     /// Resolves a component with the absolute or relative URL. If relative, the
     /// component will be resolved relative to the supplied `context`.
     ///
     /// `component_url` is the unescaped URL of the component to resolve, the
     /// format of which can be either:
     ///
     ///   * a fully-qualified absolute component URL
     ///   * a subpackaged-component reference, prefixed by a URI relative
     ///     path to its containing subpackage (for example,
     ///     `child_package#meta/some_component.cm`); or
     ///   * a URI fragment to a component in the current package (for
     ///     example,`#meta/other_component.cm`)
     ///
     /// `context` is the `resolution_context` of a previously-resolved
     /// `Component`, providing the context for resoving a relative URL.
     ResolveWithContext(struct {
         component_url string;
         context Context;
     }) -> (resource struct {
         component Component;
     }) error ResolverError;
   }

系統會修改傳回的 Component 類型,加入 用於解析其他相關元件的 resolution_context Component

   type Component = resource table {

       ...

       /// The context used to resolve `component_url`s relative to this
       /// component.
       5: resolution_context Context;
   };

舉例來說,解析名為 parent 的元件後, 後續呼叫 ResolveWithContext(subpackaged_url, parent.resolution_context)

針對絕對 component_urlResolveWithContextcontext 引數為 已忽略。

針對相對 component_url

  • 用戶端必須使用 ResolveWithContext。使用相對呼叫 Resolve 元件網址會傳回錯誤代碼 ResolveError::INVALID_ARGS

針對相對的子封裝元件網址:

  • component_url 的開頭為相對路徑 (子套件名稱,後接 是由特定元件的 # 片段所產生,例如 child_package#meta/some_component.cm)。
  • 如果套件解析器傳回 PACKAGE_NOT_FOUND (或一些同等項目) 套件商店相依錯誤),元件解析器「必須」傳回 ResolveError:PACKAGE_NOT_FOUND

適用於相對資源元件網址 (來自與其他套件的相同套件網址) 元件):

  • component_url 是 URI 片段 (例如 #meta/other_component.cm,如 RFC-0104:相對元件 網址
  • 片段必須參照另一個套件中的元件 先前解析的元件 (「對等」元件)。
  • context 值「必須」參照相同的套件版本 (相同套件) 雜湊)。

注意:使用 context 解析相對資源元件網址 (依 URI) 片段) 變更相對解析器的目前行為。目前市面上 解析器會從其父項元件建構絕對套件網址,以及 附加相對片段部分。這個行為不保證 父項元件和子項元件是從同一個套件擷取 版本。子套件不一定能向 來自父項或對等元件的套件網址。另一方面,透過 至特定套件雜湊值,該物件會用來解析 套件也許是所需的行為此時,使用情境 都有所進步

代表使用相對 URI (路徑或片段) 解析元件網址時 元件管理員 (即「父項元件」) 的元件,元件管理員 能夠將解析度委派給用來解析問題的相同 Resolver 父項元件。

背景值應該視為 Component Resolver,且對用戶端設為不透明。5 月 Resolver 正向 resolved_context 值 (從 PackageResolver::Resolve...()) 做為元件解析度 context 值。 (API 不會阻止 Resolver 傳回不同的或 來擴增背景值,但不一定要有)。

解析含有子套件的元件的程序示意圖 子項 (假設啟動後環境) 如下所示:

  1. 如要從頂層套件 P 載入元件 A

    a. 元件管理服務會取得應用程式的註冊 Resolver 能力 fuchsia-pkg 配置,然後呼叫 Resolver::Resolve("fuchsia-pkg://fuchsia.com/package-p#meta/component-a.cm") ,直接在 Google Cloud 控制台實際操作。

    b. Resolver 會擷取套件網址並呼叫 PackageResolver::Resolve("fuchsia-pkg://fuchsia.com/package-p", ...), 傳回用於載入元件的 fuchsia.io.Directoryresolved_context

    c. Resolver::Resolve() 建構並傳回已解析的 Component,搭配 resolution_context,元件管理服務快取 這個元件的狀態

  2. 如要從子套件 child-package 載入子元件 B (相對 至上方的 A 元件:

    a. 元件管理服務會取得用於解析的 Resolver 能力 component-a和來電 Resolver::ResolveWithContext("child-package#meta/component-b.cm", component_a.resolution_context)

    b. Resolver 會擷取相對套件路徑 ( 這個子套件名稱,然後從元件網址中擷取 從元件 context 輸入參數中的 package_context,然後呼叫 PackageResolver::ResolveWithContext("child-package", package_context), 傳回用來載入元件的 fuchsia.io.Directory。 以及子套件本身的 resolved_context

    c. Resolver::ResolveWithContext() 建構並傳回 使用新元件的 resolution_context 解析 Component 元件管理服務會以該元件的狀態快取

日後的工作

  • 整合 subpackagescontents 檔案:如果檔案 Persistent FIDL 套件的建議 RFC 內容為 子套件檔案必須更新,以符合新的 格式取代 contents;或者也可使用展開後, 欄位,用於區分內容項目和子套件項目。
  • 使用摘要統計資料為 subpackages 檔案項目加上註解 - 「永久 FIDL 套件內容」RFC 會提供 以及每個子套件與套件雜湊對應之間的額外資料。大約 有助於納入摘要統計資料,例如內容大小 (包括 每個子套件及其巢狀依附元件的匯總大小)。可以是 例如:在套件擷取作業期間回報進度 載入含有大量依附元件的套件時
  • 改善執行階段依附元件解析功能 - 這也是 會考量 (適用於日後的 RFC) 支援使用 用來要求頂層的絕對路徑 (開頭以斜線「/」開頭) 來自「相同套件伺服器」的套件放送「目前」套件 (或 目前元件中)。(您可以透過相同方式得知目前的套件伺服器 解析目前套件中的子套件網址。 ) 中。)
  • 用於解析及載入資產套件內容的通用 FIDL 服務 - 目前 Fuchsia 軟體從套件載入內容的唯一方式是 在這個套件中加入元件自訂元件會是 負責路由目錄或提供 FIDL 通訊協定來進行佈建 從套件新增素材資源考慮在未來的提案中 更易於存取的 FIDL API,在該 API 中載入子套件和/或資產 套件。例如發布視覺素材資源 可選取的使用者介面「主題」做為資源套件使用 實作元件中介的額外步驟。
  • 延遲載入子套件 - 這個 RFC 提議提出一個套件和 系統將在頂層套件 就會引發這個現象。未來提議的擴充功能,可讓指定的 宣告「可延遲載入」的子套件這樣可以避免 從遠端伺服器將套件匯入至有限儲存空間的費用 裝置。(詳情請參閱 加速載入套件)。
  • 子封裝元件的熱重載:這個 RFC 提出嚴格的 跨套件版本管理實作:系統會從 內容雜湊,包括其子套件雜湊。因此,如果 子套件變更 (指出子套件套件雜湊值的異動) 父項套件也已變更建議您重新載入 子套件,而且不必重新載入父項 (例如「hot-reload」 反之亦然)。只要允許這類行為 降低子套件的某些預期效益,包括可靠性和 安全性。此外,在元件管理服務解決方式的過程中也存在落差 並重新載入新版本的元件 (請參閱 https://fxbug.dev/42145182)。如果 已解決這些已知問題,子套件依附元件的限制可能會 修訂 (在日後提案中) 允許上層套件宣告 依據較寬鬆合約 (行為、API 和/或 ABI 保證) 決定依附元件 例如)。

實作

Fuchsia 樹狀結構內結構建構系統 (GN 規則和指令碼)

建立規則、指令碼和檔案格式 (包括 產生 Fuchsia 套件) 須更新,才能轉寄「subpackages」清單 開發及/或封存套件的每個階段,最終產生 新的 meta/subpackages 檔案與套件 contents 檔案一起出現。

對於 subpackages 中的每個套件目標,meta/subpackages 檔案「必須」對應一個 宣告的子套件名稱 (預設為子套件名稱) 子套件目標的 blob 雜湊 (也就是 子套件的 meta.far)。

一些「可能需要」變更格式 (例如 或同一階段的補充檔案 (例如 contents 會與 subpackages 配對,包括:

  • 「build manifest」套件(或 archive_manifest),後者通常會結束 (在 .manifest 擴充功能中)
  • package_manifest.json

Fuchsia 樹狀結構外建構環境 (GN、Bazel 和支援指令碼)

建立規則和腳本「必須」以與 Fuchsia 類似的方式更新 樹狀結構內建構規則和指令碼,以啟用現成的子套件 與存放區受影響的存放區包含 Chromium 和 Flutter/引擎。(注意: 導入波動的/引擎目前導入經過修改的 GN SDK 建構規則副本 因此非相同的情況下 GN SDK 存放區和流動/引擎)。

  • package.gni--manifest-path 叫用 prepare_package_inputs.py 產生 ${package_name}.manifest (稱為 archive_manifest ,或「建構資訊清單」pm CLI 說明文件中)
  • pm_tool.gni 透過 -m ${archive_manifest}pm build 產生 package_manifest.json-output-package-manifest

套件管理員套件指令列介面 (CLI)

變更 ffx package 即可修改套件管理員指令。

注意:pm 指令即將淘汰,並改用 ffx package。變更內容 系統只會在工作流程需要時才會發布 pm,且無法更新為 使用 ffx package 取代指令

  • ffx package build (原為pm build)
    • 這項指令需要變更,才能接受其他引數和 或是經過修改的輸入和輸出檔案格式 額外的子套件宣告。
  • ffx package export (原為pm archive)
    • 這個指令會讀取 contents 檔案,並產生 .far 檔案 其中包含所有參照的 blob。
    • 針對含有 subpackages 的套件,系統會擴充 export 行為 檔案,以遞迴方式將這些子套件組合到產生的封存檔中 (請參閱將套件依附元件 發行
  • 您可能也需要調整其他 ffx package 指令,以配合 subpackages (例如 downloadimport)。對下列項目的影響: 的指令。這些異動 並受到其他預定變更的影響或影響。 RFC-0124:去中心化產品整合:構件說明和傳播

組合套件依附元件以進行發行

子套件的主要用途之一是 確保套件及其所有直接和間接依附元件 全部視為套裝組合。軟體包格式比開發 遞迴週遊子套件依附元件的程序。

ffx package 工具是邏輯工具,可用來實作識別及 找出每個子套件的內容 (展開的套件目錄或 .far 封存)。

比起部署自訂指令碼來保持隱密性 並按照此 RFC 建議擴充套件 利用這類工具支援以子套件方式發布套件,藉此支援 子套件依附元件。舉例來說,ffx package 會擴充為組合 具有依附元件的套件 轉換為單一檔案封存檔

我們建議將密封套件封存的格式視為單一檔案,如下所示: 所有提供套件的展開內容,進而建立索引 所有套件中所有 blob 的扁平集合。

套件解析器

必須更新 fuchsia.pkg.PackageResolver 通訊協定的實作方式 實作上述設計章節中所述的行為。

正在載入 Eager 套件

套件解析器「必須」在內部以遞迴方式解析所有子套件,直到 系統擷取完所有子套件後,才會針對 根目錄套件此方法旨在簡化 所以我們保證所有必要的子套件 在元件啟動前已解決

強制執行 Eager 套件解決方案或許也支援 核准的 RFC-0145: Eager 套件更新, 值得注意的是,套件及其子套件樹狀結構可用來實作 Eager 套件更新 RFC 的「套件群組」必要條件。

元件解析器

必須導入 fuchsia.component.resolution.Resolver 通訊協定 更新,實作上述設計章節中說明的行為。

RealmBuilder

必須更新 RealmBuilder 才能加入宣告子套件的功能,以及 回應使用元件中相對路徑的元件解析要求 網址。使用 RealmBuilder 的 HermBuilder 測試目前沒有存取 套件解析器。支援透過 子套件聲明,必須導入並同時提供使用 和系統測試

成效

穿越子套件會增加識別所有 blob 的延遲時間 多個間接層級下載,但不太可能 在實務上扮演著重要角色例如,比較載入 N 的單一套件 用於載入含有子套件且有 N 個不重複 blob 的套件:

  • 有子女
    • N 個 blob

VS

  • 有子女
    • N_0 個 blob
    • Child1
      • N_1 個 blob
      • Child2
      • N_2 個 blob
      • ...

在第一個案例中,所有 N blob 都是在前已知的,並且可平行載入。 在第二種情況中,套件解析器必須依序遵循 父項和子項,來累積完整的 N blob 進行載入。這項週遊 會產生額外延遲時間,此做法受到樹狀結構的深度限制。如果延遲時間 遞迴 blob 載入會造成問題, 來改善延遲情況例如,您可以掃遍 與載入 blob 或完整的子套件內容位址組合平行處理 可以包含於建構套件時

回溯相容性

相對資源元件網址的解析度行為

解析現有套件網址和元件網址的行為如下: ,但有一個例外狀況:相對資源元件網址 (以 URI 片段 (例如 #meta/child.cm) 需要元件 context (也就是 提議的實作可以保證,但行為稍有不同。 目前的相對解析器會將片段串連至父項 的套件網址,然後重新解析套件與元件。不過 解析器可能正在載入新版本的套件。這被認為是 原始導入作業的潛在風險範圍context會 保證會從下列位置的相同套件解析相對元件 「父項元件」都已解決。

解讀已解析元件的 fuchsia.component.resolution.Package

解析元件後, fuchsia.component.resolution.Component 類型包含類型的 package 欄位 fuchsia.component.resolution.Package,其中包含 包含所傳回 Component 的套件的 package_url

   type Package = resource table {
       /// The URL of the package itself.
       1: url string;

       /// The package's content directory.
       2: directory client_end:fuchsia.io.Directory;
   };

由於子套件一律是相對的,因此現有的 package_url 使用方式 可能會受到影響此 RFC 中所述的子套件解析程序並未 使用儲存在 Package 類型中的任何資訊,因此任何變更為 Package 的資訊,或者 系統解讀該類型的方式,不會對子套件造成實質影響 RFC 設計

可在導入時考慮的替代方案包括:

  1. 儲存僅參照套件伺服器與套件的 url 雜湊 (例如 fuchsia-pkg://fuchsia.com?hash=123456789),也就是 足以重新解析子套件的內容,但無法 會保留與父項元件或其子套件名稱有關的任何資訊。
  2. 將子套件路徑儲存在 url 中,並新增選用項目 解析度內容欄位 (元件套件的結構定義 從) 解析為 Package

FIDL 方法變更

fuchsia.pkg.PackageResolverfuchsia.component.resolution.ResolverResolve() 方法會同時 變更以傳回新的已解析內容,以及呼叫的其他方法 將新增 ResolveWithContext(),以支援 context 輸入參數。 您可能不會需要進行即轉換。

套件表示法變更

在 Fuchsia 中新增子套件的做法,在沒有標記的情況下 代表子套件。現有的套件網址和元件網址 可能會受到影響開發人員可以選擇替換完整的合格 元件網址 (使用 fuchsia-pkg://fuchsia.com/top-level-package#...,適用於 執行個體) 含有其其中一個子套件的參照 (使用 child-package#...,將 child-package 對應至 top-level-package)。

工具異動

舊版 Fuchsia、套件伺服器和一些主機端工具 (例如 pm) 和 ffx package) 不支援含有子套件發布的套件,或 使用套件的相對路徑Fuchsia 系統和主機端工具 必須更新並重新編譯

套件名稱語法

子套件名稱的範圍限定在父項套件,且實際上是別名 。也就是說 的子套件名稱不需要與套件名稱的語法完全相同。

然而,機構可能會以相同的名稱來指稱套件。 以及做為子套件

由於子套件是階層式的,因此能夠自然而然地認為巢狀子套件 可命名,也可使用斜線做為分隔符號。例如: fuchsia-pkg://fuchsia.com/parent/child/grandchild#gc-component.cm,或 child/grandchild#gc-component.cm。請注意,此 RFC 既不是製裁也不是 但不得使用斜線分隔符 潛在的陷阱

套件名稱目前可包含一個斜線。之後的內容 視為「變體」 (例如 /0),這在 Fuchsia 中是常見的做法。

值得注意的是,/0 已遭淘汰。如果不再使用,可能會發生這種情況 就能釋放 / 對子套件的意義 (但這不是 且日後必須因應未來的 RFC)。

如果套件階層有競爭用途,可採用替代做法 分隔符號 (例如 :) 可用於子套件巢狀結構,或 子套件可以使用 /,而替代分隔符號 另一種意義

這個 RFC 建議從允許的子套件名稱保留至少 /: 語法。

安全性考量

可稽核性與可執行性

提議的設計也採納了至今以來的評論 資安主管需要將資安態勢的變動降到最低需求 並簡化審查作業,這些變更可能影響可稽核性及 執行力

舉例來說,父項及其所有子套件 (遞迴) 都必須從同一來源 都屬於同一套件組合 (例如來自「基數」或所有來源為「宇宙」)。使用相同的套件 設定後,子套件階層中的所有套件都會有相同規則 執行政策

根據套件或元件網址建立系統許可清單

目前在特殊權限許可清單中發現的套件或元件,因為 可能屬於子套件 但要保有這些權限所需的權限。外部 測試,父項套件「不得」含有 要求的權限比上層帳戶更多。在密封測試中執行的元件 此為例外狀況,但如果加入許可清單的套件或元件為 要在密封測試中作為子套件使用,特殊權限功能應該 如果可以的話,應使用模擬或同等的替換裝置。

如果此限製造成其他系統改進而無法改善, 安全團隊應諮詢替代方案。

控管權限套件解析作業的存取權

目前,以扁平的套件命名空間來說,PackageResolver 用戶端 讀取blobfs的所有內容;因此能夠向 Google 發出 套件伺服器和讀取其 BLOB 都是特殊權限作業。

子套件只會提供指定的 blobfs 套件子集 (目前來說是一層深度),而是宣告另一個依附關係的套件 套件不具備讀取該套件內容的權限。墨西哥聯邦納稅義務人編號 (RFC) 建議對無特殊權限用戶端可執行的操作維持相同限制 要求從子套件取得功能或素材資源時

從特定套件執行的元件可能無法查看 子套件,但可能會檢視 meta/subpackages 檔案並解析其 或是具備 PackageResolver 的能力

與包括相依的 並整合到單一套件中在該解決方案下 這些元件可任意檢視彼此內容。由於元件 只會看到執行程式的套件,而不會顯示 子套件時,這種設計會隱藏這些實作詳細資料。

導入風險:線路封鎖主管

如果我們實作深度優先的套件解析服務,巢狀子套件 DAG 就能 其他套件的區塊解析度這可能會導致解析器發生問題 解決父項資源問題時 進行遞迴修正

由於 RFC 狀態表示只會實作 Eager 解析, 實作者可以確保不需要 請先完全解決,再發布解析器資源來解析子套件。

隱私權注意事項

預估隱私權防護機制不會受到任何影響。

測試

我們會新增單元測試,驗證其他功能。現有執行個體 測試有助於找出非預期的迴歸問題

主機端封裝測試會驗證 ffx package 的行為 (和/或 pm (視需要) 及相關工具 (處理子套件時)。

您將編寫密封整合測試,驗證各自的元件解析度 子套件。

說明文件

以下已知文件需要更新:

  • 現有說明文件:說明 Fuchsia 套件網址和元件網址 軟體推送說明文件 以及元件架構概念文件目前顯示的示例 CML 範例包含 fuchsia-pkg:// 網址參照,可使用 使用子套件的範例)。
  • 應更新相對元件參考資料的說明文件 兩者之間的異同

缺點、替代方案和未知

請參閱「設計」一節中的「未來工作」子章節, 說明日後推出的強化功能、替代方法和其他 先將考慮到的功能列入考量,然後再縮小至目前的版本 RFC。

此外,下列子節將說明

替代做法:在子元件網址中插入版本雜湊

我們並未在軟體推送堆疊中加入子套件 新增工具,讓元件能夠宣告版本化依附元件 將套件雜湊限定詞新增至子項元件網址。舉例來說 在 Pod 的 children:清單中 parent.cm 將顯示為 url: "fuchsia-pkg://fuchsia.com/some_package?hash=1234#meta/a_component.cm"

只要工具和基礎架構可以保證 some_package 版本 在套件儲存庫中,此參照可使用現有的解析器。新的 檔案 (例如此 RFC 中描述的概念 subpackages 檔案) 以及 SWD 因此並不需要進行任何變更

這個替代項目因需要工具和建構基礎架構而遭到拒絕 工作目的是增加複雜度,尤其是在工具和建構 工作流程。例如:

  • 這個替代方案假設開發人員 CML 並未嵌入套件雜湊。 或在執行階段解析元件網址的程式碼中 新增至 collection。您需要新增一些機制才能修改 產生元件資訊清單和靜態參照的編譯表示法 來源,在網址內插入 ?hash=<blobid> 限定詞,在 開發人員會指明 (某部分方式) 希望使用元件網址 且會在建構期間固定至特定雜湊。
  • 元件資訊清單中的密封依附元件支援執行階段解析功能, 需要獨立的機制才能支援 依附元件剖析修改後的資訊清單和程式碼可能不切實際。 因此會以任何一種機制 判斷應從何處著手 您也會需要產生額外的中繼資料 依附關係圖然後修改工具,以讀取該中繼資料 例如封存含有所有依附元件的套件 將套件及其所有雜湊固定依附元件發布至套件 也就是經過處理且會導入模型的資料 接著再透過特徵儲存庫與他人分享

替代做法:使用情境專屬的解析器

解析 resolution_context 時,而不是傳遞並傳回 resolution_context 元件或套件,您可以修改 Resolve 方法,加入 context_resolver 要求控制代碼 (server_end) 做為新的輸入參數。

從概念上來說,PackageResolver 和 Resolver 可以 採用以下 FIDL 通訊協定模式:

protocol Resolver {
  Resolve(struct {
      component_url string;
      context_resolver server_end:Resolver;
  }) -> (resource struct {
      component Component;
  }) error ResolverError;

  ...
}

在此替代方案,context_resolver必須 後續呼叫,為傳回的 PackageComponent (例如解析 CML 宣告的 children)。

這個方法遭拒的主因在於這麼做會增加 與解析器保持即時連線如果發生問題 解析伺服器以重新啟動,則需要或所有管道都需具備 重建作業,增加不必要的複雜度。

內容參數應為對應所需的資訊進行編碼 將特定子套件名稱提供給父項套件的固定套件雜湊值 meta/subpackages 個檔案,允許「PackageResolver」和「Resolver」 的實作,以便於解析器重新啟動時繼續保持運作 (如有需要)。

替代方法:解析度結構定義值的 FIDL 類型表示法

我們考慮採用數種方式來表示解析度的背景、 最後決定針對 PackageResolverContextResolver。這種做法的優點之一 編碼值常用的類型,且未將任意內容編碼。 (包括空值位元組)。

FIDL 團隊建議使用位元組陣列,因為並沒有其他結構 明確 FIDL 類型 (可以視為「Cookie」 模式。

我們最終整理了這個類型的限制,如下所示:

  • 這些類型在未導入 API 依附元件的情況下應可管理 fuchsia.pkg 和 fuchsia.component.Resolution 的高度,
  • 背景值不需在元件管理員重新啟動後繼續保留,但 導入子套件時,不需要將現有內容 「非重要」(可重新啟動) 的套件提供元件 「重大」(這項限制似乎不符合服務使用的控制代碼)。 請注意,如果元件管理員重新啟動,所有元件都會 (目前) 已重新解決並重新啟動,包含新的結構定義值。背景資訊值沒有 就需要在元件管理員重新啟動時持續運作、單獨重新啟動或 重新開機。
  • 結構定義可能很小 (關於套件伺服器名稱的大小) 以及套件雜湊)。這意味著 VMO 的控制代碼、每個子套件 可能所費不貲

替代方法:元件管理服務使用 resolution_context 取得解析器

解析相對子封裝元件網址時,我們會考慮加入 URI 配置 (例如 fuchsia-pkg),做為 Component::resolution_context,讓元件管理員取得 Resolver。交易遭拒,原因如下: 理論上,理論上允許 Resolver 傳回含有 解析相對子封裝元件的不同配置, 基礎架構風險元件管理員則會追蹤 用於解析元件的 Resolver。元件管理服務一律會使用 元件的 Resolver,該元件會透過相對網址要求另一個元件。

替代做法:相對元件,而非相對套件

在 Fuchsia 中,套件是軟體發布單位,也是 軟體安裝 (可執行的程式碼和其他檔案)。雖然富赫西亞 元件提供了一些較常見的用途 可能存在於不包含元件的套件之間 元件對元件依附元件 (例如 Fuchsia 殼層套件 而是依附於另一個沒有專屬元件的資產套件)。 此外,想獨立發布預先建構的應用程式並不方便 這些元件

替代做法:使用特殊 fuchsia-subpkg:// 配置參照子套件

這個 RFC 建議解讀 URI 相對路徑 (以路徑為開頭的 URI) 並省略配置和權威前置字元) 做為參照 放入子套件中的資源目前的提案也限制了子套裝方案參照 立即新增「子項」才會套件,因此路徑「不可」包含斜線。(使用 子套件參照中的斜線將保留供日後使用)。

替代的另一個考量是需要特殊的配置前置字元 (例如 fuchsia-subpkg://),以確保指定的 字串。

此外,使用配置前置字串 fuchsia-subpkg 似乎暗示依賴 是會處理 fuchsia-pkg 配置的解析器,可能會令人困惑。

URI 標準建議只從相對路徑開始。 需使用特殊的配置前置字串,可能表示有特定依賴 配置處理常式,限制一般性。無結構定義的相對路徑相當普遍 且易於理解 (例如,在 HTML 中 會將 <a href="sub-path/page"> 隱含為相對位置 不必特殊配置)。

既有藝術品和參考資料

標準

接受的 Fuchsia RFC

可能相關的 Fuchsia RFC 草案