RFC-0182:废弃了 config-data

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

我们打算弃用原有机制,以便在不同代码库的组件之间提供/使用配置文件

问题
Gerrit 更改
  • 696482
作者
审核人
提交日期(年-月-日)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 及其当前的替代项。
  • 构建团队:config-data 构建时逻辑的维护者。
  • 软件组装团队:config-data 汇编时逻辑的维护者。
  • config-data”的当前用户,用户来自多个团队。

教员

  • hjfreyer@google.com

审核者

  • 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 的现有代码不进行修改。

父组件或领域可能有以下声明:

{
    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 的内容可能来自 build 定义,如下所示:


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 模板,以添加对具有既定可见性列表的目标的依赖项。值得注意的是,这仅涵盖树内使用,但限制在树外 product 组件中新使用 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 迁移完成之前不得开始此类工作,但我们应快点并停止回归。

在有专门的人员来完成迁移之前,对许可名单的更新(例如为支持重构)应在一个工作日内接受审核并获得批准。

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

结构化配置是一种不断演变的新机制。例如,表示配置所需的某些功能(例如其他数据类型)尚未实现。

功能路由目前不受平台版本控制的约束。我们计划为在 ABI 修订版本上调整功能路由提供支持,但这种机制尚未设计。