RFC-0144:大小检查工具

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

建议重写 size_checker.go,以创建更具凝聚力的树内和树外开发者体验。

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

摘要

本文档建议开发一种新的大小检查工具,该工具将添加到 SDK 中,以便开发者和产品所有者验证其软件包和产品是否超出指定的大小预算。虽然有意省略了实现细节,但由于树外 Assembly 不断改变基础,因此提到了设计要求和目标。

设计初衷

在软件开发过程中,了解软件是否符合目标的大小限制很有帮助。Fuchsia 有一个大小检查工具,用于分析不同软件组占用的空间,并为每个组强制执行预算。此工具与 fuchsia.git 的实现细节紧密相关,因此在没有 fuchsia.git 检出的情况下无法使用。因此,Chromium 等 Fuchsia 的使用者已实现自己的临时方法来检查软件的大小。通过将大小检查工具重写为 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 集成

社交化

此项目已作为内部文档进行社交化,并已提前与利益相关者在会议中讨论过。在起草此 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 检出的情况下无法使用该工具。

首先,Fuchsia 构建会生成一个 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. 构建一个 N 元求和树,通过将每个 blob 的 shared_size 添加到 blob 路径中的节点,表示构建输出中每个目录占用的空间。
  6. 遍历每个预算,并断言为目录预算的大小大于占用的空间。
  7. 遍历预算中的每个非 blobfs 软件包,使用 blobfs-compression 计算 blob 大小的总和,并断言其在预算范围内。
  8. 输出结果。

灵树

blobfs-compression

链接到源代码

此工具可以估算一组 blob 的压缩大小和对齐大小,但并非 100% 准确,有时可能会高估 blob 的大小。该工具绝不会低估 blob 的大小。

blobfs-compression 通过 Fuchsia SDK 交付给客户端,目前是估算 fuchsia.git 之外为 Fuchsia 构建的代码大小的唯一方法。Chromium 是此工具的客户端。

当前工具存在的问题

  • 用于检查软件包大小的树内和树外方法是不同的工具。
  • 这两个工具都无法直接检查映像的大小,以确保刷写成功。
  • size_checker.go
    • 没有文档。
    • 取决于 Fuchsia 构建的实现细节,这不是稳定的合约。
    • 在树外不起作用。
  • blobfs-compression
    • 无法保证返回 blob 的准确压缩大小。
    • 在 blob 级别运行,不如在软件包级别运行有用。开发者按软件包向产品添加软件。
    • 没有标准输出格式,因此不容易编写脚本,并且自动化使用很脆弱。

要求

  1. 在 SDK 中提供一个或多个工具,这些工具在树内和树外均可使用。
  2. 这些工具支持当前工具的所有所需现有用例。
  3. 这些工具可以执行两种类型的大小检查:
    • (a) Google 图片
    • (b) 一组软件包中的 blob
  4. 在情况 (2) 中,将对所有集中的所有软件包执行 blob 重复数据删除。
  5. 当超出用户指定的预算时,这些工具将返回失败。
  6. 这些工具与其他 SDK 工具(例如 Image Assembler (RFC-0072))配合使用效果良好。
  7. 这些工具可以轻松地在脚本中使用,具有可解析的输出,并 生成 Gerrit Size 插件使用的输出。
  8. 这些工具的使用和架构将在 fuchsia.dev 中记录。

设计

凝聚力的开发者体验

将使用 Rust 编写一个新的 ffx 插件,用于执行两种类型的大小检查。根据 CLI 评分准则,最好将其纳入 ffx,以鼓励共享工作流并提高 可发现性。此外,我们将优先考虑扩展现有文件格式,而不是发明新的文件格式。

可编写脚本

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

映像大小

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

测量映像的大小就像打开文件并读取元数据中的长度一样简单。这适用于任何未压缩或稀疏的映像。此方法不适用的一个示例是稀疏 FVM,并且由于目前没有用于计算稀疏 FVM 扩展大小的库,因此该工具将忽略稀疏 FVM 的大小检查。

软件包大小

blob 和软件包大小检查应与 Assembly 紧密集成,因为工程师在 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 和 Assembly 产品配置,并生成新的预算文件。系统将解析产品配置以收集每个软件包清单,并根据 size_limits.json 中设置的目录预算对这些清单进行分类。

可能的预算文件格式为:

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

一旦新的大小检查工具承担构建负载,生成的预算文件将被签入代码库,生成的代码将被删除。

输出比较

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

性能

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

当前的 size_checker.go 工具大约需要 1-2 秒才能运行,而我们的新工具的目标是接近相同的时长。

工效学设计

请参阅“设计”部分。

向后兼容性

此设计不需要向后兼容。

安全注意事项

此设计没有安全隐患。

隐私注意事项

此设计没有隐私隐患。

测试

在 Fuchsia 构建中,新的大小检查工具将与 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,并且更准确。

在先技术和参考文档

请参阅“背景”部分。