RFC-0212:软件包集 | |
---|---|
状态 | 已接受 |
区域 |
|
说明 | 针对 Fuchsia 上的软件包集的定义和菜单提出了一系列更改 |
问题 | |
Gerrit 更改 | |
作者 | |
审核人 | |
提交日期(年-月-日) | 2022-11-17 |
审核日期(年-月-日) | 2023-03-07 |
摘要
此 RFC 为“软件包集”一词提供了官方定义,并提出了更新后的软件包集框架。此框架根据软件包集提供和适用的可用性和版本控制来表达软件包集:
- 三个现有软件包集
- 之前未与软件包集集成且已完成的软件交付工作
- 新的软件包集,可根据产品的要求更灵活地分发 Fuchsia 软件。
设计初衷
套餐是 Fuchsia 上软件分发的单位。 软件包用于交付平台软件和产品软件,还用于各种不同的测试和开发工作流。
每个 Fuchsia 产品都混合使用产品专用软件包和平台提供的软件包;这种混合内容因产品而异。产品使用的所有软件包都不需要同时交付或使用相同的策略进行更新。例如,某些软件包可能会作为无线更新的一部分进行下载,而其他软件包可能需要用户执行某些操作才能下载。
“软件包集”是指产品使用的软件包集合,其中集合中的所有软件包均采用相同的策略进行传送和更新。Fuchsia 目前使用三种不同的软件包集:base、cache 和 universe。
由于以下几点原因,Fuchsia 上软件包集的当前状态不够完善:
- “软件包集”一词未明确定义。
- 现有的软件包集尚未明确定义,而且从其名称无法看出它们提供的行为。在不同情境中重复使用相同的术语,但具有不同的含义。例如,设备存储在其软件包缓存中的软件包集与“缓存”软件包集不同。
- 现有的软件包集尚未更新,无法反映近期的软件提交 RFC,例如提前打包更新、子软件包或bootfs 软件包。
- 现有的软件包集无法满足一些产品开发者的需求。例如:
- 当磁盘可用空间有限时,应能够推迟提取非必需软件包。
- 应能够独立于平台更新产品软件(这在 RFC-0145 中进行了设计,但尚未纳入软件包集定义中)。
- 在开发过程中,应能够快速可靠地更新软件包。
此 RFC 旨在实现以下目标:
- 明确定义“软件包集”一词。
- 定义可能的软件包集定义所在的设计空间。
- 说明现有软件包概念在该设计空间中的适用位置,并据此优化用于引用这些概念的名称。
- 找出设计空间中应由未来 RFC 中的设计填补的空白。
- 确定不再需要且应废弃的现有概念。
利益相关方
教员:
- abarth
审核者:
- wittrock (SWD)
- amituttam(项目经理)
- aaronwood(软件装配)
- markdittmer(安全团队)
- sethladd (DX)
- marvinpaul(服务器基础架构)
咨询了:
- yaar, senj, etrylezaar, galbanum, richkadel
社交:
软件交付团队内部进行了一系列设计讨论,讨论了促成此 RFC 的工作。此 RFC 文本的早期版本已交由软件组装、服务器基础架构、第一方产品和 PM 团队的利益相关方进行审核。
定义
-
软件包是指清单、元数据、零个或多个可执行文件(例如组件)和资源等文件的集合。“软件包”一词既可以指此类集合的定义(例如,由其构建规则定义的 Timekeeper 软件包),也可以指根据该定义生成的单个工件(例如,2022 年 11 月 14 日构建的 Timekeeper 软件包,其 Merkle 根为
de07b9f06ae01181b0536b61c7f643496025598c3a2908dca5c72fce191be5d1
)。在本 RFC 中,我们仅使用前一种含义。 - 软件包版本 - 特定软件包的单个实例(例如,2022 年 11 月 14 日构建的 Timekeeper 软件包,其 Merkle 根为
de07b9f06ae01181b0536b61c7f643496025598c3a2908dca5c72fce191be5d1
)。Fuchsia 目前不需要为软件包版本编号(甚至不需要对其进行排序)。某些提前更新软件包的 CUP 元数据可能包含在回退检查中使用的有序版本号,如 RFC-0145 中所定义。 - 产品定义了 build 将生成的软件配置。最重要的是,产品通常会定义提供的用户体验类型,例如用户可能会看到什么类型的图形界面、是否包含多媒体支持等。
- 产品 build - 特定产品的已组装系统的单个版本。产品 build 是根据产品定义的规范生成的工件。例如“Workstation 8.20220622.2.1”。
- 产品版本 - 已推送到更新渠道的产品 build。
- 软件包集 - 请参阅下文。
- 版本控制权威 - 用于确定 Fuchsia 设备应使用哪个软件包版本的服务器或代码库。在生产系统中,Omaha 充当版本控制权威,而在开发期间,主机上的 TUF 代码库充当版本控制权威。
- Base(以前称为“单体”)- 在本 RFC 之前定义的软件包集。基准软件包集的内容始终存在于设备上,其版本由产品版本固定。此 RFC 提议保留基础软件包集。
- 缓存(以前称为“预安装”)- 在本 RFC 之前定义的软件包集。在几乎所有情况下,缓存软件包集的内容都会存在于设备上,但在本地开发期间,版本在某些情况下可能会更新。此软件包集不用于生产环境。此 RFC 建议创建一个以开发者为中心的新流程来替换缓存软件包集。
- Universe(以前称为“available”)- 在本 RFC 之前定义的软件包集。系统会使用版本控制机构确定的版本,按需下载该通用软件包集的内容。此软件包集目前不用于生产环境。“宇宙”一词既可指此软件包集的内容,也可指所有软件包集的内容。为避免混淆,此 RFC 建议将“universe”软件包集重命名为“可检测”。
- 提前更新 - 一种独立于产品版本更新软件包的机制,如 RFC-0145 中所定义。
- Bootfs 软件包 - 存储在 bootfs 文件系统中的软件包,如 RFC-0167 中所定义。
- 子软件包 - 某个软件包引用并与某个其他软件包以原子方式提取的软件包,如 RFC-0154 中所定义。
- 父级软件包 - 引用子软件包的软件包,如 RFC-0154 中所定义。
- 垃圾回收 - 在不再需要软件包内容时从 blobfs 中移除这些内容的过程。
- 系统更新(也称为“OTA”)- 将 Fuchsia 设备从一个产品版本更新到另一个产品版本的过程。
设计
文件包集
软件包集是指一组软件包,其中软件包集中的所有软件包均采用相同的策略进行分发和更新。例如,在基本软件包集中,系统会在更新期间提取所有软件包,并且提取的版本由产品版本决定。每当设备运行时,此基础软件包集中的软件包都保证存在于设备上。
文件包集的内容由产品定义。某个软件包可能出现在产品 A 的一个软件包集中,但出现在产品 B 的另一个软件包集中(或完全省略)。软件包所在的软件包集反映了软件包与使用它的产品之间的关系;对产品操作至关重要的软件包应放置在软件包集中,以确保这些软件包始终存在于设备上。通常,对于给定商品,一个软件包只会存在于一个软件包集中,但在某些情况下,一个软件包可能会存在于多个软件包集中。
“软件包集”有几个相关但略有不同的定义,这些定义的演变取决于该术语的使用上下文。下面介绍了其中一些,以及可用于明确引用定义的名称。
- 符合条件的软件包集 - 设备允许解析的一组软件包。例如,“符合条件的基准软件包集”是指设备能够成功解析并放入其所交付的基准软件包集中的所有软件包。
- 已构建的软件包集(也称为 build 依赖项集)- 构建 Fuchsia 产品时生成的一组软件包。构建的软件包集通常等于相应的符合条件的软件包集,但在某些情况下,它可能会小得多。例如,某部设备可能有数千个符合条件的通用软件包,但某个 build 可能不会生成其中任何一个。
- 已传送的软件包集 - 一组已传送到设备的软件包。已提交的软件包集是相应符合条件的软件包集的子集。
本文档的其余部分将重点介绍软件交付系统的设计,以及“符合条件的软件包集”定义。
拟议的设计空间
软件交付系统可解答以下两个关键问题:
- 是什么决定了软件包的版本?
- 软件包何时可在设备上使用?
本 RFC 提出了一个二维设计空间,用于根据这两个问题对软件包集进行分类,如下图所示:
请注意,在这两种情况下,都没有唯一的“最佳”答案;每个轴都代表两种理想属性之间的权衡。对于某些用例,轴的一端可能最适合,而对于其他用例,则是另一端更适合。
轴 1 - 版本控制
确定软件包的当前正确版本对于系统的安全性和可更新性至关重要。如需发布新功能和修复 bug,必须更改软件包的版本,但如果有权选择软件包版本的实体遭到入侵,则可能会被用于部署不当或恶意版本的软件。频繁更改软件包版本通常会涉及运行不太成熟的软件,或者运行尚未一起测试的软件组合。
版本控制轴是高敏捷性和高确定性之间的权衡。例如:
- 系统的关键元素无需频繁更改,并且必须集中且严格控制。在这些情况下,最好将软件包的版本锁定为平台或产品版本。
- 最终用户应用可能会根据开发它们的组织的节奏而频繁变化。在这种情况下,发布商最好能够在不等待产品发布的情况下,向兼容的设备发布新版本。
- 每当代码发生更改时,开发者正在调试的组件可能会每隔几秒更改一次。在这些情况下,最好立即自动更新版本。
轴 2 - 库存状况
软件包用于在 Fuchsia 设备上启用一些实用功能,并且只有当它们存在于该设备上(并且已知正确无误)时,才能执行此操作。
可用性轴是高可用性与低资源利用率之间的权衡。例如:
- 系统的关键元素需要始终可用,即使网络不可用也是如此。在这些情况下,必须在可能使用该软件包的整个时间内存储该软件包。这意味着在更新期间同时存储软件包的旧版和新版。
- 产品体验中不太重要的部分可能不需要可用性保证。在这些情况下,最好先删除软件包的旧版本,然后再提取更新后的版本,以减少峰值存储需求。
- 某些最终用户应用可能仅在少数设备上使用。在这些情况下,最好仅在有迹象表明用户打算使用软件包时,通过提取软件包来消耗资源。
映射到现有概念
现有的软件包集和与软件包相关的 RFC 分为四个不同的版本控制类别:
- 软件包版本由产品固定:适用于 base 和 bootfs。
- 产品将特定软件包的版本控制委托给具有约束条件的版本控制权威:适用于提前更新的软件包。对于急切更新的软件包,产品版本可能会限制接受的最低版本。
- 产品将特定软件包的版本控制委托给没有约束条件的版本控制权威:适用于缓存软件包。
- 商品将网域中所有网址的版本控制委托给版本控制权威机构,且不受限制:适用于不在基础或缓存集中的 Universe 软件包。请注意,这是唯一一个商品版本未定义该套件中每个软件包是否存在的类别。
现有的软件包集和软件包相关 RFC 分为四个不同的可用性类别:
- 始终可用:适用于 base 和 bootfs。
- 几乎始终可用:适用于提前更新的软件包(指定回退版本时)和缓存软件包。在这些情况下,我们的目标是确保该软件包始终可用,但由于缓存软件包解析和垃圾回收算法的当前设计,在某些情况下,该软件包将不可用。
- 在系统更新后自动提取:适用于在未指定回退版本的情况下提前更新的软件包。在系统更新提交后,这些软件包会在一段时间后可用(前提是网络状况良好)。
- 按需提取:适用于不属于其他软件包集(例如 base)的通用软件包。在发出软件包解析请求后,这些软件包会在一段时间后可用(前提是网络状况良好)。
子软件包引用包含目标的内容哈希,因此子软件包遵循其父级软件包的版本控制类别。子软件包会与其父级软件包一起原子解析(如果没有用于解析父级软件包的上下文,则无法解析),因此子软件包会遵循其父级软件包的可用性。
总而言之,现有的软件包概念适合拟议的设计空间,如下图所示:
建议的更改
将现有软件包概念映射到此设计空间(如上所示)时,会立即发现几个问题:
- 现有概念未涵盖设计空间的大部分内容,这表明我们目前的软件包集无法为许多可能很有价值的用例提供解决方案。
- 缓存软件包和提前更新的软件包发挥着非常类似的作用。
- “几乎始终可用”软件包是不可取的,只因缓存软件包解析和垃圾回收算法存在问题而存在。
- 现有概念的名称不遵循一致的模式,在大多数情况下,这些名称并未暗示相应概念所占据的设计空间部分。
- 其中一些概念(例如,提前更新)并未定义为软件包集。
本文档提出了一系列更改,这些更改可共同解决这些问题,并使设计空间的覆盖范围更全面、更一致,如下图所示:
以下各部分将详细介绍每项变更。请注意,我们按打算启用它们的顺序介绍这些功能,但许多更改可以并行进行。如果更改相互依赖,文本中会讨论这种关系。
更改 1 - 为软件包集引入统一的命名法
在此 RFC 之前,软件包集的命名方式是使用单个字词。由于只有三个集合,并且它们沿着单个轴排列,因此这种做法可行,但即便如此,简短的名称还是会造成一些混淆。
此 RFC 建议使用简短的短语来描述软件包集提供的属性。每个词组包含一个术语来描述该软件包集的软件包可用性,另一个术语来描述该软件包集的软件包版本,如下表所定义:
播出信息 | 说明 |
永久 | 这些文件包适用于所有情况 |
自动 | 在磁盘空间和网络可用的情况下,系统会自动提取这些软件包 |
OnDemand | 只有当设备上的某个实体尝试使用这些软件包时,系统才会提取这些软件包 |
版本控制期限 | 说明 |
锚定 | 这些软件包的版本由产品版本设置。 |
可升级 | 产品版本会将对这些软件包的控制权委托给版本控制权威机构,并可选择性地附加限制条件(例如最低可接受版本)。 |
可检测到 | 产品版本不会定义此集合中的各个软件包,而是将控制权委托给网址网域的版本控制权威机构。 |
例如,没有回退的提前更新软件包将被完整地称为“自动可用性、可升级版本控制”软件包集的成员。如果上下文和含义明确,则可以缩写为“自动且可升级”。
在左下角部分,我们有两个具有相同版本控制和可用性行为的不同软件包集 - base 和 bootfs。我们将保留这些名称来指代这些软件包集,同时使用“永久可用、锚定版本控制”来指代它们共享的更常规行为。
在替换此软件包集之前,我们将保留现有的“cache”名称来引用缓存软件包集(请参阅更改 6)。
“universe”一词在 Fuchsia 中具有相互冲突的定义。原始定义是所有已构建软件包的集合,这与该术语的集合理论含义一致。如今,“universe”通常仅指已构建但未包含在其他软件包集中的软件包,即基础软件包不属于“universe”。此定义与该术语的集合论含义不一致。为避免混淆,在提及设计空间的右上角部分时,我们使用“可检测到”一词,而不是“宇宙”。
更改 2 - 废弃“cache”软件包集
缓存软件包集和具有回退的提前更新软件包是解决同一需求的两种不同解决方案:让版本控制服务器提供较新版本的软件包,同时确保某个版本的软件包始终可用,即使设备处于离线状态也是如此。
RFC-0145 中定义的“提前更新的软件包”可为此问题提供更稳健的解决方案:
- 与缓存软件包不同,服务器通信问题不会导致提前更新的软件包无法解析
- 与缓存软件包不同,如果设备处于离线状态,提前更新的软件包不会回滚到较低版本
缓存软件包目前仅用于开发者工作流,但由于上述问题和其他问题,它们并不非常适合这些用例。鉴于提前更新的软件包的优势,在生产流程中使用缓存软件包绝不是一个好主意。
我们将废弃缓存软件包的概念,这意味着 SWD 不会再投入资源来进一步改进该流程。在适当的替代方案部署并采用之前,我们不会移除该流程和开发者文档(请参阅更改 6)。
请注意,弃用缓存软件包并不意味着弃用同名“软件包缓存”组件。
更改 3 - 移除 RFC-0154 中的子软件包软件包集限制
RFC-0154 要求子软件包应放置在“与其父级相同的软件包集中”。随着我们引入新的软件包类别,这一要求将变得难以满足,因为这要求产品维护者在每组传递子软件包发生变化时都更新软件包集定义。
自 RFC-0154 以来的实现工作已放宽了相同软件包集约束条件,但此 RFC 正式移除了该约束条件。如上所述,子软件包仍遵循其父级软件包的可用性和版本控制(因此仍有效地表现为其父级软件包集的成员),但产品维护者不再需要独立将子软件包作为引用它们的软件包集的顶级成员包含在内。
安全审核工具用于验证产品的每个版本是否包含预期的一组软件包。用于此验证的金文件将以传递方式包含锚定版本软件包集中包含的所有子软件包。这样可确保向锚定版本软件包集添加子软件包或嵌套子软件包时,系统会进行人工审核。
更改 4 - 重新设计垃圾回收算法
Fuchsia 当前的软件包垃圾回收 (GC) 算法是在该计划的早期设计的,随着软件交付方式的演变,其扩展性不佳。即使在今天,我们也遇到了必要软件包被删除且不必要软件包被保留的失败模式。当前的 GC 算法无法处理引入新软件包集的情况。
我们将在不久的将来发布后续 RFC,其中包含可容纳更多软件包集的替代 GC 实现的要求和算法。
更改 5 - 设计自动锚定文件包集
在产品的每次发布期间,产品维护人员必须一起测试许多不同平台和产品软件包的固定版本,以确保它们正确集成。目前,产品要包含固定版本的软件包,唯一的方法就是将其包含在基本软件包集中。这意味着,在系统更新期间,可能需要将所有这些软件包的两个副本同时存储在磁盘上,这使得在存储空间有限的设备上运行 Fuchsia 变得非常困难。
此问题可通过实现自动可用性锚定版本软件包集来解决,即支持版本由产品固定的软件包,但只有在系统更新成功提交后才会下载。我们将在不久的将来发布此软件包集的设计,作为后续 RFC 发布。
更改 6 - 设计以开发者为中心的替换软件包传送流程
如上文更改 2 中所述,缓存软件包流程不适合开发者在开发过程中轻松、快速且可靠地更新软件包的需求。我们将着重研究开发者需求,以便研究出更好的解决方案,然后以后续 RFC 的形式发布设计。
我们预计,我们讨论的这项以开发者为中心的新流程将作为工程 build 中的设计空间叠加层,但我们将在后续的 RFC 中进一步探讨这一点。
更改 7 - 设计按需锚定和/或按需可升级的软件包集
借助这些软件包集,产品维护人员可以定义具有固定版本或受限版本的软件包,这些版本在需要时才会提取。
这些软件包集可能对未来的产品有用,但与更改 5 中的自动锚定软件包集不同,我们尚未有发布客户。
当出现特定产品或开发者需求时,我们会设计和实现这两种软件包集或其中一种。
总结
完成这些更改(包括提议的后续 RFC)后,软件交付堆栈将为产品开发者提供更大的灵活性。例如:
- 通过将非必需软件包从基础软件包集移至自动锚定软件包集或按需锚定软件包集,产品将能够在不失去版本控制的情况下降低资源利用率。
- 产品将能够包含可使用可升级的软件包集独立于产品进行升级的软件包。
- 产品将能够控制这些可升级软件包的可用性。这包括将它们放入永久且可升级的软件包集中,以使其始终可用。
- 这些可升级软件包可能会引用在构建产品版本时产品版本不认识的其他软件包。
- 这可以通过子软件包实现,其中父级软件包设置了被引用软件包的版本;也可以通过可检测到的软件包集中的网址实现,其中版本控制权威机构设置了被引用软件包的版本。
- 这些被引用软件包的可用性遵循引用软件包(如果引用的是子软件包)或由引用软件包控制(如果引用的是可检测软件包)。
- 通过启用可检测到的软件包集,产品可以使用在产品版本中未明确定义的软件包。
- 在所有情况下,软件包只能从产品信任的代码库中提取。
- 软件分发功能将管理可用的 blob 存储空间,确保在需要执行系统更新时驱逐非关键软件包,并在有空间时自动提取自动软件包。
- 开发者将能够轻松更新他们在开发过程中需要修改的软件包。
此 RFC 中所述的变更对 SWD 堆栈中的假设也有重大影响。例如:
- 需要在软件包缓存中存储多个版本的软件包。可升级的软件包可能包含对产品已在其锚定集合中包含的软件包的子软件包引用。由于产品和可升级软件包彼此不知道对方的版本方案,因此无法协调以确保此公共软件包在二者中的版本相同。同样,同一可升级软件包集中的不同软件包可能包含对同一软件包的子软件包引用,但版本不同。
- 软件包缓存中的软件包必须支持多个软件包集。如上所述,可升级的软件包可能包含对产品已包含的软件包的子软件包引用。有时,这两个软件包集中的此软件包版本相同。在决定何时移除软件包时,必须考虑该软件包支持的所有软件包集。
- 需要协调软件包提取和垃圾回收。可升级软件包集和自动软件包集都表示系统会在系统更新流程之外提取新软件包版本。只有在有足够的 blob 存储空间可用时,这些操作才能成功。在某些情况下,由于没有可用空间,可能需要推迟或取消这些操作;在另一些情况下,可能需要驱逐其他软件包,以便操作成功。
- 软件包解析器与软件包集之间的关系将发生变化。目前,基础软件包解析器和宇宙软件包解析器与同名软件包集之间存在松散关联,但这种关联并不精确,在某些情况下,一个解析器会用于解析要解析的其他软件包集。这种关联无法扩展到包含更复杂关系的更多软件包集,并且我们不会为本 RFC 中讨论的新软件包集添加其他软件包解析器。未来,软件包解析器的选择和命名将成为软件交付堆栈的实现细节,让我们能够将与确定软件包版本相关的工作与与确保其可用性相关的工作分离开来。
- 可执行性强制执行机制可能需要更改。目前,只有基本软件包的内容在正式版中是可执行的;这意味着,简单的控制可执行性的机制就足够了。未来,每个软件包集中的软件包内容(以及它们引用的子软件包)都可能需要是可执行的。这可能需要更复杂的违规处置机制。
实现
此 RFC 的初始实现将主要涉及文档更改,下文会对此进行详细介绍。此 RFC 不会更改最常用的软件包集(即 base、bootfs 和 cache)的名称。我们会在有机会时,在源代码和工具中将对“universe”的引用更新为“可检测”。如果已废弃的源代码和工具使用了“universe”一词,我们通常不会更新这些引用。
建议的更改 4、5 和 6 需要后续 RFC,这些 RFC 将记录所引入更改的实现。
性能
从长远来看,此 RFC 将缩减基础软件包集的大小,目前位于基础软件包集中的部分软件包将迁移到资源要求更低的较新软件包集。从长远来看,这将改进多个性能指标,尤其是磁盘和网络利用率。
如果商品选择将软件包从可永久下载的软件包集中移至可自动下载或按需下载的软件包集中,则解析软件包的延迟时间可能会增加。
安全注意事项
我们认为,此 RFC 的净安全影响是积极的:
- 此 RFC 正式定义了可升级的软件包集。可升级的软件包集可让产品更轻松地更新某些软件包以修补安全漏洞
- 此 RFC 可在软件包之间建立更清晰的关系,从而更轻松地推理软件交付行为。这可能会导致长期安全性提高,但这种改进很难量化。
- 建议的更改 3 中对子软件包使用限制的放宽需要由安全团队进行分析。
隐私注意事项
我们认为,此 RFC 对隐私权的净影响为中性:
- 此 RFC 可让您更轻松地定义在用户执行某些操作之前不会下载的软件包,从而更轻松地将网络流量与用户行为相关联
- 此 RFC 可让产品更轻松地更新产品软件版本,从而更轻松地修补隐私漏洞
- 受此 RFC 影响的软件交付组件不会直接处理用户数据
测试
建议的更改 4、5 和 6 需要后续 RFC,这些 RFC 将记录所引入更改的测试。
文档
接受此 RFC 后,我们将:
- 为“软件包集”“基础软件包”以及每个版本控制和可用性类别添加了术语表条目。
- 更新了软件包的术语表条目
- 更新了概念中的软件包部分
- 更新了 IDK 中的软件包页面
- 更新了入门指南中关于商品包的页面
缺点、替代方案和未知情况
缺点 1 - 名称更改
RFC 对通用软件包和提前更新的软件包的命名进行了更改。任何命名更改都会给开发者带来一些困惑,但许多开发者之前并未使用这些术语,而且使用也不一致。我们认为,逻辑清晰且自洽的名称在长期可用性方面优于更名带来的混淆。
方案 1 - 允许有保证的和/或可自动发现的软件包
上文中的建议的更改部分将设计空间的右下角标记为“不适用”。我们之所以不支持这种组合,是因为我们认为这种组合不合逻辑:为了保证某个软件包可自动加载或自动加载,必须由产品版本明确指定,此时该软件包必须符合可纳入可升级软件包集的条件。