5 理解 Yocto 项目 Autobuilder
5 Autobuilder 内部的执行流程
“a-full” 和 “a-quick” 是 Autobuilder 常用的入口,可以从这里跟踪整个执行过程。 最直观的查看方式是 Autobuilder 控制台视图。
控制台顶部的每一项代表一个目标构建,这些目标并行运行。
完整构建触发大部分目标,快速构建只触发其中一部分。
每个目标的配置会在独立的 Buildbot 工作节点上执行。
配置定义位于 yocto-autobuilder-helper
仓库的 config.json 中,具体目标列在 overrides 部分。
例如,qemux86-64 的配置如下:
"qemux86-64" : {
"MACHINE" : "qemux86-64",
"TEMPLATE" : "arch-qemu",
"step1" : {
"extravars" : [
"IMAGE_FSTYPES:append = ' wic wic.bmap'"
]
}
},
要进一步展开,还需查看 templates 中的 arch-qemu 模板:
"arch-qemu" : {
"BUILDINFO" : true,
"BUILDHISTORY" : true,
"step1" : {
"BBTARGETS" : "core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev core-image-sato:do_populate_sdk",
"SANITYTARGETS" : "core-image-minimal:do_testimage core-image-sato:do_testimage core-image-sato-sdk:do_testimage core-image-sato:do_testsdk"
},
"step2" : {
"SDKMACHINE" : "x86_64",
"BBTARGETS" : "core-image-sato:do_populate_sdk core-image-minimal:do_populate_sdk_ext core-image-sato:do_populate_sdk_ext",
"SANITYTARGETS" : "core-image-sato:do_testsdk core-image-minimal:do_testsdkext core-image-sato:do_testsdkext"
},
"step3" : {
"BUILDHISTORY" : false,
"EXTRACMDS" : ["${SCRIPTSDIR}/checkvnc; DISPLAY=:1 oe-selftest ${HELPERSTMACHTARGS} -j 15"],
"ADDLAYER" : ["${BUILDDIR}/../meta-selftest"]
}
},
结合两段配置可知,qemux86-64 构建包含三个步骤,
每步先运行 bitbake BBTARGETS,再运行 bitbake SANITYTARGETS。
所有步骤都使用 MACHINE="qemux86-64",但 SDKMACHINE 设置可能不同。
第 1 步还向 build/conf/auto.conf 添加了变量,启用 wic 镜像生成。
这里没有逐项解释所有细节,但可以看出模板机制如何在尽量减少重复配置的同时, 组合出较为复杂的构建方案。
各构建目标按便于并行化的方式设计。不同机器通常并行构建, 使用相同机器和元数据的操作则顺序执行,以尽可能提高效率。
config.json 由 Helper 仓库 scripts 目录中的脚本处理,
下一节介绍具体过程。
5 Autobuilder 目标执行概览
对于构建中的每个目标,Autobuilder 会执行多个步骤。
这些步骤定义在 yocto-autobuilder2/builders.py 中,大致如下:
运行 clobberdir。
清理之前的构建。保留旧构建是为了便于调试失败情况。 详情见 clobberdir。
获取 yocto-autobuilder-helper。
克隆 yocto-autobuilder-helper 仓库。 这样就不必把所有版本或项目专用代码都维护在 Buildbot 中。 所选分支与待构建版本一致,因此既能支持旧版本,也能改进新版本的行为。
写入 layerinfo.json。
将在 Buildbot 界面中配置构建时提供的数据传给 Helper。
调用 scripts/shared-repo-unpack。
Helper 脚本准备该构建所需全部组件的检出副本, 可能包括 BitBake、OpenEmbedded-Core (OE-Core) 及额外的层。 脚本使用
layerinfo.json理解配置,并通过本地仓库缓存加快克隆。 详情见 Autobuilder 克隆缓存。这一步有两种运行模式。如果构建属于某个父构建, 所需仓库可能已经放在事先准备好的目录中。 “a-quick” 或 “a-full” 会先准备这些仓库,再启动子目标,原因有二:
构建过程中上游可能发生变化,例如被强制推送。 共用预先准备的副本可以确保整个构建使用一致内容。
如果 15 个工作节点同时从相同上游仓库拉取数据, 可能触发服务器资源限制,甚至被误认为网络攻击。
准备好的目录通过 NFS 在工作节点之间共享。 如果是单独构建,没有这样的共享目录,则按需从缓存和上游克隆,作为后备方式。
调用 scripts/run-config。
再次进入 Helper 脚本,执行该目标的主要工作。
5 Autobuilder 的实现技术
Autobuilder 包含一些针对 Yocto 项目的机制,以提高构建效率与速度。
5.3.1 clobberdir
清理文件时使用 clobberdir。
它不会立刻删除文件,而是先移到专门的位置,
随后由运行在 ionice -c 3 下的 rm 删除。
这样只有在工作节点有空闲 I/O 能力时才执行删除。
该工作由工作节点清理进程负责,见
Autobuilder 工作节点清理进程。
5 Autobuilder 克隆缓存
每次从头克隆仓库会降低构建速度,因此工作节点会预先缓存常用仓库。 克隆时先使用缓存,再按需从上游补齐较新的修订。 缓存由工作节点清理进程维护,见 Autobuilder 工作节点清理进程。
5 Autobuilder 工作节点清理进程
每个工作节点上都运行一个清理进程,主要完成两项工作: 在 I/O 空闲时后台删除文件,见 Autobuilder 目标执行概览 中的 clobberdir 步骤;以及维护克隆仓库缓存,加快后续检出。
5.3.7 Resulttool
构建过程中运行的各类测试会将结果写入 testresults.json。
据此可以判断某次构建执行了哪些测试,以及它们的状态。
文件还可能包含失败日志、测试耗时等信息。
Resulttool 属于 OpenEmbedded-Core,用于处理这些 JSON 结果文件, 支持合并文件、显示测试报告和比较不同结果。
5 run-config 的目标执行过程
Autobuilder 的大部分工作发生在 scripts/run-config 中。
开始时执行一次通用初始化:
如有配置,安装 buildtools 归档。
如果启用 buildhistory,调用
buildhistory-init。
对于 config.json 中配置的每一步,依次执行:
用
bitbake-layers add-layer加入指定的层,日志记为 stepXa。调用
scripts/setup-config,生成该构建所需的 build/conf/auto.conf。运行
bitbake BBTARGETS,日志记为 stepXb。运行
bitbake SANITYTARGETS,日志记为 stepXc。在 BitBake 构建环境中运行
EXTRACMDS,日志记为 stepXd。在 BitBake 构建环境之外运行
EXTRAPLAINCMDS,日志记为 stepXd。用
bitbake-layers remove-layer移除本步最初加入的层,日志记为 stepXa。
上述步骤完成后,再执行构建后的处理:
调用
scripts/publish-artifacts,收集需要保存的构建产物。调用
scripts/collect-results,收集需要保存的测试结果。调用
scripts/upload-error-reports,将错误报告发送到远程服务器。构建成功时用 clobberdir 清理 Build Directory;失败时则将目录重命名为 “build-renamed”, 以便后续调试。
5 部署 Yocto Autobuilder
部署自己的 Autobuilder 的最新说明见 yocto-autobuilder2 仓库中的 README.md。
项目希望用户能直接使用 yocto-autobuilder2 代码。
但为了定义自己的测试矩阵,通常需要较大幅度地定制
yocto-autobuilder-helper,
尤其是 config.json。
Autobuilder 支持两种定制方式:
变量替换。
用额外配置文件覆盖配置。
标准 config.json 至少支持路径替换。
Helper 仓库提供的 local-example.json 展示了如何从独立配置文件覆盖设置。
可以在 Autobuilder 环境中设置:
$ ABHELPER_JSON="config.json local-example.json"
也可以使用另一个位置的配置文件:
$ ABHELPER_JSON="config.json /some/location/local.json"
用户经常遇到的问题是 config.json 校验失败。
为减少无效 JSON 导致的问题,可以在提交前用 Git 的
pre-commit-hook.sh 验证文件。创建符号链接的方法如下:
$ ln -s ../../scripts/pre-commit-hook.sh .git/hooks/pre-commit