10.7.Poudriere
对于 Port 贡献者来说,poudriere 是最重要且最有用的测试和构建工具之一。它的主要功能包括:
批量构建整个 Ports 树、Ports 树的特定子集或单个 Port 及其依赖项
自动打包构建结果
每个 Port 的构建日志文件生成
提供签名的 pkg(8) 仓库
在向 FreeBSD bug 跟踪器提交补丁或向 Ports 树提交时测试 Port 构建
测试不同选项下 Port 构建的成功与否
由于 poudriere 在干净的 jail(8) 环境中执行构建并使用 zfs(8) 功能,因此相比传统的主机系统测试,它具有以下几个优势:
不污染主机环境:没有残留文件,没有意外删除,没有现有配置文件的更改。
验证 pkg-plist 是否有缺失或多余的条目
Ports 提交者有时会要求在提交补丁时附上 poudriere 日志,以评估补丁是否准备好集成到 Ports 树中
poudriere 的设置和使用也非常简单,它没有依赖关系,并且可以在任何受支持的 FreeBSD 版本上运行。本节将展示如何作为 Ports 贡献者的一部分安装、配置和使用 poudriere。
本节中的示例显示的是 FreeBSD 中的默认文件布局,请根据需要替换任何本地更改。Ports 树(由 ${PORTSDIR}
表示)位于 /usr/ports。默认情况下,${LOCALBASE}
和 ${PREFIX}
都是 /usr/local。
10.7.1. 安装 poudriere
可以在 Ports 树中的 ports-mgmt/poudriere 中找到 poudriere。可以通过 pkg(8) 或从 Ports 安装:
# pkg install poudriere
或者
# make -C /usr/ports/ports-mgmt/poudriere install clean
还有一个开发中的版本,最终将成为下个发布版。可在 ports-mgmt/poudriere-devel 中找到它。这个开发版本用于官方的 FreeBSD 包构建,因此经过了充分的测试,并且通常包含更新的有趣功能。Ports 提交者会希望使用开发版本,因为它是用于生产环境的,并且拥有所有新的功能,能够确保一切完全正确。贡献者不一定需要这些功能,因为最重要的修复会回溯到发布版本。使用开发版本构建官方包的主要原因是它更快,在高端 32 CPU 服务器和 128GB 内存的情况下,完整构建时间将从 18 小时缩短到 17 小时。而这些优化在桌面机器上构建 Ports 时影响不大。
10.7.2. 设置 poudriere
该程序安装了默认的配置文件 /usr/local/etc/poudriere.conf。每个参数在配置文件中都有文档说明。
以下是个最简配置文件示例:
ZPOOL=zroot
BASEFS=/usr/local/poudriere
DISTFILES_CACHE=/usr/ports/distfiles
RESOLV_CONF=/etc/resolv.conf
ZPOOL
poudriere 要使用的 ZFS 存储池的名称。必须在 zpool status
的输出中列出。
BASEFS
poudriere 文件系统的根挂载点。此条目将导致 poudriere 将 tank/poudriere
挂载到 /poudriere
。
DISTFILES_CACHE
定义存储 distfiles 的位置。在这个示例中,poudriere 和主机共享 distfiles 存储目录。这可以避免重新下载已存在于系统中的 tarballs。如果该目录尚未存在,请创建它,以便 poudriere 可以找到它。
RESOLV_CONF
在 jail 内部使用主机的 /etc/resolv.conf 进行 DNS 解析。这是为了使 jail 在下载 distfiles 时能够解析 URL。当使用代理时不需要此项。请参考默认配置文件中的代理配置。
10.7.3. 创建 poudriere Jail
创建 poudriere 将用于构建的基础 jail:
# poudriere jail -c -j 131Ramd64 -v 13.1-RELEASE -a amd64
从 poudriere.conf 中指定的 FTP 服务器获取 13.1-RELEASE
版本的 amd64
,创建 ZFS 文件系统 tank/poudriere/jails/131Ramd64
,将其挂载到 /poudriere/jails/131Ramd64,并将 13.1-RELEASE
的 tarballs 提取到该文件系统中。
# poudriere jail -c -j 12i386 -v stable/12 -a i386 -m git+https
创建 tank/poudriere/jails/12i386
,将其挂载到 /poudriere/jails/12i386,然后从 poudriere.conf 中指定的 GIT_HOST
或默认的 git.freebsd.org
获取 FreeBSD-12-STABLE
的 Git 分支的最新代码,检出到 /poudriere/jails/12i386/usr/src,然后完成 buildworld
并将其安装到 /poudriere/jails/12i386 中。
注意
尽管可以在较旧的版本上构建较新的 FreeBSD 版本,但大多数情况下它无法运行。例如,如果需要
stable/13
jail,则主机也必须运行stable/13
,仅运行13.1-RELEASE
不够。
注意
要为
14.0-CURRENT
创建 poudriere jail:# poudriere jail -c -j 14amd64 -v main -a amd64 -m git+https
要运行
14.0-CURRENT
的 poudriere jail,主机必须运行14.0-CURRENT
。通常情况下,较新的内核可以构建并运行较旧的 jails。例如,14.0-CURRENT
内核可以构建并运行12.4-STABLE
,前提是已编译COMPAT_FREEBSD12
内核选项(默认启用,14.0-CURRENT
的 GENERIC 内核配置中已启用)。
可以使用 poudriere jail -l
显示当前 poudriere 知道的 jail 列表:
# poudriere jail -l
JAILNAME VERSION ARCH METHOD
131Ramd64 13.1-RELEASE amd64 ftp
12i386 12.4-STABLE i386 git+https
10.7.4. 保持 poudriere Jail 更新
管理更新非常简单。使用以下命令:
# poudriere jail -u -j JAILNAME
该命令会将指定的 jail 更新到最新版本。对于 FreeBSD 版本更新,可以使用 freebsd-update(8) 更新到最新的补丁级别。对于从源代码构建的 FreeBSD 版本,可以更新到分支中的最新 git 修订版。
注意
对于采用
git+*
方法的 jail,添加-J NumberOfParallelBuildJobs
有助于通过增加并行编译作业数来加速构建。例如,如果构建机器有 6 个 CPU,使用:# poudriere jail -u -J 6 -j JAILNAME
10.7.5. 为 poudriere 设置 Ports Trees
在 poudriere 中使用 Ports Trees 有多种方法。最直接的方法是让 poudriere 为自己创建一个默认的 ports tree,使用 Git:
# poudriere ports -c -m git+https -B main
这些命令会创建 tank/poudriere/ports/default
,将其挂载到 /poudriere/ports/default,并使用 Git 填充它。之后,它会被包括在已知的 ports trees 列表中:
# poudriere ports -l
PORTSTREE METHOD TIMESTAMP PATH
default git+https 2020-07-20 04:23:56 /poudriere/ports/default
注意
请注意,“default”ports tree 是特殊的。除非明确指定,否则后续解释的所有构建命令将隐式使用此 ports tree。如果要使用其他树,可以在命令中添加
-p treename
。
处理本地修改的最佳方法是使用 Git。与创建 jail 类似,可以使用不同的方法来创建 ports tree。为了测试本地修改和开发 Port,最好通过 git 检出树(如上所述)来添加额外的 ports tree。
10.7.6. 使用手动管理的 Ports Trees 与 poudriere
根据工作流的不同,使用手动维护的 ports trees 可能非常有用。例如,如果有一个位于 /work/ports 的本地 ports tree,可以将 poudriere 指向该位置:
# poudriere ports -c -m null -M /work/ports -p development
这将会在已知树的表格中列出:
# poudriere ports -l
PORTSTREE METHOD TIMESTAMP PATH
development null 2020-07-20 05:06:33 /work/ports
注意
METHOD
列中的破折号或null
表示 poudriere 永远不会更新或更改该 ports tree。用户完全负责维护此树,包括所有用于测试新 Port 和提交补丁的本地修改。
10.7.7. 保持 poudriere Ports 更新
更新 ports 与上述 jail 更新一样简单:
# poudriere ports -u -p PORTSTREE
该命令会将指定的 PORTSTREE(由 poudriere -l
输出的树)更新到官方服务器上最新的修订版。
注意
没有指定更新方式的 ports,参见 使用手动管理的 Ports 与 poudriere,无法像这样更新,必须由维护者手动更新。
10.7.8. 测试 Ports
在设置好 jails 和 ports trees 后,可以测试贡献者对 ports tree 的修改。
例如,本地修改位于 /work/ports/www/firefox 的 www/firefox Port,可以在之前创建的 13.1-RELEASE jail 中进行测试:
# poudriere testport -j 131Ramd64 -p development -o www/firefox
这将构建 Firefox 的所有依赖项。如果某个依赖项已构建并且仍是最新的,则会安装预构建的包。如果依赖项没有最新的包,poudriere 将在 jail 中使用默认选项构建该依赖项。然后会构建 Firefox 本身。
每个 Port 的完整构建过程会记录在 /poudriere/data/logs/bulk/131Ri386-development/build-time/logs 中。
目录名 131Ri386-development
是根据 -j
和 -p
参数生成的。为了方便起见,还维护了一个符号链接 /poudriere/data/logs/bulk/131Ri386-development/latest,该链接指向最新的 build-time 目录。该目录中还有一个 index.html,可以通过网页浏览器观察构建过程。
默认情况下,poudriere 会清理 jails 并将日志文件保留在上述目录中。为了便于调查,可以通过在 testport
命令中添加 -i
来保持 jail 在构建后继续运行:
# poudriere testport -j 131Ramd64 -p development -i -o www/firefox
构建完成后,无论是否成功,都会提供一个 shell 进入 jail。可以使用该 shell 进一步调查。poudriere 可以通过 -I
选项在构建完成后保持 jail 运行。构建完成后,poudriere 会显示退出 jail 的命令。此时可以使用 jexec(8) 进入 jail:
# poudriere testport -j 131Ramd64 -p development -I -o www/firefox
[...]
====>> Installing local Pkg repository to /usr/local/etc/pkg/repos
====>> Leaving jail 131Ramd64-development-n running, mounted at /poudriere/data/.m/131Ramd64-development/ref for interactive run testing
====>> To enter jail: jexec 131Ramd64-development-n env -i TERM=$TERM /usr/bin/login -fp root
====>> To stop jail: poudriere jail -k -j 131Ramd64 -p development
# jexec 131Ramd64-development-n env -i TERM=$TERM /usr/bin/login -fp root
# [在 jail 中做一些操作]
# exit
# poudriere jail -k -j 131Ramd64 -p development
====>> Umounting file systems
FreeBSD ports 构建基础设施的一个重要组成部分是能够根据个人喜好调整 Port 的选项。也可以使用 poudriere 测试这些选项。添加 -c
选项:
# poudriere testport -j 131Ramd64 -c -o www/firefox
这会在构建 Port 之前显示 Port 配置对话框。-o
后面的 Port 将使用指定的选项,所有依赖项将使用默认选项。可以使用集合测试带有非默认选项的依赖 Port,参见 使用集合。
技巧
当在构建过程中根据所选选项修改 pkg-plist 时,建议分别进行一个测试运行,选中所有选项 和 不选任何选项。
10.7.9. 使用 Sets
对于所有涉及构建的操作,可以使用 -z <setname>
指定一个所谓的 set。set 表示一个完全独立的构建。例如,这允许在依赖 Port 使用非标准选项时,使用 testport
。
为了使用 sets,poudriere 需要一个类似于 PORT_DBDIR
的现有目录结构,默认情况下为 /var/db/ports,该目录位于其配置目录中。然后,使用 nullfs(5) 将该目录挂载到构建 jails 中的 Port 及其依赖项的位置。通常,可以通过递归复制现有的 PORT_DBDIR
到 /usr/local/etc/poudriere.d/jailname-portname-setname-options 来获得合适的起始点。详情请见 poudriere(8)。例如,要在名为 devset
的特定 set 中测试 www/firefox,只需在 testport
命令中添加 -z devset
参数:
# poudriere testport -j 131Ramd64 -p development -z devset -o www/firefox
poudriere 将按以下顺序查找这些目录的存在:
/usr/local/etc/poudriere.d/131Ramd64-development-devset-options
/usr/local/etc/poudriere.d/131Ramd64-devset-options
/usr/local/etc/poudriere.d/131Ramd64-development-options
/usr/local/etc/poudriere.d/devset-options
/usr/local/etc/poudriere.d/development-options
/usr/local/etc/poudriere.d/131Ramd64-options
/usr/local/etc/poudriere.d/options
从这个列表中,poudriere 会 nullfs(5) 挂载 第一个存在 的目录树到构建 jail 中的 /var/db/ports 目录。因此,所有自定义选项将用于此运行中的所有 Port。
提供 set 的目录结构后,可以更改特定 Port 的选项。例如:
# poudriere options -c www/firefox -z devset
这将显示 www/firefox 的配置对话框,并可以编辑选项。所选选项将保存到 devset
set 中。
注意
poudriere 在选项配置方面非常灵活。poudriere 可以针对特定的 jails、ports trees 以及多个 Port 通过一个命令进行设置。有关详情,请参见 poudriere(8)。
10.7.10. 提供自定义 make.conf 文件
与使用 sets 类似,poudriere 还可以使用提供的自定义 make.conf 文件。如果提供了该文件,则无需特殊的命令行参数。相反,poudriere 会根据命令行中的名称模式查找现有文件。例如:
# poudriere testport -j 131Ramd64 -p development -z devset -o www/firefox
这将导致 poudriere 按以下顺序查找这些文件的存在:
/usr/local/etc/poudriere.d/make.conf
/usr/local/etc/poudriere.d/devset-make.conf
/usr/local/etc/poudriere.d/development-make.conf
/usr/local/etc/poudriere.d/131Ramd64-make.conf
/usr/local/etc/poudriere.d/131Ramd64-development-make.conf
/usr/local/etc/poudriere.d/131Ramd64-devset-make.conf
/usr/local/etc/poudriere.d/131Ramd64-development-devset-make.conf
与 sets 不同,所有找到的文件将 按顺序 追加到构建 jails 中的一个 make.conf 文件中。因此,可以在 /usr/local/etc/poudriere.d/make.conf 中设置影响所有构建的通用 make 变量。特定 jails 或 sets 的特殊变量可以在专用的 make.conf 文件中进行设置,例如 /usr/local/etc/poudriere.d/131Ramd64-development-devset-make.conf。
示例 1. 使用 make.conf 更改默认 Perl 版本
例如,要使用名为 perl5-20
的 set 构建一个非默认的 Perl 版本 5.20
,可以创建一个 perl5-20-make.conf 文件,并添加以下内容:
DEFAULT_VERSIONS+= perl=5.20
注意使用 +=
,这样即使该变量在默认 make.conf 中已设置,其内容也不会被覆盖。
10.7.11. 清理不再需要的 distfiles
poudriere 提供了一种内建机制,用于删除不再被任何 Port 使用的过时 distfiles。使用以下命令:
# poudriere distclean -p portstree
该命令将扫描 poudriere.conf 中的 DISTFILES_CACHE
文件夹,并与通过 -p <portstree>
参数指定的 Ports 树进行对比,提示删除那些不再使用的 distfiles。如果希望跳过提示,直接无条件删除所有未使用的文件,可以添加 -y
参数:
# poudriere distclean -p portstree -y
最后更新于
这有帮助吗?