RFC-0212:软件包集

RFC-0212:软件包集
状态已接受
领域
  • 软件交付
说明

提议对 Fuchsia 上软件包集的定义和菜单进行一系列更改

问题
Gerrit 更改
作者
审核人
提交日期(年-月-日)2022-11-17
审核日期(年-月-日)2023-03-07

摘要

此 RFC 提供了“软件包集”一词的官方定义,并提出了一个经过更新的软件包集框架。此框架从软件包提供的可用性和版本控制方面来表达软件包集,并支持:

  • 三个现有软件包集
  • 之前未与软件包集集成的早期软件交付工作
  • 新的软件包集,便于根据产品的要求更灵活地交付 Fuchsia 软件。

设计初衷

软件包 则会 软件包用于提供平台软件和产品软件,还可用于一系列不同的测试和开发工作流。

每种 Fuchsia 产品都混合使用特定产品的软件包和平台提供的软件包;这种组合的内容因产品而异。并非产品使用的所有软件包都需要同时提交或使用同一策略进行更新。例如,某些软件包可能会作为无线下载更新的一部分进行下载,而其他软件包可能在用户执行操作后才能下载。

“软件包集”是产品使用的一系列软件包,此集合中的所有软件包都使用同一策略传送和更新。Fuchsia 目前使用的是三种不同的软件包集:base、cache 和 universe。

Fuchsia 上软件包集的当前状态不足,原因如下:

  • “软件包集”这一术语尚未明确定义。
  • 现有的软件包集尚未明确定义,而且从名称来看,它们提供的行为也并不明显。相同的术语在不同上下文中以不同的含义重复使用。例如,设备存储在其软件包缓存中的这组软件包与“缓存”软件包集不同。
  • 现有的软件包集尚未更新,以反映最新的软件交付 RFC,例如“即刻更新软件包”子软件包bootfs 软件包
  • 现有的软件包集无法满足多个产品开发者的需求。例如:
    • 当磁盘空间有限时,应该可以延迟提取非必需软件包。
    • 应该可以独立于平台更新产品软件(这是在 RFC-0145 中设计的,但未包含在软件包集定义中)。
    • 在开发过程中应该能够快速可靠地更新软件包。

此 RFC 旨在实现以下目的:

  • 明确定义“软件包集”一词。
  • 定义潜在的软件包集定义所在的设计空间。
  • 说明现有软件包概念适合此设计领域的什么位置,并根据这一点优化我们用于指代这些概念的名称。
  • 确定设计空间中应由未来的 RFC 来填补的空白。
  • 确定不再需要且应废弃的现有概念。

利益相关方

教员

  • 阿巴斯

审核者

  • Wittrock(南达科他州)
  • 阿米图坦 (PM)
  • aaronwood(软件组装)
  • Markdittmer(安全)
  • Sethladd (DX)
  • marvinpaul(服务器基础架构)

咨询人员

  • yaar、senj、Etrylezaar、galbanum、richkadel

社交

我们在软件交付团队内部的一系列设计讨论中讨论了促成此 RFC 的工作。此 RFC 中文本的早期版本已经与软件组装、服务器基础架构、第一方产品和 PM 团队的利益相关方一起进行了审核。

定义

  • 软件包是文件的集合,例如清单、元数据、零个或多个可执行文件(例如组件)和资产。“package”一词既用于表示此类集合的定义(例如,根据其构建规则定义的 Timekeeper 软件包),也用于表示根据该定义生成的单个工件(例如,2022 年 11 月 14 日构建的 Timekeeper 软件包,其 Merkle 根为 de07b9f06ae01181b0536b61c7f643496025598c3a2908dca5c72fce191be5d1)。在此 RFC 中,我们仅使用前一种含义。
  • Package version - 特定软件包的单个实例(例如,2022 年 11 月 14 日构建的 Timekeeper 软件包,且 Merkle 根为 de07b9f06ae01181b0536b61c7f643496025598c3a2908dca5c72fce191be5d1)。Fuchsia 目前不要求对软件包版本进行编号(或均匀排序)。某些紧急更新软件包的 CUP 元数据可能包含回退检查中使用的有序版本号(如 RFC-0145 中所定义)。
  • 产品定义了 build 将生成的软件配置。最重要的是,产品通常会定义所提供的各种用户体验,例如用户可能观察到的图形 shell 类型、是否支持多媒体等等。
  • 产品 build - 特定产品的组装系统的单个版本。产品 build 是根据产品定义的规范生成的工件。例如“Workstation 8.20220622.2.1”。
  • 产品发布 - 已推送到更新渠道的产品 build。
  • 软件包集 - 详见下文
  • 版本控制授权 - 用于确定 Fuchsia 设备应使用哪个版本的软件包的服务器或代码库。在生产系统中,Omaha 充当版本控制授权机构,而在开发期间,主机上的 TUF 仓库充当版本控制授权机构。
  • 基础(最初称为“单体式应用”)- 在此 RFC 之前定义的软件包集。基础软件包集的内容始终存在于设备上,并且其版本已通过产品版本修复。此 RFC 建议保留基础软件包集。
  • 缓存(以前称为“预安装”)- 在本 RFC 之前定义的软件包集。几乎在所有情况下,设备上都会存在缓存软件包集的内容,但在某些情况下,本地开发期间版本可能会更新。此软件包集未用于生产环境。此 RFC 建议创建了一个以开发者为中心的新流程来替换缓存软件包集。
  • Universe(最初称为“可用”)- 此 RFC 之前定义的软件包集。Universe 软件包集的内容将根据版本管理机构确定的版本按需下载。此软件包集目前未用于生产环境。“universe”一词既指这个软件包集的内容,也指代所有软件包集的内容。为避免混淆,此 RFC 建议将 Universe 软件包重命名为“discoverable”。
  • 紧急更新 - 一种独立于产品版本更新软件包的机制,如 RFC-0145 中所定义。
  • Bootfs 软件包 - 存储在 bootfs 文件系统中的软件包(如 RFC-0167 中所定义)。
  • 子软件包 - 由 RFC-0154 中定义的一些其他软件包以原子方式引用并提取的软件包。
  • 父级软件包 - 引用 RFC-0154 中定义的子软件包的软件包。
  • 垃圾回收 - 从 blobfs 中移除不再需要软件包内容的过程。
  • 系统更新(也称为“OTA”)- 将 Fuchsia 设备从一个产品版本更新到另一个产品版本的过程。

设计

软件包集

软件包集是一个软件包的集合,该集合中的所有软件包都使用同一策略传送和更新。例如,在基础软件包集中,在系统更新期间,系统会以由产品版本确定的版本提取所有软件包。每当设备运行时,此基础软件包集中的软件包都一定会存在于设备上。

软件包集的内容由产品定义。特定软件包可能出现在产品 A 中的一个软件包中,而产品 B 中却是另一个软件包集(或完全省略)。放置软件包的软件包集反映软件包与使用该软件包的产品之间的关系;对产品运行至关重要的软件包应放置在软件包集中,以确保这些软件包始终存在于设备上。 通常情况下,一个软件包只会存在于某个给定产品的一个软件包集中,但在某些情况下,一个软件包可存在于多个软件包集中。

根据使用“软件包集”这一术语的上下文,“软件包集”的几个相关但略有不同的定义已发生了变化。我们在下面介绍其中的一些内容,以及可用于明确引用相关定义的名称。

  • 符合条件的软件包集 - 设备可以解析的一组软件包。例如,“符合条件的基础软件包集”是指设备可以成功解析并将其放入其提供的基础软件包集中的所有软件包的集合。
  • 已构建软件包集(也称为 build 依赖项集)- 构建 Fuchsia 产品时生成的一组软件包。构建的软件包集通常等于对应的符合条件的软件包集,但在某些情况下,它可能要小得多。例如,一台设备可能包含数千个符合条件的宇宙软件包,但 build 可能不会生成任何这些软件包。
  • 分发的软件包集 - 已交付到设备的一组软件包。分发的软件包集是对应的合格软件包集的子集。

本文档的其余部分将重点介绍软件交付系统的设计,以及“符合条件的软件包集”定义。

提议的设计空间

该软件交付系统回答两个关键问题:

  1. 哪些因素决定了软件包的版本?
  2. 设备何时提供包裹?

此 RFC 基于以下两个问题提出了一个二维设计空间,用于对软件包集进行分类,如下所示:

此图呈现了一个矩形设计空间,如以下小节所述。

请注意,在这两种情况下,不存在一个“最佳”答案;每个轴表示两个理想属性之间的平衡。对于某些用例,轴的一端可能最适合,而对于其他用例,频谱的另一端可能更合适。

轴 1 - 版本控制

确定软件包的当前正确版本对于系统的安全性和可更新性至关重要。若要发布新功能和修复 bug,必须更改软件包的版本。然而,如果有权选择软件包版本的实体遭到入侵,它可能会被用于部署不适当或恶意的软件版本。频繁更改软件包版本通常涉及运行不太成熟的软件或尚未一起测试的软件组合。

版本控制轴是高敏捷性和高确定性之间的平衡点。例如:

  • 系统的关键元素不需要频繁更改,必须进行集中、严格控制。在这些情况下,建议将软件包的版本锁定到平台或产品版本。
  • 最终用户应用可能会根据开发应用的组织的节奏频繁更改。在这些情况下,发布商最好立即将新版本发布到兼容设备上,而不是等待产品发布。
  • 每次更改代码时,开发者正在调试的组件可能每隔几秒就会更改一次。在这些情况下,我们希望版本立即自动更新。

轴 2 - 可用性

软件包的存在是为了在 Fuchsia 设备上实现一些实用功能,但仅当该设备上存在(并且已知是正确的)时,这些软件包才能执行此操作。

可用性轴是在高可用性与低资源利用率之间进行权衡。例如:

  • 系统的关键元素需要始终可用,即使网络不可用也是如此。在这些情况下,必须存储软件包的整个可能使用的时间。这意味着在更新期间同时存储软件包的先前版本和当前版本。
  • 产品体验中不太重要的部分可能不需要可用性保证。在这些情况下,最好先删除软件包的旧版本,然后再提取更新版本,以减少峰值存储需求。
  • 某些最终用户应用只能在一小部分设备上使用。在这些情况下,最好仅在有用户有意使用软件包的信号时通过提取软件包来消耗资源。

映射到现有概念

现有的软件包集和与软件包相关的 RFC 可分为四个不同的版本控制类别:

  1. 产品修复了软件包版本:适用于基础和 bootfs。
  2. 产品将特定软件包的版本控制委托给有限制的版本控制机构:适用于紧急更新的软件包。对于迅速更新的软件包,产品版本可能会限制可以接受的最低版本。
  3. 产品将特定软件包的版本控制委托给版本控制授权机构,而没有任何限制:适用于缓存软件包。
  4. 产品将某个网域中所有网址的版本控制委派给无约束条件的版本控制授权:适用于不在基本集或缓存集中的通用软件包。请注意,这是唯一一个产品版本未定义该集中是否存在每个软件包的类别。

现有的软件包集和与软件包相关的 RFC 划分为四个不同的可用性类别:

  1. 始终可用:适用于基础和 bootfs。
  2. 几乎始终可用:适用于紧急更新的软件包(指定了回退版本时)和缓存软件包。在这些情况下,我们的目标是始终提供软件包,但当前的缓存软件包解析和垃圾回收算法设计意味着在某些情况下软件包将不可用。
  3. 系统更新后自动提取:适用于未指定回退版本时紧急更新的软件包。这些软件包将在系统更新提交后的一段时间内可用,前提是网络状况良好。
  4. 按需提取:适用于未包含在其他软件包集(如基础版)中的宇宙软件包。这些软件包将在发出软件包解析请求后的一段时间内可用,前提是网络状况良好。

子软件包引用包含目标的内容哈希,因此子软件包遵循其父软件包的版本控制类别。子软件包与其父软件包以原子方式进行解析(由于没有上下文,因此子软件包无法解析父软件包),因此子软件包会遵循其父软件包的可用性。

总的来说,现有的软件包概念可满足提出的设计空间,如下图所示:

此图显示了矩形设计空间中的现有软件包概念,如上文所述。

建议的更改

将现有软件包概念映射到此设计空间(如上所示)时,几个问题会立即显现:

  1. 现有概念无法涵盖大部分设计空间,这表明我们当前的软件包集无法为许多可能很有价值的用例提供解决方案。
  2. 缓存软件包和紧急更新的软件包的作用非常相似。
  3. “几乎始终可用”的软件包并非必需,而只是因为缓存软件包解析和垃圾回收算法存在问题。
  4. 现有概念的名称没有遵循一致的模式,并且在大多数情况下,并不暗示该概念占用的设计空间。
  5. 有些概念(例如,即刻更新)未定义为软件包集。

此 RFC 提出了一系列更改,这些更改共同解决了这些问题,并使设计空间更全面且更一致,如下所示:

此图显示了使用现有软件包集以及本部分引入的新潜在软件包集填充的设计空间。

以下各部分更详细地介绍了各项更改。请注意,我们按照预期启动它们的顺序引入这些变化,但许多更改可以并行进行。文中讨论了各种变化之间的关系。

变更 1 - 为软件包集引入统一命名法

在此 RFC 之前,软件包集使用单个单词命名。这种方法是可行的,因为只有三个集合,并且它们沿一个轴排列,但即使是简洁的名称也导致了一些混淆。

此 RFC 建议通过一个短语来描述软件包集提供的属性,从而引用软件包集。每个短语都包含一个术语,用于描述该集中软件包的可用性,另一个术语用于描述该集中的软件包版本控制,如下表所示:

可用期限 说明
永久 这些软件包适用于所有情况
自动 在磁盘空间和网络可用性允许时,系统会自动提取这些软件包
OnDemand 仅当设备上的某个实体尝试使用这些软件包时,系统才会提取它们
版本编号术语 说明
锚定 这些软件包的版本由产品版本设定。
可升级 产品版本将控制权委托给其中每个软件包的版本控制授权机构,可以选择性地施加限制(例如可接受的最低版本)。
可检测到 产品版本不会定义此集中的各个软件包,而是将控制权委托给网址网域的版本控制机构。

例如,没有回退机制的紧急更新软件包可完全称为“自动可用性、可升级的版本控制”软件包集的成员。在上下文和含义明确的情况下,可以将其缩写为“自动且可升级”。

在左下角细分中,我们有两个具有相同版本控制和可用性行为的不同软件包集:base 和 bootfs。我们将保留这些名称来引用这些软件包集,同时利用“永久可用性、锚定版本控制”来指代它们共有的更常规行为。

我们将保留现有的“缓存”名称来引用缓存软件包集,直到此缓存软件包集被替换(请参阅变更 6)。

在 Fuchsia,“宇宙”一词的定义可能相互冲突。原始定义是所有已构建软件包的集合,这与术语的集合理论含义一致。如今,更常见的“宇宙”仅指构建后未包含在其他软件包集中的软件包,即基础软件包不是宇宙的一部分。这一定义与该术语的集合理论含义不符。为了避免这种混淆,我们在引用设计空间的右上角时使用“可发现”而不是“宇宙”。

更改 2 - 弃用“缓存”软件包集

Cache 软件包集和带有回退机制的紧急更新软件包是可以满足同一需求的两种不同解决方案:让版本控制服务器提供软件包的较新版本,同时确保即使设备处于离线状态,软件包的某个版本也仍然可用。

RFC-0145 中定义的即时更新的软件包为此问题提供了更可靠的解决方案:

  • 与缓存软件包不同,服务器通信问题不会导致紧急更新软件包解析失败
  • 与缓存软件包不同,如果设备离线,急切更新的软件包不会还原到之前的版本

缓存包目前仅在开发者流程中使用,但(由于上述问题和其他问题)并非非常适合这些用例。鉴于即时更新软件包的优点,绝不希望在生产流程中使用缓存软件包。

我们将废弃缓存软件包概念,这意味着 SWD 将不会投资于进一步改进该流程。在部署并采用合适的替代方案之前,我们不会移除该流程或开发者文档(请参阅变更 6)。

请注意,弃用缓存软件包并不意味着弃用名称相似的“软件包缓存”组件。

变更 3 - 移除了 RFC-0154 中的子软件包集限制

RFC-0154 要求将子软件包放置在与其父级相同的软件包集中。随着我们推出新的软件包类别,这项要求将变得难以满足,因为它要求产品维护人员在每次传递子软件包集发生更改时更新软件包集定义。

自 RFC-0154 以来的实现工作已经放宽了同一软件包集限制条件,但此 RFC 已正式将其移除。如上所述,子软件包仍然遵循其父级软件包的可用性和版本控制(因此仍可作为其父级软件包集的成员有效运作),但产品维护人员不再需要单独添加子软件包作为引用它们的软件包集的顶级成员。

安全审核工具用于验证产品的每个版本是否都包含预期的软件包集。用于此验证的黄金文件将以传递方式包含锚定版本软件包集中包含的所有子软件包。这样可以确保向锚定版本软件包集添加子软件包或嵌套子软件包时,一律都会接受人工审核。

变更 4 - 重新设计垃圾回收算法

Fuchsia 当前的软件包垃圾回收 (GC) 算法是在计划早期设计的,并且未随着软件交付的演变而扩展。如今,我们会遇到以下情况的故障模式:必要的软件包被删除,并保留不必要的软件包。当前的 GC 算法不足以应对引入新的软件包集。

不久之后,我们将发布替换 GC 实现的要求和算法,以便在后续 RFC 中容纳更多软件包集。

变更 5 - 设计自动的锚定软件包集

在每个产品发布期间,产品维护人员必须一起测试许多不同平台和产品软件包的固定版本,以确保它们正确集成。目前,要让产品包含某个软件包的固定版本,唯一的方法就是将其纳入基础软件包集中。这意味着,在系统更新期间,可能需要将所有这些软件包的两个副本同时存储在磁盘上,这使得在存储空间有限的设备上运行 Fuchsia 变得非常困难。

此问题可以通过实现自动可用性的锚定版本软件包集来解决,即版本已由产品修复但直到成功提交系统更新后才下载的支持软件包。我们会在不久的将来发布此软件包的设计,并将其设置为后续 RFC。

变更 6 - 设计以开发者为中心的替代软件包交付流程

如上面的变更 2 中所述,缓存软件包流程不太适合在开发过程中需要轻松、快速、可靠地更新软件包的开发者。我们将专注于开发者需求来研究更好的解决方案,然后将设计作为后续 RFC 发布。

我们预计这一以开发者为中心的新流程在工程 build 中充当设计空间的叠加层,但在后续 RFC 中将会进一步探索。

变更 7 - 设计按需锚定和/或按需升级的软件包集

借助这些软件包集,产品维护者可以定义具有固定版本或受限版本的软件包,此类版本只有在需要时才提取。

这些软件包集可能对未来的产品有用,但与变更 5 中设置的自动软件包和锚定软件包不同,我们目前还没有发布客户。

如果出现特定产品或开发者需求,我们将设计和实现其中一个或两个软件包集。

总结

完成这些更改(包括建议的后续 RFC)后,软件交付堆栈将为产品开发者提供显著更高的灵活性。例如:

  • 通过将非必需软件包从基础软件包移到自动和锚定或按需和锚定软件包集,产品将能够在不失去对版本控制的控制的情况下降低资源利用率。
  • 产品将能够包含可使用可升级软件包集单独升级的软件包。
    • 产品将能够控制这些可升级软件包的可用性。这包括将它们置于可升级的永久软件包集中,以使其始终可用。
    • 这些可升级的软件包可以引用构建产品版本时不知道的其他软件包。
      • 这可以通过子软件包实现(父软件包设置引荐软件包的版本),或使用可发现软件包集中的网址(由版本控制授权方设置引荐软件包的版本)。
      • 这些引荐软件包的可用性遵循引荐软件包(在引用子软件包的情况下)或由引荐软件包控制(如果引用可发现软件包)。
  • 通过启用可检测到的软件包集,产品可以使用产品版本中未明确定义的软件包。
  • 在所有情况下,软件包都只能从产品信任的代码库中提取。
  • 软件交付将管理可用的 blob 存储空间,以确保在执行系统更新时需要逐出非关键软件包,并在有可用空间时自动提取自动软件包。
  • 开发者将能够轻松更新他们在开发期间需要修改的软件包。

此 RFC 中描述的更改也会对 SWD 堆栈内的假设产生重大影响。例如:

  • 您需要在软件包缓存中存储多个软件包版本。可升级的软件包可能会包含一个子软件包引用,该子软件包引用的是产品已包含在其锚定集中的软件包。由于产品和可升级软件包彼此不了解彼此的版本控制方案,因此它们无法进行协调,以确保这两个通用软件包的版本相同。同样,同一可升级软件包集中的不同软件包可能包含对同一软件包但位于不同版本的子软件包引用。
  • 软件包缓存中的软件包必须支持多个软件包集。如上所述,可升级的软件包可能包含对产品已包含的软件包的引用。有时,此软件包在两个软件包集中的版本相同。在决定何时移除软件包时,必须考虑软件包支持的所有软件包集。
  • 软件包提取和垃圾回收需要进行协调。可升级的软件包和自动软件包设置都意味着,系统将在系统更新过程之外提取新的软件包版本。仅当有足够的 blob 存储空间时,这些操作才能成功。在某些情况下,由于空间不足,可能需要推迟或取消这些操作;在其他情况下,您可能需要逐出其他软件包才能成功执行操作。
  • 软件包解析器和软件包集之间的关系将发生变化。目前,基础软件包和全局软件包解析器与同名软件包集之间存在松散的关联,但这种关联并不精确,在某些情况下,系统会使用一个解析器解析目标为另一个软件包集的软件包。这种关联关系不会扩展到包含更复杂关系的大量软件包集,我们也不会为此 RFC 中讨论的新软件包集添加其他软件包解析器。将来,软件包解析器的选择和命名将成为软件交付堆栈的实现细节,这样一来,我们将与确定软件包版本相关的工作与确保其可用性相关的工作分离开来。
  • 可执行性强制执行机制可能需要更改。在当今的正式版中,只有基础软件包的内容可执行;这意味着,用于控制可执行文件的简单机制已经足够。将来,每个软件包集(及其引用的子软件包)中的软件包内容都必须是可执行文件。这可能需要更复杂的强制执行机制。

实现

此 RFC 的初始实现主要是文档变更,下文更详细地进行了介绍。此 RFC 不会更改最常用的软件包集(即 base、bootfs 和 cache)的名称。随着机会出现,我们会在源代码和工具中将对“宇宙”的引用更新为“可发现”。如果已弃用的源代码和工具使用“全部”一词,我们通常不会更新这些引用。

建议的变更 4、5 和 6 需要后续的 RFC,这些 RFC 将记录其引入的变更的实现。

性能

从长远来看,此 RFC 将缩减基础软件包集的大小,一些目前的基础软件包将移至资源要求更低的较新软件包集。从长远来看,这将提高多个性能指标,尤其是磁盘和网络利用率。

如果产品选择将软件包从设置为永久可用的软件包迁移到自动或按需可用性的软件包,则解析软件包的延迟时间可能会增加。

安全注意事项

我们相信,此 RFC 对净安全的影响是积极的:

  • 此 RFC 正式定义了可升级的软件包集。通过可升级的软件包集,产品可以更轻松地更新某些软件包来修补安全漏洞
  • 此 RFC 在软件包之间建立了更清晰的关系,从而更轻松地推断软件交付行为。从长远来看,这可能会提高安全性,但这种提升很难量化。
  • 建议的变更 3 中放宽子软件包使用限制需要安全团队进行分析。

隐私注意事项

此 RFC 对隐私权的净影响一般不影响:

  • 此 RFC 可让您更轻松地定义在执行某些用户操作之前不会下载的软件包,从而更轻松地将网络流量与用户行为关联起来
  • 此 RFC 便于产品更新产品软件的版本,从而更轻松地修补隐私漏洞
  • 受此 RFC 影响的软件交付组件不会直接处理用户数据

测试

建议的变更 4、5 和 6 需要后续的 RFC,这些 RFC 也将记录对所引入变更的测试。

文档

接受此 RFC 后,我们将:

缺点、替代方案和问题

缺陷 1 - 名称更改

RFC 引入了对宇宙软件包和急切更新的软件包的命名法变更。任何命名更改都会给开发者带来一些困扰,但这些术语并未被很多开发者使用,而且以前也并非一直使用。我们认为,具有逻辑性和自一致性的名称的长期易用性将取代名称更改的困惑。

替代方案 1 - 允许有保证和/或自动检测到的文件包

上面的建议的更改部分将设计空间的右下角部分标记为“不适用”。我们不支持这种组合的原因在于,我们认为这种做法不合逻辑:为了让某个软件包自动进行保证或加载,必须由产品版本明确指定,届时该软件包符合纳入可升级软件包集的条件。

现有艺术和参考资料