RFC-0144:大小检查工具

RFC-0144:大小检查工具
状态已接受
领域
  • 开发者
说明

提议了对 size_checker.go 进行重写,以打造更一致的树内和树外开发者体验。

问题
  • 85371
Gerrit 更改
  • 609963
作者
审核人
提交日期(年-月-日)2021-11-22
审核日期(年-月-日)2021-12-10

总结

本文档提议开发一种将添加到 SDK 中的新尺寸检查工具,该工具可让开发者和产品所有者验证其软件包和产品是否不超过指定的尺寸预算。虽然我们特意排除了实现细节,但由于树外组件不断改变基础,因此会提到设计要求和目标。

设计初衷

在软件开发过程中,了解您的软件是否符合目标的大小限制会很有帮助。Fuchsia 具有大小检查工具,可以分析不同软件组消耗的空间,并为每个组强制执行预算。此工具与 fuchsia.git 的实现细节密切相关,因此如果没有 fuchsia.git 检出,则无法使用。因此,Duchsia 的消费者(例如 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) - 组装集成

社交

此项目已作为内部文档进行社交化,并提前与利益相关方开会讨论。在本 RFC 起草之前,就已收集了相关要求。

背景

此 RFC 假定您了解以下主题。

两种大小检查方式

尺寸检查分为两类:

  1. 映像在刷写时不会超过其目标分区大小。
  2. 在更新期间,Blob 符合 FVM 预算。

刷写:开发者可以将新映像刷写到 Fuchsia 目标上。刷写映像时,分区的内容会被新映像的字节完全替换。为了确保成功刷写,新映像不得大于分区的大小。

更新:Fuchsia 目标可以无线下载进行更新。为了确保更新成功,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 检出,则无法使用该工具。

首先,Fucchsia build 会生成一个 blobs.json 文件(列出 blobfs 中每个 blob 的压缩后对齐大小)和一个 blob.manifest 文件(列出这些 blob 的 Merkle 和源路径)。

接下来,运行 size_checker.go 并执行以下操作:

  1. 读取 blobs.json 以收集每个 blob 的压缩大小:compressed_size
  2. 读取 blob.manifest 以收集所有软件包。
  3. 计算 blob 在软件包中的次数:share_count
  4. 计算每个 blob 的共享大小:shared_size = compressed_size / share_count。由于多项预算可以包含同一个 blob,因此我们使用 blob 的 shared_size 在各个预算之间平均分配大小消耗。
  5. 通过将每个 blob 的 shared_size 添加到 blob 路径中的节点,构造表示 build 输出中每个目录所占用空间的 N 元总和树。
  6. 遍历每项预算,并断言预算为目录预算的大小大于所占用的空间。
  7. 遍历预算中的每个非 blobfs 软件包,使用 blobfs-compression 计算 blob 大小的总和,并断言其在预算范围内。
  8. 输出结果。

总和树

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 级别操作,不如在软件包级别操作有用。开发者按软件包向产品添加软件。
    • 它没有标准的输出格式,因此不易编写脚本,并且自动使用不稳定。

要求

  1. 在 SDK 中提供同时适用于树内和树外的一个或多个工具。
  2. 这些工具支持当前工具的所有现有预期应用场景。
  3. 这些工具可以执行两种类型的大小检查:
    • (a) 图片
    • (b) 一组软件包中的 Blob
  4. 在第 (2) 种情况下,将对所有软件包中的所有软件包执行 blob 重复信息删除。
  5. 如果超出用户指定的预算,工具会返回错误。
  6. 这些工具可以与其他 SDK 工具(例如 Image Assembler (RFC-0072))完美搭配使用。
  7. 这些工具可以在脚本中轻松使用,具有可解析的输出,并生成供 Gerrit Size 插件使用的输出。
  8. 该工具的用法和架构将记录在 fuchsia.dev 中。

设计

一致的开发者体验

一个新的 ffx 插件将使用 Rust 编写,用于执行两种类型的大小检查。根据 CLI 评分准则,最好将其合并到 ffx 中,以鼓励共享工作流并提高可检测性。此外,系统还会优先扩展现有的文件格式,而不是创建新格式。

可编写脚本

此工具将主要用于构建系统,因此输出应该可以解析。输出格式可能会使用 json5 作为输出格式,但随着 Assembly 项目的推进,系统可能会考虑使用其他格式。

图像大小

映像大小检查工具应在构建 Flash 清单的同时运行,其中组合的映像会映射到分区。目前,Flash 清单的创建是在 Fuchsia 构建系统中完成的,因此 ffx 插件将通过 GN 操作调用。未来,我们可能会提供用于构建 Flash 清单的 SDK 工具,并且作为 ffx 插件,我们的大小检查工具应该能够在该场景中无缝运行。

测量图片大小非常简单,只需打开文件并读取元数据中的长度即可。这适用于任何非压缩或稀疏映像。例如,稀疏 FVM 就不适合此方法,而由于目前没有可用于计算稀疏 FVM 的较大大小的库,该工具将忽略针对稀疏 FVM 的大小检查。

软件包尺寸

Blob 和软件包大小检查应与 Assembly 紧密集成,因为在组装期间,工程师会将软件包分组为多个集合,然后将这些集合组合以指定产品。

大小检查工具使用 blobs.json 文件,其中列出了每个 blob 的压缩后尺寸和对齐后尺寸。开发者可以提供多个 blobs.json 文件作为工具的输入。如果在提供的任何 blobs.json 文件中都找不到软件包的 blob,则大小检查工具将使用 blobfs 工具为所有缺失的 blob 生成一个 blobfs 映像,从而生成额外的 blobs.json。大小检查工具将读取生成的 blobs.json 以获取缺失 blob 的大小。

与现有的 size_checker.go 工具类似,新的大小检查工具将通过大小除以使用该 blob 的软件包数量来计算每个 blob 的共享大小。此共享尺寸会在制定预算的过程中用到。

实现

此工具的实现和集成将分几个阶段完成。

  1. 声明资源包集的预算。请参阅下面的说明
  2. 编写一个 ffx 插件,以确保软件包集在其预算范围内
  3. 确保 ffx 插件的输出与构建系统的一部分之前的工具的输出一致。如果输出不同,构建应该会失败。请参阅下面的说明
  4. 声明图片的预算
  5. 添加功能以确保图片尺寸不超出预算
  6. 停用 size_checker.go 并让新的 ffx 插件承载
  7. 删除 size_checker.go 代码。

生成预算文件

为了避免重复为给定产品维护两组相同的预算,构建系统会更新以读取现有的 size_limits.json 并汇编产品配置,并生成新的预算文件。系统会解析产品配置以收集每个软件包清单,并且这些清单将根据在 size_limits.json 中设置的目录预算进行分类。

可能的预算文件格式包括:

[
    {
        name: "name-of-package-set",
        packages: [
            "path/to/manifest1.json",
            "path/to/manifest2.json",
        ],
        budget_bytes: 12000,
    },
]

一旦新的大小检查工具能够为 build 带来负载,生成的预算文件将签入代码库,并且生成的代码将被删除。

输出比较

在过渡到新的大小检查工具期间,构建系统会断言新工具的输出与新工具的输出一致。将编写一个脚本来解析这两种工具的输出,并确保每个软件包组(或目录)的预算和计算出的消耗相等。为了将这两种输出格式关联起来,该脚本将假设标识这组软件包的名称完全相同。由于旧工具和新工具使用相同的基础机制来计算 blob 的大小(使用 blobfs),因此计算出的消耗量也完全相同。

性能

大小检查工具旨在用于构建系统,因此对性能不稳定性的容忍度高于网络堆栈等工具。另一方面,缩短构建时间对于提高开发者的工作效率非常重要。此外,此工具位于构建的关键路径上,因为它必须等待所有软件包构建完毕和映像组合完毕之后才能开始运行,因此无法并行运行。

当前的 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 工具更慢。生成 blobfs 映像更与当前的 size_checker.go 更内联,并且更准确。

早期技术和参考资料

请参阅背景部分。