结构化配置

  • 项目负责人:jsankey@google.com
  • 领域:组件

问题陈述

如果软件可以“配置”,即可以在外部控制其行为,而不是通过其源代码进行修复,那么该软件将更加灵活且可重用。

Fuchsia 适用于涉及各种产品的大规模生产环境,因此可能造成需要进行配置的原因有很多。例如:

  • 一名产品工程师,负责定制平台组件的操作,以满足产品的需求。
  • 在自动化平台测试期间启用更多诊断或更快超时的软件工程师。
  • 发布管理员在正式版发布之前为产品的 Beta 渠道启用新功能。
  • 一名用户研究人员在产品的一小部分生产设备上对提议的界面更改进行 A/B 测试。
  • 企业管理员用于限制企业拥有和管理的设备的功能。
  • 软件开发者在开发应用时更改系统参数以探索故障模式。
  • 最终用户自定义其设备以启用预发布功能。

请注意,这些示例具有截然不同的属性。一些是“静态”的,即在构建软件包或组建系统时应用配置,还有一些是“动态”的,无需对系统映像进行任何更改即可应用配置。有些更改应该在设备重启后持续有效,而有些更改则只是临时更改。其中一些属性应适用于所有产品,而其他某些属性仅在一种产品的情况下才有意义。

其他平台则提供一种或多种灵活的配置机制来满足如此广泛的需求。例如,Chrome 具有偏好设置、设置、功能、开关和标志

目前,在 Fuchsia 上,平台组件的配置主要通过两种机制执行:

  • config_data。build 会创建一个 config_data 软件包,其中包含每个包含可配置组件的软件包的目录。这些组件可以在运行时从此软件包中读取自己的配置文件。
  • #defines。有些软件是基于构建系统参数(例如 auto_update_packages)进行条件式编译。这些参数在不同产品中可以不同。

一些平台服务还会公开 FIDL 接口来控制其配置,并且可能会使用隔离的永久性存储空间或 stash 在设备重启后保留这些数据。

这些机制足以处理少量产品中的简单配置情况,但不适合进行动态配置或多层配置,并且已经导致了一些痛点。例如:

  • 配置是在系统映像级别设置的,因此即使是配置上的细微差异,也要求添加新产品(例如_eng_arrested 个产品)
  • 配置在系统映像级别设置,因此(假设当前缺少树组合)无法在树外进行管理
  • 系统映像的配置已修复,因此无法直接调试生产映像。例如,“用户”映像不能与不同的标志组合使用,也不能使用开发者密钥重新签名以在以开发者为密钥的设备上启用 SSH。
  • 编译期间会发生一些配置,这会限制在各产品中重复使用预编译工件。
  • 由于缺少平台级配置,某些方面引入了特定于领域的解决方法(例如模块化配置)
  • 重大迁移很危险,因为一个渠道中的所有设备会同时迁移。安全发布会给组件开发者带来沉重的负担,需要支持并行操作并进行暗发布(例如从粗略时间迁移到 HTTPSDate)
  • config_data 系统是针对 CFv1 创建的,并且每个软件包都有一个组件的模型。可以使用“目录子目录”功能在 CFv2 中提供支持,但这需要耗费大量人力,并且容易出错。

解决方案声明

此项目仍处于早期阶段,需要进一步的工作才能最终确定相关要求和解决方案。

通过 config_data 软件包传递给组件的文件对平台是不透明的 - 不同的组件使用不同的文件格式,并且数据可以任意复杂程度。Fuchsia 平台无法知道组件需要或接受哪些数据,因此平台无法验证数据或合并来自不同来源的元素。接受来自不可信来源的不透明配置数据会引发一些安全问题。

我们认为,需要一种新的“结构化配置数据”来补充现有的“不透明配置数据”。此结构化配置数据应具有以下属性:

  • 每个组件都明确定义了所需的数据元素
  • 明确定义了每个数据元素的允许值:在许多情况下,布尔值、枚举和有界限整数就足够了。
  • 该平台收集来自各种来源的结构化配置数据,支持静态和动态配置。
  • 来源能够禁止在“较高”层进行某些更改,例如,产品配置应该能够防止动态发布不兼容的功能。
  • 平台会将结构化配置数据提供给独立于设置数据源的组件(例如通过运行程序),也就是说,组件不知道特定数据元素是动态配置还是静态配置。
  • 动态配置可用于诊断,因此可以将 bug 和系统指标更改归因于导致这些错误的实验和部分发布。

我们预计下一季度的工作将涉及以下阶段。

第 1 阶段

明确定义可能的配置来源、这些来源之间的关系以及用于描述配置更改的关键属性。请商定短期和长期所支持的组合以及实现每种组合的推荐机制。这包括描述不同配置形式之间的边界,例如,系统设置服务应在何时处理某项配置。

本练习将更好地定义结构化配置必须填补的空白。最终结果应该类似于 Chrome 的配置参考页面,并且应该发布到 fuchsia.dev。

第 2 阶段

定义结构化配置在短期和未来都必须满足的要求,并优先满足这些要求。与 1-2 位启动客户合作,商定 2021 年的时间表和需求。可能的候选对象是支持将现有客户从模块化配置(因而不再采用模块化配置)迁移,或者支持扩展可扩缩产品组件中可能的配置类型。

此阶段的待解决问题在很大程度上与范围有关。例如:

  • 是否需要支持 v1 组件或非组件化驱动程序?
  • 是否应该使用与其管理的组件相同的系统来配置组件管理器?
  • 是否可以以不同的方式配置同一组件的不同实例?
  • 在短期内,是否有必要持久保留动态配置?

第 3 阶段

通过 RFC 流程提出并商定满足这些要求的技术解决方案。

依赖项

在此阶段,结构化配置项目不依赖于任何其他持续性项目。

其他项目可能会选择依赖于结构化配置来实现某些新功能或迁移。例如,将现有产品迁移到会话框架可能依赖于结构化配置来替换模块化配置。

根据范围和时间表,可能只有组件框架 v2 组件支持结构化配置。对于希望将结构化配置用于组件 v2 迁移或驱动程序作为组件的项目,这可能会创建一个传递依赖项。

风险和缓解措施

解决方案尚未完全定义,在此过程中可能会出现其他风险。

目前,主要风险似乎与时间安排在预期范围内;结构化配置能否及时准备就绪,以满足首批客户的需求?在商定技术解决方案后,通过向项目添加更多人员可以部分缓解这种风险。