RFC-0100 - 產品中繼資料

RFC-0100:產品中繼資料
狀態已接受
區域
  • 開發人員
說明

產品中繼資料的標準表示法

Gerrit 變更
作者
審查人員
提交日期 (年-月-日)2021-04-30
審查日期 (年-月-日)2021-06-02

摘要

Fuchsia 軟體開發套件 (SDK) 目前提供所謂的裝置設定檔中繼資料 (或在本文件中簡稱為「中繼資料」metadata),其結構定義在 //build/sdk/meta/device_profile.json 中定義。中繼資料的用途是描述可在裝置上安裝的系統映像檔和套件。我們發現該結構定義不完整,需要進行現代化。此外,SDK 以外的工具現在也需要中繼資料,因此中繼資料的重要性也隨之提升。

這份 RFC 會為這項資訊引進新的結構定義,做為平台和工具之間的合約,並提供日後更新該結構定義的程序。

提振精神

目前,中繼資料會隨 SDK 一併提供。目前包含裝置名稱、裝置的文字說明,以及使用者可用來下載圖片和套件資訊的 URI。我們發現這項中繼資料難以保持最新狀態,且不完整,因此無法使用。

工具最終會依賴關於映像檔和套件的非官方慣例,或硬式編碼的假設 (例如下載項目的 URI 結構)。因此,當這些慣例發生變更時,工具就容易發生故障。

我們希望能解決這些問題。我們會為中繼資料指定正式的結構定義,以便工具使用。

當我們發布完整且易於使用的中繼資料時,SDK 使用者就能選擇要將哪個映像檔刷入裝置,或透過模擬器啟動,而無須仰賴 Fuchsia 基礎架構或 SDK 團隊的協助。SDK 開發人員將擁有單一可靠資料來源,用於向使用者顯示產品資訊。工具開發人員將有明確的契約,說明如何使用這類資訊。

更新容易

中繼資料目前是硬式編碼的 SDK 產生作業的一部分,每次發布新映像檔時都需要手動更新。因此,新增、重新命名或移除中繼資料的作業會變得費時且容易出錯。這些資訊經常過時,甚至從未新增。

實際上,SDK 使用者無法依賴 SDK 隨附的中繼資料準確度,因此會將套件和圖片的位置,以及其他與實作相關的脆弱資訊硬式編碼到工具中。舉例來說,除了網址的硬式編碼外,樹狀結構外模擬器啟動程序還會依賴系統映像檔中未記錄說明的 images.json 檔案。

這項提案為我們的中繼資料提供新的結構定義,以供外部使用者依循。這會激勵我們持續更新。

完整性

現有的裝置中繼資料缺少重要詳細資料。舉例來說,裝置閃燈工具需要分割區名稱清單,以及要寫入這些分割區的檔案名稱。這項功能目前尚未正式推出,因此我們並未在發布的內容和執行刷機作業的工具之間簽訂合約。因此,我們很難保證穩定性 / 相容性。

當架構不完整,且更新中繼資料的難度又高時,問題就會更加複雜。舉例來說,假設模擬器工具想要確保啟動的模擬器與使用者要執行的映像檔具有相同的架構,這就是一個假設範例。如果不嘗試啟動映像檔,工具如何得知特定位置的任何映像檔是否與特定架構相容?有了更新的結構定義,我們就能使用單一組中繼資料來描述圖片的架構及其位置。接著,這項工具就能為特定圖片選擇正確的架構。

這項提案將概略說明中繼資料的初始結構定義,並提供更新的後續路徑,確保中繼資料能保持相關性。

設計

為提供實用且最新的中繼資料,我們會:

  • 為中繼資料定義新的結構定義。
  • 定義更新該結構定義的程序。
  • 在建構作業中產生符合該結構定義的中繼資料,並樹狀結構內使用。
  • 將符合該結構定義的中繼資料,作為 SDK 版本的一部分進行發布,並樹狀結構外使用。
  • 提供標準工具和程式庫,以便在閃燈和模擬工作流程中使用中繼資料。

請注意,雖然我們在此定義初始結構,但會透過 API 委員會審查,讓演進作業持續進行,而不需要額外的 RFC。

定義

為了方便說明,本文會使用下列定義:

  • 結構定義是指中繼資料的組織形式。
  • 中繼資料是特定架構的具體例項化。
  • 構件是指任何具體檔案或資料,這些檔案或資料經常在中繼資料中透過 URI 參照。
  • manifest是包含構件清單的中繼資料。
  • 映像檔是指刷新實體裝置或啟動模擬器所需的一系列構件。
  • 套件是 Fuchsia 中軟體發行單位,通常會封裝為 Fuchsia ARchive (FAR) 檔案。
  • 產品是用於建立映像檔和套件的建構設定
  • 產品套件是圖片和套件的集合,這些圖片和套件是產品建構的輸出內容。
  • 目標 (裝置) 是指用於執行產品的實體或虛擬 Fuchsia 裝置。

我們會使用 JSON 代表中繼資料。結構定義採用 json-schema.org 定義的草稿 7 格式

Schemata

本節將詳細說明初始要求和我們對結構定義所做的初始變更。

初始結構定義的必要條件

  1. 中繼資料必須有專屬名稱或 ID。
  2. 中繼資料必須含有人類可讀的說明。
  3. 中繼資料結構定義必須有版本。
  4. 中繼資料必須指定目標裝置的硬體特性。其中至少必須包含:
    1. 目標 CPU 架構,目前為 arm64 或 x64。
  5. 中繼資料必須指定一或多個產品套裝組合,每個套裝組合都必須包含:
    1. 不重複的名稱。
    2. 使用者可讀的說明。
    3. 圖片套件。
    4. 套件套裝組合。
  6. 中繼資料可能會以鍵值組合的形式納入其他產品中繼資料,協助使用者選取所需產品。這類中繼資料的範例包括建構類型 (使用者 vs. eng)、啟動類型 (正常 vs. 已停止)。
  7. 映像檔或套件組合必須符合下列條件:
    1. 指定一或多個基礎 URI。
      1. URI 中繼資料必須允許使用者指定特定格式。舉例來說,URI 存取權可能會封存 (tarball 或 zip) 或保留原樣。
      2. 使用此中繼資料的 SDK 工具必須支援 gshttp(s)file URI 配置。本機存取功能需要 file URI。
      3. 如果構件可供大眾存取,則使用此中繼資料的 SDK 工具不得要求驗證。
    2. 指定閃電中繼資料,其中包含足夠的詳細資料,以便透過 Fastboot 通訊協定為裝置進行建構。
    3. 指定模擬器中繼資料,其中包含足夠的詳細資料,以便在虛擬裝置上啟動映像檔。

結構定義演進

未來可能會針對結構定義進行一些調整。例如:

  1. 實體硬體中繼資料可能包含裝置硬體功能,例如螢幕、鍵盤或指標裝置的存在。
  2. 虛擬硬體中繼資料可指定足以佈建模擬器的虛擬裝置特性。

為因應這項需求,我們為結構定義建立版本。版本是字串,每當加入或移除結構定義的元素時,就會更新。工具可能會指定多個不同版本的結構定義,或者使用者可能需要改用舊版工具來使用舊版結構定義。

為簡化版本之間的轉換作業,我們建議採用靈活的剖析和版本化方案。我們引入了版本化信封,可簡化 JSON 剖析作業。剖析工具可以讀取版本欄位,同時忽略 JSON 文件的其餘部分。這可讓工具為每個支援的結構定義版本選擇正確的剖析器。

我們建議使用隨機產生的 8 位元十六進制數字,為每個結構定義檔案個別建立版本。在所有現有結構定義檔案中,此號碼不得重複。為防範衝突,建議您實作建構時間衝突偵測功能,以免意外提交重複內容。

由於結構定義可能會透過 $ref 設施納入其他結構定義,因此我們建議將結構定義的版本附加至結構定義檔案名稱。這不僅可在 //build/sdk/meta/common.json 等常見檔案的多個版本之間消除歧義,還會觸發參照來源結構定義的版本重新計算。

每個不相容的結構定義變更 (例如新增或移除必填欄位) 都會觸發版本重新計算。

我們允許透過 API 審查程序變更結構定義。結構定義的變更屬於開發人員功能區。

實作

實作結構定義本身,主要是將結構定義新增至 fuchsia.git,並確保該結構定義可接受 API 審查。還有兩個問題:中繼資料產生於何處?中繼資料的使用位置?

裝置中繼資料最初會產生:

  • fuchsia.git 中的 Fuchsia 版本;
  • 發布圖片供樹狀結構外使用時,
  • 作為 SDK 發布作業的一部分。

也可能會在其他位置產生,尤其是在 SDK 版本以外發布的圖片和套件。

ffx 工具會大量使用裝置中繼資料,並用於刷新裝置和啟動模擬器。由於我們會透過 SDK 發布這個結構定義,Fuchsia 樹狀結構外部的工具也可能會使用遵循該結構定義的中繼資料。

採用這種做法後,無論是樹狀結構內還是樹狀結構外使用,所有刷新和模擬工作流程都會使用裝置中繼資料做為規格。

這兩項工作都需要超出本 RFC 範圍的設計。

常見結構定義

我們會擴充 common.json 結構定義,如下所示。這並非不相容的變更,因此不必考量回溯不相容性。為求簡潔,以下省略 common.json 中的現有定義。

為求簡潔,我們省略了檔案的原始內容,並使用 ... 表示省略。

/** build/sdk/meta/common.json */
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "id": "http://fuchsia.com/schemas/sdk/common.json",
  "definitions": {
    ...,
    "envelope": {
      "description": "A versioned envelope.",
      "type": "object",
      "properties": {
        "version": {"$ref": "#/definitions/version"},
        "data": {
          "description": "The payload."
         }
      },
      "required": [
        "version",
        "data"
      ],
      "additionalProperties": false
    },
    "versioned_sdk_element": {
      "type": "object",
      "allOf": [
        {"$ref": "#/definitions/envelope"},
        {
          "type": "object",
          "properties": {
            "data": {
              "oneOf": [
                {"$ref": "#/definitions/sdk_element"}
              ]
            }
          }
        }
      ]
    },
    "version": {
      "description": "An opaque version string. The string may include any characters. Tools must not attempt to draw any conclusions about inter version compatibility other than the version 'X' manifest complies with the version 'X' of the schema and is therefore parsable by the version 'X' parser. There are no guarantees, for example, a parser for version 'B' may be able to parse a JSON document versioned 'A'.",
      "type": "string",
      "minLength": 1
    },
  }
}

請注意,由於這個結構定義了我們使用的結構定義版本,因此無法輕易變更。工具必須讀取符合此結構定義的檔案,才能瞭解封套 JSON。

裝置

由於裝置上可能安裝多個映像檔,因此我們會將裝置硬體規格納入自身定義。裝置硬體規格有兩個用途:

  1. 說明執行映像檔所需的最低硬體需求。
  2. 它會指定用來執行映像檔的虛擬 (模擬) 裝置。

我們為實體和虛擬裝置推出兩個新版本的 SDK 元素。

舞出新方向

目前,我們只會考量實體裝置的 CPU 架構。日後的結構定義版本將加入其他硬體屬性。為了提供完整的範例,下方的結構定義會將信封結構定義與 sdk_element 結構定義結合1

/** build/sdk/meta/physical_device-c906d79c.json */
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "id": "http://fuchsia.com/schemas/sdk/physical_device-c906d79c.json",
  "description": "A physical device specification.",
  "type": "object",
  "allOf": [
    {"$ref": "common.json#/definitions/envelope"},
    {
      "type": "object",
      "properties": {
        "data": {
          "allOf": [
            {"$ref": "common.json#/definitions/sdk_element"},
            {
              "properties": {
                 "type": {
                   "allOf": [
                     {"$ref": "common.json#/definitions/type"},
                     {"enum": ["physical_device"]}
                   ]
                 }
              }
            },
            {"$ref": "hardware-f9928aa4391e2ae3644ce712074a1ef7.json#/definitions/requirements"}
          ]
        }
      }
    }
  ]
}

實體裝置需求結構定義

這個結構定義可讓我們呈現裝置硬體需求。這樣一來,工具就能確保裝置硬體與我們用於佈建的構件相符。目前僅會說明 CPU 架構。

/** build/sdk/meta/hardware-c0a116ca.json */
{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "definitions": {
        "requirements": {
            "properties": {
                "hardware": {
                    "additionalProperties": false,
                    "properties": {
                        "cpu": {
                            "additionalProperties": false,
                            "properties": {
                                "arch": {
                                    "oneOf": [
                                      {"$ref": "common.json#/definitions/target_arch"}
                                    ]
                                }
                            },
                            "required": ["arch"],
                            "type": "object"
                        }
                    },
                    "required": ["cpu"],
                    "type": "object"
                }
            },
            "required": ["hardware"],
            "type": "object"
        },
    },
    "description": "Hardware requirements for running a product image.",
    "id": "http://fuchsia.com/schemas/sdk/hardware-c0a116ca.json"
}

虛擬

虛擬裝置規格可讓我們選取適當的產品套件來啟動模擬器。在日後的修訂版本中,我們會進一步開發配置模擬器的結構定義。舉例來說,下方的結構定義會使用新定義的 versioned_sdk_element 結構。

/** build/sdk/meta/virtual_device-8a8e2ba9.json */
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "id": "http://fuchsia.com/schemas/sdk/virtual_device-8a8e2ba9.json",
  "description": "A virtual device specification for launching emulators.",
  "type": "object",
  "allOf": [
    {"$ref": "common.json#/definitions/versioned_sdk_element"},
    {
      "type": "object",
      "properties": {
        "data": {
          "type": "object",
          "properties": {
             "type": {
               "allOf": [
                 {"$ref": "common.json#/definitions/type"},
                 {"enum": ["virtual_device"]}
               ]
             },
             "description": {"type": "string"},
             "virtual": {"$ref": "virtual_hardware-4c5d1a5d.json#/definitions/spec"}
          },
          "required": ["virtual"]
        }
      }
    }
  ]
}

虛擬裝置需求結構定義

虛擬硬體規格可用於在啟動模擬器時選取適當的產品組合。

/** build/sdk/meta/virtual_hardware-4c5d1a5d.json */
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "id": "http://fuchsia.com/schemas/sdk/virtual_hardware-4c5d1a5d.json",
  "description": "A virtual device specification for launching emulators.",
  "definitions": {
    "spec": {
      "emu": {
        "type": "object",
        "properties": {
          "cpu": {
            "type": "object",
            "properties": {
              "arch": {
                "oneOf": [
                  {"$ref": "common.json#/definitions/target_arch"}
                ]
              }
            },
            "required": ["arch"],
            "additionalProperties": false
          }
        },
        "required": ["cpu"],
        "additionalProperties": false
      }
    },
    "required": ["emu"]
    }
  }
}

產品組合

映像檔和套件套件可提供對裝置上安裝的軟體構件存取權。

/** build/sdk/meta/product_bundle-514c2856.json */
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "id": "http://fuchsia.com/schemas/sdk/product_bundle-514c2856.json",
  "description": "Artifacts required to boot and run software on a device.",
  "type": "object",
   "allOf": [
    {"$ref": "common.json#/definitions/versioned_sdk_element"},
    {
      "type": "object",
      "properties": {
        "data": {
          "type": "object",
          "properties": {
             "type": {
               "allOf": [
                 {"$ref": "common.json#/definitions/type"},
                 {"enum": ["product_bundle"]}
               ]
             },
             "description": {
               "description": "A human readable description of the product bundle.",
               "type": "string"
             },
             "device_refs": {
               "description": "A list of physical or virtual device names this product can run on.",
               "type": "array",
               "minItems": 1,
               "items": {
                   "type": "string",
                   "minLength": 1
               }
             },
             "metadata": {
               "description": "A list of key-value pairs describing product dimensions. Tools must not rely on the presence or absence of certain keys. Tools may display them to the human user in order to assist them in selecting a desired image or log them for the sake of analytics. Typical metadata keys are: build_info_board, build_info_product, is_debug.",
               "$ref": "common.json#/definitions/key_value_list"
             },
             "manifests": {
               "description": "Manifests describing how to boot the product on a device.",
               "flash": {"$ref": "flash_manifest-c85dbd8e.json#/definitions/manifest"},
               "emu": {"$ref": "emu_manifest-b0708439.json#/definitions/manifest"}
             },
             "images": {
               "description": "A list of system image bundles. Each image bundle must be equivalent to all others. I.e., all image bundle URIs are effectively mirrors of each other. Their formats may vary. Pick an entry that best suits your needs.",
               "type": "array",
               "minItems": 1,
               "items": {"$ref": "#/definitions/image_bundle"}
             },
             "packages": {
               "description": "A list of package bundles. Each package bundle must be equivalent to all otherwise. I.e., all package bundle URIs are effectively mirrors of each other. Their formats may vary. Pick an entry that best suits your needs.",
               "type": "array",
               "minItems": 1,
               "items": {"$ref": "#/definitions/package_bundle"}
             }
          },
          "required": ["device_refs", "manifests", "images", "packages"]
        }
      }
    }
  ],
  "definitions": {
    "image_bundle": {
      "description": "A set of artifacts necessary to provision a physical or virtual device",
      "type": "object",
      "properties": {
         "base_uri": {
           "description": "A base URI for accessing artifacts in the bundle.",
           "$ref": "#/definitions/bundle_uri"
         },
         "format": {
           "description": "Bundle format: files - a directory layout; tgz - a gzipped tarball. In case of the 'files' format, the base base path points to a directory. The manifest paths is relative to the directory. To get a full path append a path inside the manifest to base_uri. In case of the 'tgz' format, the base path points to the archive. The manifest path is relative within the archive."
           "enum": [
             "files",
             "tgz"
            ]
         }
      },
      "required": [
        "base_uri",
        "format"
      ],
      "additionalProperties": false
    },
    "package_bundle": {
      "description": "A set of artifacts necessary to run a physical or virtual device",
      "type": "object",
      "properties": {
         "repo_uri": {
           "description": "A package repository URI. This may be an archive or a directory.",
           "$ref": "#/definitions/bundle_uri"
         },
         "format": {
           "description": "Repository format: files - a directory layout; tgz - a gzipped tarball.",
           "enum" : [
             "files",
             "tgz"
           ]
         },
         "blob_uri": {
           "description": "An optional blob repository URI. If omitted, it is assumed to be <repo_uri>/blobs. If repo_uri refers to a gzipped tarball, ./blobs directory is expected to be found inside the tarball.",
           "$ref": "#/definitions/bundle_uri"
         }
      },
      "required": [
        "repo_uri",
        "format"
      ],
      "additionalProperties": false
    },
    "bundle_uri": {
      "description": "Allowed system image and package bundle URIs.",
      "type": "string",
      "format": "uri",
      "pattern": "^(?:http|https|gs|file):\/\/"
    }
  }
}

Flash 結構定義

以 Flash 架構為基礎的資訊清單會說明裝置 Flash 作業所需的圖片構件。資訊清單會與建構作業產生的現有 flash.json 相符。閃光燈中繼資料會嵌入產品套件 SDK 元素。

/** build/sdk/meta/flash_manifest-c85dbd8e.json */
{

  "$schema": "http://json-schema.org/draft-07/schema#",
  "id": "http://fuchsia.com/schemas/sdk/flash_manifest-c85dbd8e.json",
  "description": "A manifest that describes how to flash a device.",
  "type": "object",
  "properties": {
    "manifest": {"$ref": "#/definitions/manifest"}
  },
  "required": ["manifest"],
  "additionalProperties": false,
  "definitions": {
    "manifest": {
      "description": "A named list of partitions and OEM files necessary to flash a device.",
      "type": "object",
      "properties": {
        "hw_revision" : {
          "description": "A board name used to verify whether the device can be flashed using this manifest.",
          "type": "string"
        },
        "products": {
          "description": "A list of product specifications that can be flashed onto the device.",
          "type": "array",
          "items": {"$ref": "#/definitions/product"},
          "minItems": 1
        }
      },
      "required": ["hw_revision", "products"],
      "additionalProperties": false
    },
    "product": {
      "description": "A named product specification.",
      "type": "object",
      "properties": {
        "name": {
          "description": "A unique name of this manifest.",
          "type": "string"
        },
        "partitions": {
          "description": "A list of partition names and file names corresponding to the partitions.",
          "$ref": "common.json#/definitions/key_value_list"
        },
        "bootloader_partitions": {
          "description": "A list of partition names and file names corresponding to the partitions.",
          "$ref": "common.json#/definitions/key_value_list"
        },
        "oem_files": {
          "description": "A list of OEM command and file names corresponding to the command.",
          "$ref": "common.json#/definitions/key_value_list"
        }
      },
      "required": ["name", "partitions"],
      "additionalProperties": false
    }
  }
}

模擬器結構定義

模擬器架構定義了在模擬器上啟動產品所需的映像檔成果。

/** build/sdk/meta/emu_manifest-b0708439.json */
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "id": "http://fuchsia.com/schemas/sdk/emu_manifest-b0708439.json",
  "definitions": {
    "manifest": {
      "description": "A manifest that describes how to boot an emulator.",
      "type": "object",
      "properties": {
        "kernel": {
          "description": "A path to the kernel image file. The path is relative to the image bundle base.",
          "type": "string",
          "minLength": 1
        },
        "initial_ramdisk": {
          "description": "A path to the initial ramdisk, the kernel ZBI. The path is relative to the image bundle base.",
          "type": "string",
          "minLength": 1
        },
        "disk_images": {
          "description": "A list of one or more disk image paths to FVM images. Each path is relative to the image bundle base.",
          "type": "array",
          "items": {
            "type": "string",
            "minLength": 1,
          },
          "minItems": 1
        }
      },
      "required": ["kernel", "initial_ramdisk", "disk_images"],
      "additionalProperties": false
    }
  }
}

其他常見定義

以下是常見定義的額外新增項目。如要瞭解版本相關的新增項目,請參閱 common.json 相關章節。為了簡化說明,以下省略 common.json 中的現有定義。

/** build/sdk/meta/common.json */
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "id": "http://fuchsia.com/schemas/sdk/common.json",
  "definitions": {
    ...,
   "key_value": {
     "description": "A key-value pair.",
      "type": "array",
      "items": [
        {"type": "string"},
        {"type": ["number", "string"]}
      ],
      "minItems": 2,
      "additionalItems": false
    },
    "key_value_list": {
      "description": "A list of key-value pairs.",
      "type": "array",
      "items": {"$ref": "#/definitions/key_value"}
    }

範例

裝置

實體裝置

以下是裝置硬體規格的範例。

{
  "version": "c906d79c",
  "data": {
    "type": "physical_device",
    "name": "generic-x64",
    "description": "A generic x64 device.",
    "hardware": {
      "cpu": {
        "arch": "x64"
      }
    }
  }
}

產品組合

實體裝置上的終端機

這是通用終端機產品的範例,可在通用 x64 裝置上啟動,其中包含兩個已封存的鏡像,分別可透過 gshttps 的 URI 存取映像檔和套件。

{
  "version": "514c2856",
  "data": {
    "type": "product_bundle",
    "name": "generic-x64",
    "description": "A terminal x64 product.",
    "device_refs": ["generic-x64"],
    "metadata": [
      ["build-type", "release"],
      ["product", "terminal"]
    ],
    "manifests": {
      "flash": {
        "hw_revision": "x64",
        "products" : [
          {
            "bootloader_partitions": [],
            "name": "fuchsia",
            "oem_files": [],
            "partitions": [
              ["", "fuchsia.zbi"],
              ["", "zedboot.zbi"],
              ["", "fuchsia.vbmeta"],
              ["", "zedboot.vbmeta"]
            ]
          }
        ]
      }
    },
    "images": [
      {
        "base_uri": "gs://fuchsia/development/0.20201216.2.1/images/generic-x64.tgz",
        "format": "tgz"
      },
      {
        "base_uri": "https://storage.googleapis.com/fuchsia/development/0.20201216.2.1/images/generic-x64.tgz",
        "format": "tgz"
      }
    ],
    "packages": [
      {
        "repo_uri": "gs://fuchsia/development/0.20201216.2.1/packages/generic-x64.tar.gz",
        "format": "tgz"
      },
      {
        "repo_uri": "https://storage.googleapis.com/fuchsia/development/0.20201216.2.1/packages/generic-x64.tar.gz",
        "format": "tgz"
      }
    ]
  }
}
模擬器上的終端機

這是在 x64 模擬器上可啟動的通用終端產品範例。您可以直接從 GCS 存取映像檔和套件。

{
  "version": "514c2856",
  "data": {
    "type": "product_bundle",
    "name": "generic-x64",
    "description": "A terminal x64 product.",
    "device_refs": ["qemu-x64"],
    "metadata": [
      ["build-type" , "debug"],
      ["product", "terminal"]
    ],
    "manifests": {
      "emu": {
        "kernel": "qemu-kernel.kernel",
        "initial_ramdisk": "zircon-a.zbi",
        "disk_images": ["storage-sparse.blk"]
      }
    },
    "images": [
      {
        "base_uri": "https://storage.googleapis.com/fuchsia-artifacts/builds/8852232026486839104/images/",
        "format": "files"
      }
    ],
    "packages": [
      {
        "repo_uri": "https://storage.googleapis.com/fuchsia-artifacts/builds/8852232026486839104/packages/",
        "blob_repo_uri": "https://storage.googleapis.com/fuchsia-artifacts/blobs/",
        "format": "files"
      }
    ]
  }
}

成效

由於中繼資料產生和剖析作業不會耗用大量資源,因此這項作業不太可能會影響效能。

Ergonomics

發布標準化中繼資料後,不必使用不穩定的硬式編碼設定,整合作業應該會變得更簡單。

我們選擇 JSON 的原因是,這是一種成熟的格式,也是 Fuchsia 設定檔的實際標準。JSON 結構定義格式已正式化並經過同儕審查。

回溯相容性

由於現有的中繼資料沒有使用者,因此導入中繼資料不會影響回溯相容性。

這些結構定義的未來修訂版本將透過標準 LSC 程序進行 API 審查及變更管理,其中包括測試和與高優先順序客戶的直接互動。這項程序會透過定義結構定義的版本來協助。

安全性考量

以這些結構定義為基礎的結構描述資料,安全性不亞於現有解決方案,後者是類似資訊的臨時硬式編碼。

我們會在這些結構定義的生命週期初期,提升構件交付的安全性。這可能會在部署前進行,具體取決於安全團隊的意見回饋。重要的是,工具必須驗證下載的構件內容是否完整:構件必須與發布中繼資料時的預期內容一致。方法是將雜湊函式的輸出內容加入結構定義,或是使用支援完整性檢查的通訊協定,例如 TUF。

作為 Fuchsia SDK 一部分,用於使用此結構定義和擷取構件且可供販售的工具,必須實作額外的安全措施,確保傳輸安全性,以防範中間人攻擊等攻擊。他們可能會拒絕從不安全 / 不受信任的位置擷取或使用構件。

隱私權注意事項

此提案沒有任何已知的隱私權考量。發布中繼資料的使用者或團隊可能需要考量隱私權問題,我們建議他們自行進行隱私權審查。舉例來說,發布中繼資料的團隊可能需要仔細考量如何追蹤下載次數。

測試

雖然結構定義的存在情形不需要測試,但我們會確保建構作業產生的中繼資料符合結構定義。我們也會進行相容性測試,確保工具可在必要時繼續使用舊版結構定義。

說明文件

目前並未規劃在結構定義之外提供任何文件,但這可能會隨著需求而改變。開發人員在建立或更新結構定義時,可能需要提供術語的字典,並說明每個結構定義的用途,以及彼此的互動方式。

缺點、替代方案和未知因素

我們會提供特定 API,用於指定裝置映像檔。這種做法的好處是可提高各版本的相容性、利用現有的變更管理程序,以及提供我們發布能一致運作的工具的能力,但缺點是彈性降低 (因為有繁文縟節的障礙,因此需要更長的時間才能變更結構定義)。

既有技術與參考資料

本文件收集並系統化上述樹狀結構中的常見設定。您可以在 //build/images/BUILD.gn 中找到大部分現有中繼資料,例如目前版本的閃燈架構可在其中找到


  1. 所有中繼資料都會以 SDK 元素的形式發布。