RFC-0182:废弃了 config-data

RFC-0182:废弃 config-data
状态已接受
区域
  • 组件框架
说明

打算废弃在各个代码库的组件之间提供/使用配置文件的旧版机制

问题
Gerrit 更改
作者
审核人
提交日期(年-月-日)2022-06-30
审核日期(年-月-日)2022-08-15

摘要

此 RFC 提出了以下建议:

  • [config-data] 机制声明为已废弃。
  • 为现有用例建立许可名单。
  • 随着时间的推移,将现有的 config-data 用法替换为其他更好的解决方案。
  • 最终从 Fuchsia 中移除对 config-data 的支持。

设计初衷

此 RFC 的直接目标是为现有 config-data 用例创建许可名单达成粗略共识,并尽量避免扩大该许可名单。为提供额外的背景信息,并应各利益相关方的请求,我们还会提供与此直接目标无关的其他信息。

[config-data] 是一种配置文件机制,可通过在运行时在该组件的命名空间中提供某些文件来调节打包组件的行为。

config-data 会针对目标组件的软件包名称使用未强制执行的合约或惯例来创建“远程幽灵操作”。这很有问题,因为软件包名称无法用作稳定的标识符,无法成为 Fuchsia SDK Surface 的一部分,无法与 SDK 一起进行版本控制,也无法随时间推移而演变(例如声明支持窗口并允许进行软过渡)。经验表明,基于软件包名称的协定会导致运行时假设不稳定且维护成本高。

此外,由于 config-data 会将开发者软件包中的内容与包含配置文件的基础软件包中的内容混合,这会导致开发者体验混乱,因为开发者会推送软件包的新修订版,但在运行时会看到旧的配置文件。开发者经常会问,为什么他们推送了更新版软件包,但在 /config/data 下看到了过时文件,却没有意识到这些文件来自其他软件包。若要向开发者说明此行为,就需要向他们介绍“基础软件包”等平台实现细节,这表明抽象失败,这是不希望的。更不用说,由于这种周期性工作流不一致性,工作效率会受到影响。

config-data 在解决以下问题时非常有用:产品组装不同阶段的参与者需要影响不在其直接控制之下的组件。使用 config-data,您可以使用来自一个位置(代码库、构建系统等)的配置值来调节来自其他位置的组件的行为。

在某些情况下,组件和配置具有相同的来源,但用户仍更倾向于使用 config-data 作为集成点。例如,这样一来,用户就可以生成一个软件包,并将不同的配置值旁加载到此软件包中包含的组件。当生成多个软件包的成本较高时,这非常有用,例如,如果每个软件包变种都需要单独上传到后续集成点。

目前,config-data 有多个替代方案。这些方法包括基于目录功能结构化配置、通过协议功能提供配置以及将配置文件与使用它们的组件打包来路由配置目录的其他方法。

虽然弃用 config-data 的现有用法和该功能本身并不是当务之急,但我们应引导新用法采用现代解决方案,并促使用有现有用法的所有者迁移到现代替代方案。

在这种情况下,最佳做法是为 config_data() GN 规则建立许可名单,并使用现有用法对其进行初始化。随着时间的推移,许可名单预计会趋向于零,但如果不确定新用法是否适用现代替代方案,则可以将其列入许可名单。允许新用法时,应在允许此更改时事先说明原因,以减少代码审核流失。

利益相关方

  • 组件框架团队:创建了 config-data 及其当前替代方案。
  • build 团队:config-data 构建时逻辑的维护者。
  • 软件汇编团队:config-data 汇编时间逻辑的维护者。
  • config-data 的当前用户,涵盖多个团队。

教员

  • hjfreyer@google.com

Reviewers:

  • aaronwood@google.com
  • adamperry@google.com
  • awolter@google.com
  • ddorwin@google.com
  • fmil@google.com
  • geb@google.com
  • jsankey@google.com
  • kpozin@google.com
  • wez@google.com
  • yaar@google.com
  • ypomortsev@google.com

社交

此 RFC 的草稿在发布前已由组件框架和软件组装技术主管审核。

背景

config-data 的运作方式

在旧版 appmgr(也称为 CFv1)中,config-data 的实现方式是将已启动的组件的软件包名称与 config-data 基础软件包中的子目录进行匹配。如果找到匹配项,系统会在已启动组件的命名空间中将匹配的子目录提供在路径 /config/data 下。

定义 config-data 的方法是指定要提供的文件、这些文件在组件的传入命名空间中应提供的路径(通常在 /config/data 下),以及应在这些路径中提供这些文件的组件的一个或多个软件包名称。

例如,某个组件可能会请求使用配置文件,如下所示:

{
    use: [
        {
            directory: "config-data",
            rights: [ "r*" ],
            path: "/config/data",
        },
    ],
}

这表示该组件要求嵌入程序提供名为“config-data”的只读目录功能,该功能将由框架在 /config/data 处呈现,以允许依赖于 /config/data 的现有代码在未经修改的情况下正常运行。

父级组件或 Realm 可能包含以下声明:

{
    children: [
        {
            name: "font-provider",
            url: "fuchsia-pkg://fuchsia.com/fonts#meta/font-provider.cm",
        },
    ],
    offer: [
        {
            directory: "config-data",
            from: "parent",
            to: [ "#font-provider" ],
            subdir: "fonts",
        },
    ],
}

它会接受来自父级的包含多个子目录的 config-data,并将包含 font-provider 配置数据的 example 子目录路由到该组件。

config-data 的内容可能来自构建定义,例如:


import("//build/config.gni")

config_data("example_config_data") {
  for_pkg = "example"
  sources = [
    "file1.dat",
    "file2.dat",
    ...
  ]
  outputs = [ "{{source_file_part}}" ]
}

构建系统会收集上述目标以及类似的目标,以构成名为 config-data 的软件包的内容。然后,专用路由规则会将 config-data 软件包的所有内容(按上述 for_pkg 参数所示整理为子目录)路由到核心领域和其他位置,在这些位置,这些内容会分发到进一步配置为使用它们的各种组件。

config-data 目前的使用方式

config-data 有许多用例。以下是一些说明性示例:

  • ICU 数据和 tzdata:ICU 库的数据(尤其是时区数据“tzdata”)在运行时以 config-data 的形式提供。在 Fuchsia 平台源代码中为这些数据文件定义单一真相来源,并将这些文件提供给来自各种来源(例如 Chromium、Flutter、内部 Google 代码库等)的组件,用于确保仅使用这些文件的一个修订版。这样可以实现一致性(例如,所有组件都同意使用单个 tzdata,无论其来源如何)和高效性(所有组件都共享相同的 ICU blob,无论其构建时间或位置如何)。
  • buildinfohwinfo 组件的值以 config-data 的形式提供。这些组件是从平台源代码构建的,但可能需要由产品进行配置。目前,config-data 充当此配置机制。
  • 在平台源代码中定义的“设置”界面组件可以配置为在具有不同硬件切换开关的不同设备上表现出不同的行为。例如,SetUI 在 Astro 设备上的行为与在 Sherlock 设备上的行为不同,目前由 config-data 控制。
  • 平台字体提供程序组件可配置为提供特定于产品的字体。字体文件和用于描述其属性的清单以 config-data 的形式提供,并添加到树外产品组件中。

设计和实现

我们将建立构建时回归停止点,以防止在未经明确批准的情况下对 config-data 进行新的使用。系统会签入现有用例的许可名单,对此许可名单所做的更改将受 OWNERS 文件的约束。组件框架团队将被分配为 fuchsia.git 的所有者,使用 config-data 的花瓣将被分配为其使用情况的所有者。代表将负责管理各自的许可名单条目,例如协助重构或有针对性的消减。

回归停止的实现方式并不重要。一种常见且可能的实现策略是更改 config-data GN 模板,以向具有设定可见性列表的目标添加依赖项。值得注意的是,这仅涵盖树内使用情形,但限制在树外产品组装中对 config-data 的新用法也很重要。我们还可以在此处与 PDK 团队协作,开发适当的机制。

深入探讨 config-data 的替代方案不在本 RFC 的讨论范围之内。如需使用这些替代方案,请参阅上面链接的文档。

确定向组件提供配置的最佳实践,或为从 config-data 迁移提供迁移指南,不在本 RFC 的讨论范围内。我们正在努力编写此类文档,并将其单独发布,不与此 RFC 一起发布。

性能

config-data 软件包的一个特殊且有趣的方面是,所有文件都打包在路径 meta/ 下。这意味着这些文件会归档到 meta.far 文件中。存储在底层 blobfs 文件系统中时,磁盘上的文件大小会向上舍入到块大小(通常为 8KiB)。通过将配置文件一起归档,可以消除向上舍入的额外开销。这一点很重要,因为配置文件通常数量众多且体积较小,因此总开销实际上可能大于这些文件压缩后的大小总和。

在使用替代解决方案时,如果存储空间很重要,则应使用相同的技术或等效技术,以确保存储效率不变。

工效学设计

config-data 的替代方案的人体工学设计更出色,最重要的原因是它们不依赖于基于软件包名称和“远程操作”的脆弱协定。

向后兼容性

config-data 迁移有时需要以软过渡的方式进行。在过渡期内,使用配置数据的组件必须能够接受 config-data 和所选替代方案这两种形式的输入。

安全注意事项

此 RFC 不会引入任何新的配置机制,我们将用作 config-data 替代方案的所有机制都已存在于系统中,并且已通过各自的安全审核。在设计或更改与安全相关的功能的配置时,组件作者应咨询安全团队。

隐私注意事项

此 RFC 不会引入任何新的配置机制,我们将用作 config-data 替代方案的所有机制都已存在于系统中,并且已通过各自的隐私权审核。在设计或更改隐私敏感功能的配置时,组件作者应咨询隐私权团队。

测试

config-data 提供的替代方案都采用了已建立的测试最佳实践。如需了解测试信息,请参阅特定功能的文档。例如,请参阅有关使用 Realm Builder 测试结构化配置的指南。替换待测试的结构化配置值只需执行以下操作:

realm_builder.SetConfigValue(child_name, key, value_for_test);

当我们需要将配置数据作为文件提供给受测组件时(例如在集成测试中),可以将这些文件与测试打包在一起,然后将其作为数据目录从测试组件(位于测试领域根目录)路由到受测组件。例如:

{
    ....
    capabilities: [
        {
            directory: "test_config",
            rights: [ "r*" ],
            path: "/test_config",
        },
    ],
    children: [
        {
            name: "component_under_test",
            ...
        },
    ],
    offer: [
        {
            directory: "test_config",
            from: "self",
            as: "config",
        },
    ],
}

文档

为了支持从 config-data 迁移,我们将提供迁移指南。迁移指南可帮助开发者为其使用场景选择最佳替代方案,并引导他们参阅其他文档。

有关人员配置和流失率的说明

接受此 RFC 不会对 config-data 的现有用户施加任何迁移到新型替代方案的要求。如果收到迁移任务,则应组建一个核心迁移团队来执行大部分工作。作者建议,在 CFv2 迁移完成之前,不应开始进行此类工作,但我们应加快速度,尽快完成回归停止。

在有专门的人员负责迁移之前,许可名单的更新(例如为支持重构而进行的更新)应在 1 个工作日内完成审核和审批。

缺点、替代方案和未知情况

结构化配置是一种新机制,并且还在不断发展。例如,尚未实现用于表达配置所需的一些功能,例如其他数据类型。

功能路由目前不受平台版本控制。这项计划旨在为调节 ABI 修订版的 capability 路线提供支持,但此机制尚未设计完毕。