| RFC-0144:尺寸检查工具 | |
|---|---|
| 状态 | 已接受 |
| 区域 |
|
| 说明 | 建议重写 size_checker.go,以创建更具凝聚力的树内和树外开发者体验。 |
| 问题 | |
| Gerrit 更改 | |
| 作者 | |
| 审核人 | |
| 提交日期(年-月-日) | 2021-11-22 |
| 审核日期(年-月-日) | 2021-12-10 |
摘要
本文档建议开发一种将添加到 SDK 中的新大小检查工具,以便开发者和产品所有者验证其软件包和产品是否超出指定的大小预算。虽然有意省略了实现细节,因为树外 Assembly 会不断改变基础,但提到了设计要求和目标。
设计初衷
在软件开发过程中,了解软件是否符合目标的大小限制很有帮助。Fuchsia 有一个大小检查工具,可分析不同软件组占用的空间,并为每个组强制执行预算。此工具与 fuchsia.git 的实现细节紧密相关,因此必须先检出 fuchsia.git 才能使用。因此,Fuchsia 的消费者(例如 Chromium)已实现自己的临时方法来检查其软件的大小。通过将大小检查工具重写为 ffx 插件并将其添加到 Fuchsia SDK,Fuchsia 软件上强制执行大小预算的方法将得到统一,从而使未来的开发者能够更轻松地开始使用 Fuchsia。
利益相关方
谁会受到此 RFC 是否被接受的影响。
辅导员:
- Hunter Freyer (hjfreyer@google.com)
审核者:
- Saman Sami (samans@google.com) - 功能
- Anthony Fadrianto (atyfto@google.com) - 与基础设施集成
- Sébastien Marchand (sebmarchand@google.com) - 与基础架构的集成
- Rohan Pavone (rohpavone@google.com) - 与 Chromium 集成
- Amit Uttamchandani (amituttam@google.com) - 集成到 ffx 中
已咨询:
- Aaron Wood (aaronwood@google.com) - Assembly Integration
共同化:
该项目已作为内部文档进行宣传,并提前在与相关负责人的会议中进行了讨论。在起草此 RFC 之前,已收集了相关要求。
背景
此 RFC 假定读者了解以下主题。
两种大小检查
尺寸检查可分为两类:
- 刷写时,映像不会超过其目标分区大小。
- 在更新期间,Blob 符合 FVM 预算。
刷写:开发者可以将新映像刷写到 Fuchsia 目标设备上。刷写映像时,分区的内容会被新映像的字节完全替换。为确保刷写成功,新映像的大小不得大于分区的大小。
更新:Fuchsia 目标设备可以通过 OTA 方式进行更新。为确保成功更新,Blob 占用的总空间不得超过为 FVM 设置的预算。通常情况下,FVM 中的空间会预留给 UpdatePackage 和其他 blob,这意味着该工具无法简单地填充 FVM,然后检查最终映像是否适合分区。
当前工具
Fuchsia 提供了两种有助于检查大小的工具:
- size_checker.go
- blobfs-compression
size_checker.go
此工具可在树内(在 fuchsia.git 内)使用,以确保 blob 符合其预算。size_checker.go 通过确定 Fuchsia 代码库中 blob 目录的压缩大小和对齐大小来实现此目的。预算可以按产品定义,但目前不适用于 fuchsia.git 中的任何产品。由于该工具专门检查 fuchsia.git 中的目录,因此在未检出 fuchsia.git 的情况下无法使用。
首先,Fuchsia build 会生成一个 blobs.json 文件,其中列出了 blobfs 中每个 blob 的压缩大小和对齐大小;还会生成一个 blob.manifest 文件,其中列出了这些 blob 的 merkle 和源路径。
接下来,运行 size_checker.go 并执行以下操作:
- 读取
blobs.json以收集每个 blob 的压缩大小:compressed_size。 - 读取
blob.manifest以收集所有软件包。 - 计算 Blob 包含在软件包中的次数:
share_count。 - 计算每个 blob 的共享大小:
shared_size = compressed_size / share_count。由于多个预算可能包含同一 Blob,因此我们使用 Blob 的shared_size在各个预算之间均匀分配大小消耗。 - 通过将每个 blob 的
shared_size添加到 blob 路径中的节点,构建一个 N 元求和树,表示 build 输出中每个目录所占用的空间。 - 遍历每个预算,并断言为目录分配的预算大小大于消耗的空间。
- 遍历预算中的每个非 blobfs 软件包,使用
blobfs-compression计算 blob 大小的总和,并断言该总和在预算范围内。 - 打印结果。

blobfs-compression
此工具可以估算一组 blob 的压缩后大小和对齐后大小,但并非 100% 准确,有时可能会过高估计 blob 的大小。该工具绝不会低估 blob 的大小。
blobfs-compression 通过 Fuchsia SDK 交付给客户端,目前是 fuchsia.git 之外唯一可用于估算为 Fuchsia 构建的代码大小的方法。Chromium 是此工具的客户端。
当前工具存在的问题
- 用于检查软件包大小的 In-Tree 和 Out-Of-Tree 方法是不同的工具。
- 这两种工具都无法直接检查映像的大小,以确保刷写成功。
size_checker.go- 未记录。
- 取决于 Fuchsia build 的实现细节,而这并非稳定合约。
- 无法在树外运行。
blobfs-compression- 无法保证返回的 blob 压缩大小准确无误。
- 在 blob 级层运行,不如在软件包级层运行有用。开发者以软件包为单位向产品添加软件。
- 没有标准输出格式,因此不容易通过脚本实现自动化,自动化使用容易出错。
要求
- 在 SDK 中提供可在 In-Tree 和 Out-Of-Tree 中使用的工具。
- 相应工具支持当前工具的所有预期现有使用情形。
- 该工具可以执行两种类型的尺寸检查:
- (a) 图片
- (b) 一组软件包中的 blob
- 在情况 (2) 中,将对所有集中的所有软件包集执行 blob 重复数据删除。
- 当超出用户指定的预算时,相应工具会返回失败。
- 该工具可与其他 SDK 工具(例如 Image Assembler [RFC-0072])完美搭配使用。
- 该工具可轻松用于脚本中,具有可解析的输出,并生成 Gerrit Size Plugin 使用的输出。
- 工具的使用情况和架构将记录在 fuchsia.dev 中。
设计
一致的开发者体验
我们将使用 Rust 编写一个新的 ffx 插件,用于执行两种类型的尺寸检查。根据 CLI 评分准则,最好将其纳入 ffx 中,以鼓励共享工作流并提高可发现性。此外,我们更倾向于扩展现有文件格式,而不是发明新的文件格式。
可编写脚本
此工具主要用于构建系统,因此输出应可解析。输出格式可能会使用 json5 作为输出格式,但随着 Assembly 项目的进展,可能会考虑其他格式。
图片尺寸
图片大小检查器应与 flash 清单的构建同时运行,在其中将组装的图片映射到分区。目前,flash 清单创建是在 Fuchsia build 系统中完成的,因此 ffx 插件将通过 GN 操作进行调用。未来,我们可能会提供一个 SDK 工具来构建 flash 清单,并且作为 ffx 插件,我们的尺寸检查器工具应该可以在该场景中无缝运行。
测量图片大小非常简单,只需打开文件并读取元数据中的长度即可。此方法适用于任何未压缩或稀疏的图片。此方法不适用的一个示例是稀疏 FVM,由于目前没有用于计算稀疏 FVM 扩展大小的库,因此该工具将忽略对稀疏 FVM 的大小检查。
套餐规模
Blob 和软件包大小检查应与 Assembly 紧密集成,因为工程师正是在 Assembly 期间将软件包分组为集合,并组合这些集合来指定产品。
大小检查工具使用列出每个 blob 的压缩大小和对齐大小的 blobs.json 文件。开发者可以提供多个 blobs.json 文件作为该工具的输入。如果在任何提供的 blobs.json 文件中都找不到某个软件包的 blob,则大小检查工具将使用 blobfs 工具为所有缺失的 blob 生成单个 blobfs 映像,该工具会生成额外的 blobs.json。大小检查工具将读取生成的 blobs.json 以获取缺失 blob 的大小。
与现有的 size_checker.go 工具类似,新的大小检查工具将通过将每个 blob 的大小除以使用该 blob 的软件包数量来计算每个 blob 的共享大小。此共享规模是在制定预算时使用的规模。
实现
此工具的实现和集成将分几个阶段完成。
- 为软件包集声明预算。请参阅下面的说明。
- 编写一个 ffx 插件,确保软件包集在预算范围内
- 确保 ffx 插件的输出与之前作为 build 系统一部分的工具的输出相匹配。如果输出不同,则 build 应失败。请参阅下面的说明。
- 声明映像的预算
- 添加功能以确保图片大小在预算范围内
- 停用
size_checker.go并使新的 ffx 插件承担负载 - 删除
size_checker.go代码。
生成预算文件
为了避免维护给定产品的两组相同预算的繁琐工作,我们将更新 build 系统,以读取现有的 size_limits.json 和 assembly 产品配置,并生成新的预算文件。系统将解析产品配置以收集每个软件包清单,并根据 size_limits.json 中设置的目录预算对这些清单进行分类。
可能的预算文件格式为:
[
{
name: "name-of-package-set",
packages: [
"path/to/manifest1.json",
"path/to/manifest2.json",
],
budget_bytes: 12000,
},
]
一旦新的大小检查工具对 build 具有负载能力,生成的预算文件将被签入到代码库中,并且生成的代码将被删除。
输出比较
在过渡到新的大小检查器期间,构建系统将断言新工具的输出与新工具的输出一致。编写一个脚本,用于解析这两个工具的输出,并确保每个软件包组(或目录)的预算和计算出的消耗量是等效的。为了关联这两种输出格式,脚本将假定用于标识软件包集的名称是相同的。由于旧工具和新工具都使用相同的底层机制(使用 blobfs)来计算 blob 的大小,因此计算出的消耗量也将相同。
性能
大小检查工具旨在用于 build 系统,因此与网络堆栈相比,它对性能不稳定的容忍度更高。另一方面,缩短 build 时间对于提高开发者效率至关重要。此外,此工具位于 build 的关键路径上,因为它必须等待所有软件包构建完成并组装好映像后才能开始运行,因此无法并行化。
当前的 size_checker.go 工具大约需要 1-2 秒才能运行,而我们的新工具应力求达到相近的运行时间。
工效学设计
请参阅设计部分。
向后兼容性
此设计不需要向后兼容。
安全注意事项
此设计不涉及任何安全问题。
隐私注意事项
此设计不涉及任何隐私保护问题。
测试
在 Fuchsia build 中,新的大小检查工具将与 size_checker.go 一起运行,并比较输出结果,以确保它们具有相同的预算和计算出的空间消耗。
随着向工具添加功能,我们也会编写单元测试。
文档
文档将添加到 fuchsia.dev。
缺点、替代方案和未知因素
存在一些不利的替代方案。
不执行任何操作:这需要客户创建自己的临时方法来完成大小检查,但随着客户群的增加,这种方法无法很好地扩展。
重构现有工具:size_checker.go 可以重构为支持树外构建。根据 CLI 评分标准,最好将公开工具添加到 ffx,以鼓励共享工作流并提高发现能力。此外,重构当前代码所需做出的更改非常大,实际上完全重写该工具反而更省事。
使用 blobfs-compression:为了计算每个 blob 的压缩大小和对齐大小,可以使用 blobfs-compression 工具,而不是生成新的 blobfs 映像。这种替代方案的主要缺点是,无法保证 blobfs-compression 工具具有准确的压缩或对齐。具体来说,blobfs-compression 工具假定的是非紧凑型 Merkle 树,这通常会导致其生成的 blob 大小大于实际大小。此外,blobfs-compression 工具一次只能测量一个 blob,因此使用起来更加麻烦,并且可能比运行一次 blobfs 工具更慢。生成 blobfile 映像更符合当前的 size_checker.go,也更准确。
在先技术和参考资料
请参阅背景部分。