RFC-0144:大小检查工具

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

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

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

摘要

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

设计初衷

在软件开发过程中,了解软件是否符合目标平台的大小限制非常有用。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) - 汇编集成

社交

此项目以内部文档的形式进行共享,并在与利益相关方的会议中提前讨论。在起草本 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 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 路径中的节点,构建一个 N 元求和树,表示 build 输出中每个目录占用的空间。
  6. 迭代每个预算,并断言为目录预算的大小大于所占用的空间。
  7. 迭代预算中的每个非 blobfs 软件包,使用 blobfs-compression 计算 blob 大小的总和,并断言其在预算范围内。
  8. 输出结果。

求和树

blobfs-compression

指向来源的链接

此工具可以估算一组 blob 的压缩和对齐大小,但并不完全准确,并且可能会偶尔过高估算 blob 的大小。该工具绝不会低估 blob 的大小。

blobfs-compression 会通过 Fuchsia SDK 传送给客户端,目前是唯一一种用于估算 fuchsia.git 之外存在的为 Fuchsia 构建的代码大小的方法。Chromium 是此工具的客户端。

现有工具存在的问题

  • 用于检查软件包大小的树内和树外方法是不同的工具。
  • 这两种工具都无法直接检查图片大小,以确保刷写成功。
  • size_checker.go
    • 未记录。
    • 取决于 Fuchsia build 的实现细节,这不是稳定的合约。
    • 无法在树外运行。
  • blobfs-compression
    • 无法保证返回 blob 的准确压缩大小。
    • 在 blob 级别运行,不如在软件包级别运行实用。开发者可以按软件包将软件添加到商品中。
    • 没有标准输出格式,因此无法轻松编写脚本,自动化使用不稳定。

要求

  1. 在 SDK 中提供一个或多个同时适用于树内和树外的工具。
  2. 工具支持当前工具的所有预期现有用例。
  3. 该工具可以执行两种类型的大小检查:
    • (a) 图片
    • (b) 一组软件包中的 blob
  4. 在情况 (2) 中,系统会对所有集中的所有软件包进行 blob 去重。
  5. 当超出用户指定的预算时,工具将返回失败。
  6. 该工具可与其他 SDK 工具(例如图片汇编器 [RFC-0072])协同工作。
  7. 这些工具可轻松用于脚本,并生成可解析的输出,同时生成 Gerrit Size 插件使用的输出。
  8. 工具的使用和架构将在 fuchsia.dev 中记录。

设计

协调一致的开发者体验

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

可编写脚本

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

图片大小

图片大小检查器应与构建 Flash 清单(其中已组装的映像映射到分区)同时运行。目前,Flash 清单的创建是在 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 和汇编产品配置,并生成新的预算文件。系统会解析产品配置以收集每个软件包清单,并根据 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 且更准确。

在先技术和参考文档

请参阅背景部分。