RFC-0208:使用 SDK 發布套件

RFC-0208:使用 SDK 發布套件
狀態已接受
領域
  • 軟體推送
  • 測試
說明

提議我們如何在 SDK 中發布部分樹狀結構內套件,用於樹狀結構外外包。

問題
蓋爾特變化
作者
審查人員
提交日期 (年-月-日)2023-02-15
審查日期 (年-月-日)2023-02-10

摘要

此 RFC 描述了 Google 的建構和散佈策略 Fuchsia 平台的套裝行程 存放區做為附加條款 導入 SDK。這些套件預計在下游使用 分包機制

這個策略包含全新的 .api 檔案格式 它本身就是適用於 Fuchsia 的新 SDK API 介面格式本身 和使用這種格式的簽收檔案必須遵守 API 委員會 現場業務代表受過訓練 會提交 AI 客戶商機以供審查

提振精神

導入子檔案包來因應她的語氣 巢狀結構套件依附元件這項功能的主要用途是 以便明確加入特定套件 樹 (OOT)。其他替代方案 (包括對基本套件的參照) 已遭淘汰,因為這類方案容易發生錯誤。例如: 如果從套件中移除套件,依附元件鏈結會損毀 基本映像檔

這個 RFC 說明將策略套用至一組套件 將透過 Fuchsia 平台存放區發布 這些套件將以子套件的形式包含在下游 與存放區

請注意,雖然此 RFC 側重於這些套件 做為發布測試的通用機制 透過 SDK 安裝 套件產品擁有者可能建議將 Fuchsia 團隊編製 所套用的元件透過 SDK 發布的首批套件可能會用於測試,因為我們可以以測試時的取巧方式,執行正式版無法接受的測試。除了排定工作時程外,我們的目的是全面支援 適用於測試版和實際工作環境的套件。

相關人員

協助人員:

hjfreyer@google.com

審查者:

  • aaronwood@google.com
  • dschuyler@Google.com
  • jsankey@google.com
  • richkadel@google.com

諮詢:

  • etryzelaar@google.com
  • kjharland@google.com
  • shayba@google.com
  • wittrock@google.com

社交功能:

此 RFC 先前與軟體的代表討論過 交付、產品組裝與元件架構。

定義

  • 整合器開發套件 (IDK) 是建構系統無關的程式碼、二進位檔和資料檔案集,用於建構以 Fuchsia 為目標的程式,請參閱這篇文章
  • Fuchsia Software Development Kit (SDK) 是 IDK (API 以及語言整合構件) 整合。 最值得注意的是 Fuchsia SDK, Bazel
  • 「樹狀目錄」是指 網址是 https://fuchsia.googlesource.com/fuchsia/。這個存放區會產生 IDK 做為輸出內容。
  • 樹外 (OOT):指的是位於樹外,且使用 SDK 產生軟體和產品的存放區中的程式碼和建構規則。
  • Fuchsia 套件是指軟體單位 Fuchsia 裝置的分佈情形,也就是 二進位檔/程式庫、元件資訊清單,以及 在 Fuchsia 系統上執行某些程式所需的資料檔案。
  • 分包包裝可讓 Fuchsia 套件 來參照其他 Fuchsia 套件的特定版本 並透過遏制來控制依附元件
  • 此 RFC 中所述的 SDK 套件是 Fuchsia 樹狀結構內的 明確標示為納入 IDK 的套件,以及 提供給 SDK 使用者OOT 存放區 使用發布時發布的名稱來建構這些套件 (例如下載或進行包裝)。請注意,這項設計的擴充功能可能會允許 OOT 存放區發布自己的套件。

設計

下列關鍵字:「必須」、「不得」、「必要」、「應」、「不應」、「應該」、「應該」、 「不應該」、「建議」、「可能」和「選用」基本上就是 解讀方式 IETF RFC 2119

SDK 套件會以新構件形式產生 IDK 參照的資料。IDK 包含一組 所有建構系統都能取得 SDK 可用的構件 所有 Fuchsia SDK 整合都能夠參照 SDK 套件。

樹狀結構內會完成下列階段:

  1. 選取:選擇要分發的套件。
  2. 驗證 - 確保所預期的套件集 發行。
  3. 建構 - 建構所有必要套件的選定套件 架構
  4. 組合 - 產生套件目錄結構 都必須包含 IDK 中的值

SDK 套件可供 OOT 存放區立即使用 透過位於 sdk://packages/ 的 SDK 中的套件目錄結構。

本節的其餘部分將詳細說明各個階段的設計。

發布 SDK 套件

選項

我們不希望自動發布來自 用於使用 OOT 的樹狀結構中,我們必須承諾 將與一組特定的套件一起 平台發布。

我們會建立名為「sdk_fuchsia_package」的新 GN 範本 並提供以下資訊:

  • 要發布的 fuchsia_package 目標。
  • 套件適用的 SDK 類別 (例如「合作夥伴」)。
  • 套件加入 SDK 的 API 級別
  • (選用) 為套件排定發布的 API 級別 並從 SDK 中移除
  • 套件中預期的檔案清單及其「配置」。 說明會在下一節中說明。

這個 GN 範本會使用 sdk_atom 目標來提高成效 針對 SDK 基元驗證 / 工具建置路徑。

新的 GN 目標「sdk_package_bundle」將列出所有「sdk_fuchsia_package」 目前平台 API 級別的指定目標這個目標會使用 sdk_molecule 個目標以強制執行套件層級檢查。

此機制可讓平台擁有者明確承諾 為特定 API 級別提供 OOT 用途的特定套件 (例如允許在部分更新後淘汰及移除套件 時間)。

為了讓實作細節更為完整,我們應該避免使用 GN 中繼資料 而是明確列出 sdk_fuchsia_package目標。

驗證

發布樹狀結構內套件不僅對 name,代表至少對 套件的 contents。本節提供 為何需要這項程序,您宣告 以及套件內容的機械程序 會在建構期間通過驗證

背景

舉例來說,以下將說明簽訂合約的重要性 包含元件 sample.cm 的套件 sample-packagesample-package 是由 OOT 發布,因此 SDK 使用者可能會依賴 fuchsia-pkg://host/sample-package#meta/sample.cm。如果sample.cm 此外,這個 OOT 建構作業會失敗。兩者相差不大 到平台發行的樹狀結構內套件故障模式 圖片變更中更確切地說,如果 sample.cm 需要新的傳入要求 功能 (或任何不相容的資訊清單變更) 如下方所示),先前的使用會無預警失敗。

只是修訂套件名稱,讓我們瞭解到 除此之外,還屬於明確版本管理所有內容的其他狀況 造成過度負擔舉例來說 archivist-for-embedding,該套件的部分內容將會變更 50 個依附元件的任一個變更絕大多數的 這些變更並不會變更 archivist 元件的介面 或行為因此,我們希望只將套件內容的部分內容提交。

合約

理想情況下,我們驗證的套件內容子集應代表套件使用者可能依賴的合約。在 最理想的情況是?

  1. 樹狀結構內明確表示。
  2. 這確實是套件中 OOT 使用者可能依附的。
  3. 可提供 OOT,讓工具僅允許使用 合約內容

定義這份「真實合約」這的技術上很困難 一體適用的定義尤其適合用於 如同元件資訊清單等檔案內容只有部分通知 變更能力轉送或宣告不會造成 相容性問題 (例如公開新能力) 而其他 通常都會 (例如,視新的傳入能力而定)。其他變更的相容性則取決於情境 (例如變更元件的指令列引數)。目前還沒有 專門解釋元件相容性 以採取因應措施

在我們提供明確的相容性指引之前,我們只會在 SDK 中發布少數經過審查的套件,並接受 Fuchsia API 委員會的審查。

本節其餘部分將說明偵測變更的機制 不符合「真實合約」的瑕疵 (太過籠統) 表示法 套件。這會包含一組現有檔案,以及部分檔案的雜湊值。如果系統在這個集合中偵測到任何變更,就會觸發 API 審查。我們會在 2013 年發布 這個表示法與 SDK 中的套件 使用者可以瞭解提案內容,但我們允許 OOT 使用者只會使用含有雜湊值的子集。

也就是說,對 合約 (以免遺漏) 且過度 會嚴謹地從套件中使用 (因此, 可以使用的 Pod因此我們會在樹狀結構內建構時間 驗證 SDK 和 OOT 建構時間提供的產品 確保不會出現錯誤的執行階段錯誤。

請注意,元件使用的 FIDL API 語意有所異動 與這個驗證階段互斥。這可能會 使用 相容性測試加以處理。未來的工作可能會 也包括進一步擴大合約,以涵蓋 FIDL 檔案。

宣告合約

上一節定義的 SDK 套件建構規則。 包含套件中預期檔案的清單,以及 個檔案「描述。」選擇處置可讓您彈性地定義每個檔案如何符合套件的合約。

起始處置狀態的定義如下:

  • exact - 確切的檔案內容為合約內容。變更內容 檔案內容必須依照 請參閱下一節的說明。
  • internal - 檔案不屬於套件合約的一部分。

exact」比對功能會用於內容屬於合約的檔案 而且必須隨著時間維護的相容性 (例如 資訊清單)。

internal 表示檔案並非合約的一部分,但會出現在本機版本中。

您可以視需要加入其他處理方法,做為 墨西哥的 RFC。

驗證合約

我們會使用 .api 黃金檔案的熟悉機制,該機制需要明確的 API 審查才能變更,以驗證 SDK 套件的合約。

例如:

// sample-package.api
// The name of the file matches the name of the package with '.api' added.
// The file format is JSON.
// Note: Comments will not be present in the real .api files.
{
    // Each top-level key is a file path in the resulting package.
    "meta/sample.cm": {
        // Hash is specified for files with "exact" disposition.
        hash: "...",
    },
    "data/some-file.json": {
        // If internal, this file is simply checked for presence
        // at build time.
        internal: true,
    }
}

在建構期間,系統會根據.api 輸入建構規則以及所產生套件的內容 (其中 所有未宣告的檔案輸出內容都是隱含的 internal)。如果 這個檔案的內容與對應的 .api 檔案不符 已簽入 //sdk/packages 底下的原始碼控管 (透過深度 JSON 執行) 等同,建構失敗。與其他 .api 檔案不符的情況類似, 新的 .api 檔案會儲存為建構輸出內容 新的 Golden 指令碼是將 .api 檔案複製到適當的位置 此程序可讓您輕鬆確認預期的變更 並上傳以供審查

我們會記錄評估 SDK 套件 .api 不相符的步驟,並提供可能不安全的變更指南。

產生的套件封存檔中會提供 .api 檔案 以便在後面的步驟中,這個 OOT 工具可能會用它來 則不需依賴套件的內部詳細資料。

這種做法可以確保在發生 具有重大新增的 SDK 套件 並且定義哪些變更才有意義

建築

必須針對所有 (在本文撰寫期間,arm64) 和 x64)。debugrelease 等其他變種版本可能會 但一開始所有套件都會建構 才能發布應用程式。

這項程序的輸出內容為一組檔案內容和一個套件 資訊清單。

這項程序與現有版本的唯一差異 有一個獨立的套件資訊清單 特別適用於下一階段的 SDK 套件

子套件內含二進位檔和共用程式庫的偵錯符號 會產生並上傳至適當的 GCS 值區這個 這與分散式二進位檔和共用程式庫的處理程序相同 直接嵌入 IDK 組合中

郵件分類

建構完成後,將以規劃好的目錄結構發布套件 如下所示:

sdk://
├── blobs
   ├── CONTENT_MERKLE_1
   └── CONTENT_MERKLE_2
└── packages
    ├── arm64
       ├── 10
          ├── debug
             ├── PACKAGE_BAR
                ├── api
                └── package_manifest.json
             └── PACKAGE_FOO
                 ├── api
                 └── package_manifest.json
          └── release
              ├── PACKAGE_BAR
                 ├── api
                 └── package_manifest.json
              └── PACKAGE_FOO
                  ├── api
                  └── package_manifest.json
       └── 11
           ├── debug
              ├── PACKAGE_BAR
                 ├── api
                 └── package_manifest.json
              ├── PACKAGE_BAZ
                 ├── api
                 └── package_manifest.json
              └── PACKAGE_FOO
                  ├── api
                  └── package_manifest.json
           └── release
               ├── PACKAGE_BAR
                  ├── api
                  └── package_manifest.json
               ├── PACKAGE_BAZ
                  ├── api
                  └── package_manifest.json
               └── PACKAGE_FOO
                   ├── api
                   └── package_manifest.json
    ├── x64
       ├── 10
          ├── debug
             ├── PACKAGE_BAR
                ├── api
                └── package_manifest.json
             └── PACKAGE_FOO
                 ├── api
                 └── package_manifest.json
          └── release
              ├── PACKAGE_BAR
                 ├── api
                 └── package_manifest.json
              └── PACKAGE_FOO
                  ├── api
                  └── package_manifest.json
       └── 11
           ├── debug
              ├── PACKAGE_BAR
                 ├── api
                 └── package_manifest.json
              ├── PACKAGE_BAZ
                 ├── api
                 └── package_manifest.json
              └── PACKAGE_FOO
                  ├── api
                  └── package_manifest.json
           └── release
               ├── PACKAGE_BAR
                  ├── api
                  └── package_manifest.json
               ├── PACKAGE_BAZ
                  ├── api
                  └── package_manifest.json
               └── PACKAGE_FOO
                   ├── api
                   └── package_manifest.json
    └── subpackage_manifests
        ├── META_FAR_MERKLE_1
        └── META_FAR_MERKLE_2

每個套件資訊清單都會放入從目標架構和 API 級別建構的目錄路徑:sdk://packages/<ARCH>/<API_LEVEL>/{debug/release}/<PACKAGE_NAME>。這些路徑將做為產品依附的穩定 SDK 合約。 這個目錄包含套件的 package_manifest.json。 以及要驗證的 API 檔案

此外,套件會儲存所有子套件的資訊清單 Merkle 獨立於獨立的頂層目錄中: sdk://packages/subpackage_manifests/<META_FAR_MERKLE>

最後,所有 blob 均會以內容位址名稱的形式儲存 通知時間:sdk://blobs/<CONTENT_MERKLE>。blob 與資訊清單目錄 是套件實作的詳細資料,可能會隨著時間而變更。產品 不應仰賴這些路徑保持穩定

通用的 LICENSES 檔案 這些套件使用的二進位檔和程式庫,系統將封裝這些元件 並隨附於標準 SDK 授權故事中

這種目錄式結構的使用原因有:

  • 套件可以發布至存放區,或做為子套件使用,不需要 只需要剖析中繼檔案
  • 即使 Blob 發生在不同 API 級別中,也不會自動刪除重複資料 能大幅節省空間 (相較於封存個別 不同的是,在包含 相同的 blob (例如共用程式庫與二進位檔)。
  • 目錄結構為支援多個 API 級別的基礎作業 以及提供偵錯和發布版本
  • SDK 中已提供與套件存放區互動的工具 (ffxpm)。
  • 參照套件資訊清單即可啟用分包工作流程 讓您更輕鬆地將內容直接發布到存放區

此方法的一個已知缺點是宣告套件的情況。 以及子套件在此情況下, 系統會複製「package_manifest.json」。套件資訊清單檔案較小 以便將這些資源列為頂層、已命名的檔案 沒有問題的疑慮 最好將子包裝細節藏掉。整體來說 遠超過這個負荷

使用 SDK 套件

使用 SDK 套件 OOT 的做法,就跟使用套件的 package_manifest.json 一樣簡單,這與架構和系統的所需 API 層級相關。請根據分發的 .api 檔案,檢查套件中檔案的用途。

這可讓 OOT 工具和版本適當地警告常見的陷阱,例如:

  • 視要移除的已淘汰套件而定。
  • 視要移除的套件中已淘汰的檔案而定。
  • 視套件中不屬於煽情露骨內容的套件而定 套件合約

要導入這項功能時,SDK 必須負責 不會描述個別建構系統的維護人員 的依據。

包含

OOT 存放區可以在 本地套件 (L),如下所示:

  1. R 的所有 blob 都會儲存在本機 (下載或複製)。
  2. L 的子套件清單含有 meta.far blob 的參照 R.
  3. L 將 L 發布至存放區時,所有 blob 和 遞迴的 R 子套件的 blob) 也會納入。

RFC-0154 中定義的子套件解析度就會 任職於 L 套件

這個步驟可確保在特定產品中重新發布套件。 且可能適用於離線 blob 壓縮 以便進行其他最佳化調整包含已發布套件的遠端 TUF 存放區絕對不應直接用於 Fuchsia 裝置的套件來源 (因為其中的 blob 可能需要進一步處理,才能符合特定產品的要求)。

請注意,這個步驟會使用現有的套件和 blob 發布功能 工具 (例如 ffx package),以針對重複資料進行最佳化 執行「insert-if-absent」作業。

成效

這項設計不會影響裝置端的效能。

這項設計可能會對建構效能產生負面影響 會產生新的封存檔案不過這些影響 只有在建立 SDK 封存時才會發生 (build_sdk_archives=true) )。相較於完整版本花費的時間 建立新的封存檔的負擔應該可忽略不計

人體工學

對於平台擁有者而言,此設計可提供慣用介面,用於定義應在 Fuchsia 平台版本中發布的套件。此外,我們為以下使用者推出了 .api 檔案: 這個使用案例可減少認知到預測 SDK 套件組合的程式碼變更內建自動 進一步確保平台擁有者 控管 SDK 套件代表的合約

回溯相容性

我們承諾提供 OOT 耗用量的發布套件 語意和命名方式一致此 RFC 提出使用 API 版本管理功能支援軟體遷移作業,並提供移除路徑 或是大幅變更即將簽訂的合約

安全性考量

本提案允許以 Fuchsia SDK 編寫的 OOT 軟體 直接納入和參考與發布 SDK 版本雖然軟體本身屬於開放原始碼,但還是必須謹慎 。

這項程序與發布預先建構的二進位檔類似 ,我們會提供包含 我們產生的二進位檔由於封存檔包含 包含 SDK 套件 (IDK) 的輔助封存檔 發行套件也會修訂 輔助封存資料。

隱私權注意事項

這項設計不會改變使用者資料處理作業。

測試

在樹狀結構中,我們會針對從樹狀結構公開的套件提供黃金檔案 (.api) 測試 (請參閱上方的「驗證」)。

我們會在範例存放區中新增 OOT 測試,說明如何使用 SDK 所附的套件。我們會提供樹狀結構內測試 這類 OOT 測試的行為 。這會是 OOT 階段的端對端測試 但從基本的 ffx 指令中 而且不支援 Bazel

內樹狀結構支援 Bazel 時,我們就會進一步 擷取測試產生的 SDK 套件 使用隨附的工具對 SDK 套件進行子套件

說明文件

從 SDK 套件組合中新增、修改和移除套件的程序會記錄在 https://fuchsia.dev 上。這包括如何設定 .api 測試的操作說明。

缺點、替代方案和未知事項

直接在 SDK 中發布套件的替代方案

這個 RFC 先前反覆改進時,提議 透過 CIPD 分開封存及上傳 SDK 套件 縮減 SDK 套件的任何大小變更同樣地,SDK 使用者 不需要套件發布,因此可採用選用的封存檔案 代表他們就不必下載整個應用程式

這個模式雖然很適合日後使用,但不適合 SDK 版本,而且需要使用全新的建構工具來強制執行 SDK 類別 .api 測試,以及可下載和使用這些新穎的工具 SDK 套件 OOT。

為解決 SDK 大小問題,只需使用一小組初始 SDK 套件即可 這裡將會說明啟用測試案例。舉例來說 納入:

  • driver_test_realm
  • 封存主義
  • log-encoding-validator
  • realm_builder_server
  • test_ui_stack

這些針對 x64 的發布子建構的套件,最多可加入約 43 MiB 未壓縮,或使用預設的 gzip 設定壓縮 18 MiB。這看起來 相當合理。

任何額外套裝方案都必須接受 Fuchsia API 委員會審查 內容與大小變更此外,我們日後也會反覆調整 架構可能會指向遠端儲存的 blob,以進一步協助解決 儲存空間容量

使用目錄結構的替代方案

不要使用目錄結構來強制執行架構和 API 頂層檔案可以在 JSON 中以 JSON 格式呈現相同的資訊 格式。這種設計的優點在於檔案的可管理性 變更目錄結構不過,剖析這種檔案 額外的 SDK 工具和這類工具的優點,目前並非如此。

這項工具日後的疊代作業可能會脫離目錄結構 並在遇到此情況時建構並提供必要的工具。

既有藝術品和參考資料

Fuchsia 軟體提交是更新軟體系統的新方法,這類領域有許多先前技術,請參閱以下文件進一步瞭解: