| 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 表面的一部分,可以随 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,并将包含字体提供程序配置数据的 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,无论其构建时间或位置如何)。 buildinfo和hwinfo组件的值以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 文件中。存储在底层 blob 文件系统时,磁盘上的文件大小会向上舍入到块大小,通常为 8KiB。通过将配置文件一起归档,可以消除向上舍入带来的额外开销。这一点很重要,因为配置文件通常数量众多且很小,因此总开销实际上可能大于这些文件的压缩大小之和。
在使用替代解决方案时,如果存储空间很重要,则应使用相同的技术或等效技术,以确保存储效率的对等性。
工效学设计
config-data 的替代方案具有更好的人体工程学设计,最重要的是,它们不依赖于基于软件包名称和“远距离操作”的不稳定合约。
向后兼容性
有时需要以软过渡的方式从 config-data 迁移。在过渡期间,使用配置数据的组件必须能够接受两种形式的输入:config-data 和所选的替代方案。
安全注意事项
此 RFC 不会引入任何新的配置机制,我们将用作 config-data 替代方案的所有机制都已存在于系统中,并且已经过各自的安全审核。组件作者在设计或更改安全相关功能的配置时,应咨询安全团队。
隐私注意事项
此 RFC 不会引入任何新的配置机制,我们将用作 config-data 替代方案的所有机制都已存在于系统中,并且已经过各自的隐私审核。组件作者在设计或更改隐私敏感功能的配置时,应咨询隐私团队。
测试
针对 config-data 提出的替代方案都已建立测试最佳实践。如需了解测试信息,请参阅特定功能的文档。例如,请参阅使用 测试结构化配置 的指南,其中使用了 大区构建器。替换正在测试的结构化配置值非常简单,只需执行以下操作:
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 修订版本的功能路由的支持,但此机制 尚未设计。