RFC-0242:配置功能

RFC-0242:配置功能
状态已接受
领域
  • 组件框架
说明

向组件框架添加配置功能

Gerrit 更改
作者
审核人
提交日期(年-月-日)2024-02-05
审核日期(年-月-日)2024-04-11

摘要

简要介绍如何使用配置功能, 以及将添加到 CML 文件中以支持 。

需要注意的是,本文档取代了 配置 RFC,在先前技术部分中提及。

设计初衷

Fuchsia 中的组件使用结构化配置来获取 配置值如今,配置值大多是从 组件包。可以通过命令方式设置父组件 启动动态组件时所需的配置值, Fuchsia 是静态的。

添加此功能的动机有多种:

  • 允许静态父级配置子级的配置。
  • 将单个配置值路由到多个组件。
  • 通过 CML 文件提供配置值。

配置功能的第一位客户是系统组装,因为 功能将有助于消除技术债务。技术债务 原因是当前无法为静态 您还需要修改该组件包目前组装 打开 fuchsia 软件包,编辑其配置值文件,然后 对它们进行重新打包这是技术债务,因为它会改变 而配置值文件从技术上来讲是“私有”此 API 的 不容易进化的组件。

对于无法重新构建的树外软件包,配置功能 提供了一种配置这些组件的方法目前 可以在静态拓扑中修改这些组件的配置。

此功能在将来的许多配置用例中都很实用。

利益相关方

教员:neelsa@google.com

审核者

  • 系统组件:aaronwood@google.com
  • 组件框架:geb@google.com
  • 安全:markdittmer@google.com
  • 驱动程序框架:surajmalhotra@google.com
  • 组件框架:wittrock@google.com

社交化:已经与组件框架团队讨论过此问题 然后再撰写 RFC。

要求

借助配置功能,CML 作者可以设置 静态组件。它们允许通过 以便多个组件可以使用同一个值路由值 允许间接祖先实体指定值,其中 现有特征仅允许直接父级指定值。

配置功能应遵循现有的组件框架功能 以便与系统的其他部分保持一致

设计

该设计的大部分是用于声明和路由配置的 CML 语法 功能。在 CML。配置功能被路由到想要使用 。使用配置功能的组件将能够看到 使用现有的结构化 配置库

以下是定义配置功能的示例:

// Configuration capabilities can be defined in any component.
// When a configuration capability is defined, a value must be set for it.
capabilities: [
  {
    // Define the name of the capability.
    config: "fuchsia.netstack.UseNetstack3",
    // Define the type of the configuration.
    type: "bool",
    // When defining a configuration capability, there *must* be a value.
    // If the route for the configuration capability ends at this definition, the
    // value of the capability will always be this value.
    value: "true"
  },
  // The below shows a string config.
  {
      config: "fuchsia.config.MyString",
      type: "string",
      max_size: 100,
      value: "test",
  },
  // The below shows a vector config.
  {
      config: "fuchsia.config.MyUint8Vector",
      type: "vector",
      element: { type: "uint8" },
      max_count: 100,
      value: [1, 2, 3 ],
  },
]

config capability 中的 typeelementmax_countmax_size 字段 与其在 config 节中使用的含义相同。所有 capabilities 代码块中支持 config 节中支持的功能。

type 字段支持以下各项:

  • bool
  • uint8、uint16、uint32、uint64
  • int8、int16、int32、int64
  • string
  • 矢量

using 代码块支持相同的 typeelementmax_countmax_size 字段视为功能块。

以下是使用配置功能的示例语法:

// Using a configuration capability means that this configuration will show
// up in the component's structured config at runtime with the specified `key`
// name.
// NOTE: Using a configuration capability will override the value in the Config
// Value File (CVF) and the value obtained from the "mutability" setting.
use: [
  {
    config: "fuchsia.netstack.LaunchProcess",
    // This is the name that the component will see in its Structured Config
    // struct. If the `use` is optional this must match a name in the "config"
    // block of the component's manifest.
    key: "can_launch_process",
    // The using field needs the type information so that the component's
    // Config Value File format can be created.
    type: "bool",
    // From is identical to other capabilities.
    from: "parent",
  },
  // The below shows a vector config.
  {
    config: "fuchsia.netstack.MyUint8Vector",
    key: "my_vector",
    type: "vector",
    element: { type: "uint8" },
    max_count: 100,
    from: "parent",
  },
  // The below shows a string config.
  {
    config: "fuchsia.netstack.MyString",
    key: "my_string",
    type: "string",
    max_size: 256,
    from: "parent",
  },
]

以下是路由配置功能的示例语法:

// Expose and Offer behave the same as any other capability.
expose: [
  {
    config: "fuchsia.netstack.UseNetstack3",
    as: "fuchsia.mycomponent.UseVersion3",
    from: "self",
  },
]
offer: [
  {
    config: "fuchsia.config.MyString",
    as: "fuchsia.mycomponent.ProcessName",
    from: "self",
    to: "#mychild",
   },
]

可选功能

如果某个组件正在使用一项配置功能,并将可用性设置为 optional,并且从 void 路由该功能,然后组件 即可接收来自配置值文件 (CVF) 的值。此功能 以支持用于更新配置的软迁移。

弃用“config”屏蔽

在配置功能之前,配置字段是在 CML 中的 config 节。此信息现已替换为 在 use 节中返回。也就是说,结构化配置 为组件生成的架构将是该字段的并集 use 代码块和 config 节中的声明。

所有结构化配置客户端都迁移到配置后 功能,则将移除对 CML 中的 config 块的支持。

弃用“mutability: parent”功能

在配置 capability 之前,配置值可声明为 mutability: parent,以允许该组件的父级 更改该值。

此功能的用户将迁移至use一项配置功能 由家长提供待所有用户迁移完毕后,此功能将 已移除。

实现

这些 CML 功能的实现相对简单, 可以通过几个 CL 在树中完成。客户端可以改为使用 功能,因为这不会影响现有的结构化 配置功能

我们需要确保审查团队了解配置功能和 可以验证特定产品是否具有给定配置。

性能

由于组件框架的影响,组件的启动速度可能会稍慢一些 因此需要对组件使用的配置功能执行路由操作。 如果这些功能来自 未解决,需要下载。对于已解决的问题,此问题应该可以忽略不计 组件。

工效学设计

这一全新 CML 功能的工效学设计与现有 功能。添加和路由配置功能有点冗长 但其语法选择与现有 capability 语法尽可能一致 此外,在可能的情况下,语法还选择与现有的 config 块语法。当这两种语法发生冲突时,现有的 capability 语法。与现有语法匹配可降低认知能力 不需要您熟悉组件框架。

CF 团队可能会决定将 config 块保留为以下语句的语法糖: 或者添加额外的语法糖(如果我们 需要更好的人体工程学设计。

向后兼容性

这是一项新功能。它向后兼容现有的 配置功能

值得注意的是,将配置功能路由到组件 始终优先于 CVF 文件中的值。如果某个组件具有 可选的配置功能路由,并且该路由不存在,则 值。

安全注意事项

此功能应该不会影响安全性。审查和其他工具 调查 CML 将会开发这一新功能类型。

有人认为,以这种方式设置功能将更加显眼 与修改组件包中的值的现有策略相比。

如果某个组件使用了必需的配置功能,但没有 组件将无法启动。它不应是 因为组件的父级是可信的,而这些路由 可以进行静态验证,以确保其正确无误。

隐私注意事项

此方案对隐私没有任何影响。

测试

此功能需要单元测试和集成测试。常规测试领域 分别是:

  • 解析新的 CML 语法。
  • 通过拓扑路由新功能。
  • 尝试启动缺少配置功能的组件。
  • 尝试启动配置 capability 错误的组件 类型。
  • 启动具有配置功能的动态组件。

此功能需要向审查中添加以下测试:

  • 测试 Scrutiny 可以解析配置功能的值。
  • 测试不同配置值来源的优先级/替换逻辑。
  • 测试配置功能、配置块和 可变性。

这些测试都不需要新的测试基础架构。

文档

需要更新 Fuchsia.dev 以提供有关配置的文档 功能。现有功能文档将用作此实验的模板 新文档。

缺点、替代方案和未知问题

替代方案:实现配置替换服务

原图 结构化配置 RFC 建议结构化配置直接源于组件软件包。 RFC 规范明确指出,它不会试图解决 “其他组件(父级组件除外)设置的配置数据 和管理组件)的要求。另一种方法是继续不支持 基于功能的配置方案

使用配置功能而不替换覆盖的缺点之一 配置功能更详细、更复杂。 一开始,在全局范围内实施代码总是会更容易。 但 Fuchsia 发现,基于功能的系统最终 可组合且长远可理解。能够熟练运用这些技术 假设只有一部分组件使用了某个特定配置 或者在两个不同组件中使用两个不同的值。 配置功能使此功能更易于表达,并体现了 在 Fuchsia 的其他地方使用的基于功能的系统。使用现有的 CML 语法可以更轻松地 它能很好地与组件框架现有的 工具。

缺点:有很多额外的用途字段

将类型信息保留在 use 代码块中会额外添加 6 个字段 它们仅对配置功能有效。

您可以将这 6 个字段合并为一个包含子字段的字段, 但最好添加字段,因为这样可以保持语法 现有的 config 代码块语法。

缺点:会混淆类型信息和路由

将配置架构放在 use 声明中的一个缺点是 use 代码块定义了类型信息以及路由。 有些组件可能希望定义其配置,而不指定 然后在不同场景中以不同的方式路由其配置。 如果类型信息位于与“用途”标签不同的位置, 。

想要更改类型定义方式的组件作者必须修改 其 use 块,而不是仅修改其 config 块。

如果配置定义和路由的组合变为永久性 那么组件框架团队可能会再次 决策。

替代方案:将配置类型定义保留在 config 块中

一种替代方案是不指定“类型”字段放在 use 声明中,并将 而是依赖于现有“config”中的类型信息。这是 与此 RFC 的早期版本中的情况相同。此替代方案解决了 目前存在混淆类型信息和路由的缺点。它让您可以更轻松地 让客户端在一个位置定义配置,然后在另一个位置 (可能包含不同的 CML 分片,以便根据不同的路由条件 )。

在目前的基于结构化配置的实现中,组件 经理“推送”在启动组件时为其指定配置 管理器需要确保路由功能的类型与 target Structured Configuration 字段。有人认为,类型信息 会放在 use 声明中,因为它与 功能声明。在组件管理器执行路由时,它需要 请确保类型信息对齐,这意味着逻辑上 信息应包含在路线的两端(功能和用途)。

use 声明中保留类型信息的另一个原因是, 可以保留 use 声明中的所有信息,并且 不需要匹配的“config”禁止进入。这样就能确保 位于 CML 文件中的单个位置,这样更便于审核。

替代方案:use 声明中的 as 字段

封装结构化配置字段名称和类型信息 在 config 代码块中,as 可用于指定需要 功能。这与大多数非 path 国家/地区的情况一致 "重命名"是用 CML 语言完成的

之所以使用 key 字词,是因为该字段的运作方式不同于 其他 as 字段。as 通常是可选的,但 key 是必需的。key必须 也会匹配 config 块中的现有键(如果 capability 是可选的)。

未知:使用功能平衡现有的结构化配置不一致

可以通过多种方式将现有结构化配置 与其他功能的工作方式不一致。

其中一个不一致之处在于,程序高度依赖于 组件清单中定义的结构化配置。正常情况下 是依赖于该程序的清单,而结构化配置可让 形成这种关系从结构化的 配置构建规则要求在组件、 组件清单以及程序这种循环一致性不会 但还是应该能够解决 在后续的 RFC 中

另一个不一致性是结构化配置是“推送”的,添加到 组件启动后,其他功能会被“拉取”用作 组件访问它们。此不一致问题在 RFC。此 RFC 的目的是在 组件清单。此 RFC 不会更改程序之间的接口 和结构化配置,因此所需的迁移次数 受限。

在更新之后,Fuchsia 将能更好地解决这些不一致问题。 实现配置功能并了解其使用方式。更多 客户数据将帮助我们解决痛点并实施后续更改。

先验技术和参考资料

以前的结构化配置 rfc: