RFC-0100 - 產品中繼資料

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

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

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

摘要

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

這項 RFC 導入了這類資訊的新結構定義,做為平台和工具之間的合約,以及未來更新該結構定義的程序。

提振精神

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

工具最終會依賴非官方的圖片和套件慣例,或硬式編碼可能變更的假設 (例如下載的 URI 結構)。因此,當這些慣例有所變更時,工具就容易發生故障。

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

我們發布的完整中繼資料易於使用,因此 SDK 使用者可以選擇要將哪張圖片刷入裝置,或使用模擬器啟動,而不需要 Fuchsia 基礎架構或 SDK 團隊提供大量協助。SDK 開發人員將可透過單一資料來源,向使用者顯示產品資訊。工具開發人員將有明確的合約,說明如何使用這項資訊。

輕鬆更新

中繼資料目前是 SDK 生成作業的一部分,因此每次發布新圖片時,都必須手動更新。因此新增、重新命名或移除中繼資料時,不僅費時費力,也容易出錯。資訊經常過時,甚至從未新增。

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

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

完整性

現有裝置中繼資料缺少重要詳細資料。舉例來說,裝置刷機工具需要分割區名稱清單,以及要寫入這些分割區的檔案名稱。目前這項程序尚未正式化,因此我們與執行刷機的工具之間沒有合約。因此難以提供穩定性 / 相容性保證。

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

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

設計

為透過我們的 SDK 提供實用且最新的產品中繼資料,我們會:

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

請注意,雖然我們在此定義了初始結構定義,但會允許透過 API 委員會審查進行演變,無須額外的 RFC。

定義

為方便說明,本文將採用下列定義:

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

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

Schemata

本節詳細說明瞭初始需求,以及我們將對結構定義進行的初始變更。

初始結構定義需求

  1. 中繼資料必須有不重複的名稱或 ID。
  2. 中繼資料必須包含使用者可理解的說明。
  3. 中繼資料結構定義必須有版本。
  4. 中繼資料必須指定目標裝置的硬體特徵。至少須包括:
    1. 目標 CPU 架構,目前為 arm64 或 x64。
  5. 中繼資料必須指定一或多個產品套裝組合,每個套裝組合都必須包含:
    1. 專屬名稱。
    2. 使用者可理解的說明。
    3. 圖片組合。
    4. 套裝組合。
  6. 中繼資料可能包含鍵值組合形式的額外產品中繼資料,可協助使用者選取所需產品。這類中繼資料的範例包括建構類型 (使用者與工程師) 和啟動類型 (正常與停止)。
  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 Schema

根據快閃架構建立的資訊清單會說明快閃裝置所需的映像檔構件。資訊清單與建構作業產生的現有 flash.json 相符。Flash 中繼資料會嵌入產品套件 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"
      }
    ]
  }
}

效能

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

人體工學

發布標準化中繼資料後,就不必使用容易出錯的硬式編碼設定,整合作業也會變得更簡單。

我們選擇 JSON 是因為這是行之有年的格式,也是 Fuchsia 設定檔的事實標準。JSON 結構定義格式經過正式化和同儕審查。

回溯相容性

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

這些結構定義的後續修訂版本將經過 API 審查,並透過標準 LSC 程序管理變更,包括測試及與高優先順序客戶直接互動。透過架構定義的版本控管,可協助完成這項程序。

安全性考量

根據這些結構定義產生的中繼資料,安全性與現有解決方案不相上下,現有解決方案是類似資訊的臨時硬式編碼。

我們會在這些結構定義的生命週期初期,提高構件交付的安全性。視安全團隊提供的意見回饋而定,這可能是在部署前。最重要的是,工具必須驗證下載的構件內容是否完整:構件必須與發布中繼資料時的預期內容一致。如要達成此目的,請將雜湊函式的輸出內容新增至結構定義,或使用支援完整性檢查的通訊協定,例如 TUF。

如果工具是透過 Fuchsia SDK 販售,且會使用這個結構定義並擷取構件,就必須實施額外的安全措施,確保傳輸安全,防止中間人攻擊等。他們可能會拒絕從不安全 / 不受信任的位置擷取或使用構件。

隱私權注意事項

這項提案沒有已知的隱私權考量。發布中繼資料的個人或團隊可能需要考量隱私權問題,我們希望他們自行進行隱私權審查。舉例來說,發布中繼資料的團隊可能需要仔細考量如何追蹤下載次數。

測試

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

說明文件

目前除了架構本身,我們沒有規劃其他文件,但這可能會因應需求而改變。建立或更新結構定義的開發人員,可能需要提供術語表、說明各結構定義的使用方式,以及結構定義之間的互動方式。

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

我們將致力於提供特定 API,用於指定裝置圖片。這麼做的好處是可提高各版本之間的相容性、運用現有的變更管理程序,以及讓我們能夠發布運作一致的工具,但缺點是彈性降低 (由於官僚障礙,變更結構定義需要較長時間)。

既有技術和參考資料

本文收集並系統化了整個樹狀結構的常見設定,如上所述。大部分現有的中繼資料都可以在 //build/images/BUILD.gn 中找到,例如目前版本的刷機架構


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