10.6.Poudriere

对于一个 ports 贡献者来说,Poudriere 是最重要和最有帮助的测试和构建工具之一。它的主要功能包括:

  • 批量构建整个 ports、 port 的特定子集,或包括其依赖关系的单个 port

  • 自动打包构建结果

  • 为每个 port 生成构建日志文件

  • 提供有签名的 pkg(8) 存储库

  • 在向 FreeBSD bug 跟踪器 提交补丁或提交到 Ports 之前, 对 port 的联编进行测试

  • 使用不同的选项测试成功的 port 构建

由于 Poudriere 是在一个干净的 jail(8) 环境中进行联编, 并使用了 zfs(8) 的功能, 因此与在主机系统上进行的传统测试相比, 它具有一些优势。

  • 没有对主机环境的污染。没有遗留的文件,没有意外的删除,没有改变现有的配置文件。

  • 验证 pkg-plist 中是否有丢失或多余的条目

Ports 提交者有时会要求在提交补丁的同时提供一份 Poudriere 日志, 以评估该补丁是否已经准备好集成到 Ports 中。

它的设置和使用也相当简单, 没有任何依赖性, 并可以在任何支持的 FreeBSD 版本上运行。作为 ports 贡献者的正常工作流程的一部分,本节将介绍如何安装、 配置和运行 Poudriere。

本节中的例子显示了一个默认的文件布局, 这是 FreeBSD 的标准。请相应地替换任何本地修改。由 ${PORTSDIR} 表示的 Ports , 位于 /usr/ports${LOCALBASE}${PREFIX} 默认都是 /usr/local

10.6.1. 安装 Poudriere

Poudriere 可以在 ports-mgmt/poudriere 的 Ports 中找到。它可以使用 pkg(8) 或从 ports 安装。

# pkg install poudriere

# make -C /usr/ports/ports-mgmt/poudriere install clean

还有一个正在进行中的 Poudriere 版本, 它将最终成为下一个版本。 它可以在 ports-mgmt/poudrie-devel 中找到。 这个开发版本被用于官方 FreeBSD 软件包的构建,因此它经过了良好的测试。它通常会有更多有趣的新功能。ports committer 会希望使用开发版本, 因为它是生产中使用的版本, 并具有所有新的功能, 以确保一切都正确无误。贡献者则不一定需要这些, 因为最重要的修正已经回传到了发布版本。使用开发版本构建官方软件包的主要原因是它的速度更快,在使用高端的 32 个 CPU 服务器和 128GB 内存的情况下,完整的构建时间将从18小时缩短到17小时。在台式机上构建 port 时,这些优化不会有很大的影响。

10.6.2. 设置 Poudriere

该 port 安装了一个默认的配置文件, 即 /usr/local/etc/poudriere.conf 。 每个参数都在配置文件和 poudriere(8) 中有所记录。下面是一个最小的配置文件示例。

ZPOOL=tank
ZROOTFS=/poudriere
BASEFS=/poudriere
DISTFILES_CACHE=/usr/ports/distfiles
RESOLV_CONF=/etc/resolv.conf
FREEBSD_HOST=ftp://ftp.freebsd.org
SVN_HOST=svn.FreeBSD.org
ZPOOL

ZPOOL

Poudriere 应使用的 ZFS 存储池的名称。必须在 zpool status 的输出中列出。

ZROOTFS

Poudriere 管理的文件系统的根。此条目将导致 Poudriere 在 tank/poudriere 下创建 zfs(8) 文件系统。

BASEFS

Poudriere文件系统的根挂载点。此条目将使 Poudriere 将 tank/poudriere 挂载到 /poudriere

DISTFILES_CACHE

定义了 distfiles 的存储位置。在这个例子中,Poudriere 和主机共享 distfiles 存储目录。这样可以避免下载系统中已经存在的压缩包。如果该目录不存在,请创建该目录,以便 Poudriere 能够找到它。

RESOLV_CONF

使用 jails 内的主机 /etc/resolv.conf 进行 DNS。这是需要的,以便 jails 在下载时能够解析 distfiles 的 URL。在使用代理时,不需要它。请参考默认配置文件中的代理配置。

FREEBSD_HOST

当从 FreeBSD 版本中安装 jails 并使用 freebsd-update(8) 进行更新时要使用的 FTP/HTTP 服务器。选择一个距离较近的服务器位置, 例如, 如果机器位于澳大利亚, 使用 ftp.au.freebsd.org

SVN_HOST

使用 Subversion 时,安装和更新 jail 的服务器。同样,选择一个附近的位置。官方的 Subversion 镜像列表可以在 FreeBSD 手册中的 Subversion 部分找到。

10.6.3. 创建 Poudriere Jails

创建 Poudriere 将用于构建的基本 jails。

# poudriere jail -c -j 131Ramd64 -v 13.1-RELEASE -a amd64

poudriere.confFREEBSD_HOST 给出的 FTP 服务器上获取适用于 amd6413.1-RELEASE,创建 zfs 文件系统 tank/poudriere/jails/131Ramd64,将其挂载到 /poudriere/jails/131Ramd64 ,并将 13.1-RELEASE 的压缩包解压到该文件系统中。

# poudriere jail -c -j 12i386 -v stable/12 -a i386 -m git+https

创建 tank/poudriere/jails/12i386,将其挂载到 /poudriere/jails/12i386 ,然后从 poudriere.conf 中的 SVN_HOST 检查出 FreeBSD-12-STABLE 的 Subversion 分支的提示,并将其安装到 /poudriere/jails/12i386/usr/src ,然后完成一个 buildworld,并安装到 /poudriere/jails/12i386

技巧

如果需要一个特定的 Subversion 版本,请将其附加到版本字符串中。比如说:

# poudriere jail -c -j 12i386 -v stable/12@123456 -a i386 -m git+https

注意

虽然有可能在老版本的 FreeBSD 上构建一个较新的版本,但大多数情况下它不会运行。例如,如果需要一个 stable/13 jails,主机也必须运行 stable/13。运行 13.1-RELEASE 是不够的。

注意

要为 14.0-CURRENT 创建一个 Poudriere jails:

# poudriere jail -c -j 14amd64 -v main -a amd64 -m git+https

为了运行 14.0-CURRENT Poudriere jails,你必须运行 14.0-CURRENT。一般来说,较新的内核可以构建和运行较老的 jails。 例如,一个 14.0-CURRENT 内核可以构建和运行 12.3-STABLE。如果 COMPAT_FREEBSD12 内核选项被编译进来(在 14.0-CURRENT GENERIC 内核配置中默认为打开),则 Poudriere jails。

当心

默认的 svn 协议可以工作,但不是很安全。建议使用 svn+https,同时验证远程服务器的SSL指纹。这将确保用于构建 jails 的文件是来自可信的来源。

Poudriere 当前已知的 jails 列表可以通过 poudriere jail -l 来显示。

# poudriere jail -l
JAILNAME             VERSION              ARCH    METHOD
131Ramd64            13.1-RELEASE         amd64   ftp
12i386               12.3-STABLE          i386    git+https

10.6.4. 保持 Poudriere jails 的更新

管理更新是非常简单明了的。该命令。

# poudriere jail -u -j JAILNAME

将指定的 jails 更新到最新的可用版本。对于 FreeBSD 版本,用 freebsd-update(8) 更新到最新的补丁级别。对于从源代码构建的 FreeBSD 版本,更新到分支中最新的 Subversion 版本。

技巧

对于采用 git+* 方法的 jails,添加 -J NumberOfParallelBuildJobs 有助于通过增加并行编译作业的数量来加快构建速度。例如,如果构建机器有6个 CPU,可以使用。

# poudriere jail -u -J 6 -j JAILNAME

10.6.5. 设置用于 Poudriere 的 ports

在 Poudriere 中使用 Ports 有多种方法。最直接的方法是让 Poudriere 为自己创建一个默认的 Ports ,使用 Git

# poudriere ports -c -m git+https -B main

这些命令创建了 tank/poudriere/ports/default,将其挂载在 /poudriere/ports/default 上,并使用 Git 来填充它。之后,它就会被列入已知 Ports 的列表中。

# poudriere ports -l
PORTSTREE METHOD    TIMESTAMP           PATH
default   git+https 2020-07-20 04:23:56 /poudriere/ports/default

注意

请注意,“default” 的 Ports 很特别。后面解释的每个构建命令都会隐含地使用这个 Ports ,除非特别指定。要使用另一棵树, 请在命令中加入 -p treename

处理对 ports 贡献者的本地修改的最好方法是使用 Git。与创建 jails 一样, 也可以使用不同的方法来创建 Ports 。要增加一个额外的 Ports 来测试本地修改和 ports 开发, 通过 Subversion 来检查这个树 (如上所述) 是最好的。

注意

http 和 https 方法需要在启用 SERF 选项的情况下构建 devel/subversion。它在默认情况下是启用的。

技巧

svn 方法允许额外的限定词来告诉 Subversion 如何获取数据。 这在 poudriere(8) 中有解释。例如,poudriere ports -c -m svn+ssh -p subversive 使用 SSH 进行签出。

10.6.6. 在 Poudriere 中使用人工管理的 Ports

根据工作流程的不同,使用手动维护的 ports 可能会非常有用。 例如,如果在 /work/ports 中存在一个本地的 Ports 副本,那么将 Poudriere 指向该位置:

  • 对于早于 3.1.20 版本的 Poudriere:

# poudriere ports -c -F -f none -M /work/ports -p development
  • 对于 Poudriere 3.1.20 及以后的版本。

# 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 ,永远不会。 维护这棵树完全取决于用户, 包括所有可能用于测试新 port 和提交补丁的本地修改。

10.6.7. 保持 Poudriere Ports 的更新

就像前面描述的 Jails 一样简单明了。

# poudriere ports -u -p PORTSTREE

将更新给定的 PORTSTREE , 即由 poudriere -l 输出的一棵树, 以达到官方服务器上的最新版本。

注意

没有方法的 Ports , 见 Using Manually Managed Ports Trees with Poudriere, 不能像这样更新。它们必须由 port 使用人手动更新。

10.6.8. 测试 Ports

在建立了 jail 和 ports 之后, 可以测试贡献者对 ports 的修改结果。

例如, 对位于 /work/ports/www/firefoxwww/firefox port 所做的本地修改, 可以在先前创建的 13.1-RELEASE jail 中进行测试。

# poudriere testport -j 131Ramd64 -p development -o www/firefox

这将构建 Firefox 的所有依赖项。 如果某个依赖项之前已经构建过,并且仍然是最新的,则会安装预先构建的软件包。如果一个依赖项没有最新的软件包,那么将在 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,使 jails 在构建后继续运行。

# poudriere testport -j 131Ramd64 -p development -i -o www/firefox

在构建完成后,无论是否成功, jail 内都会提供一个 shell。这个 shell 是用来进一步调查的。可以告诉 Poudriere ,在构建完成后,用 -I 来保持 jail 的运行。Poudriere 会在不再需要该 jail 时显示要运行的命令。然后就可以用 jexec(8) 进入它。

# 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
# [do some stuff in the jail]
# exit
# poudriere jail -k -j 131Ramd64 -p development
====>> Umounting file systems

FreeBSD ports 构建基础结构的一个组成部分是通过选项将 port 调整到个人偏好的能力。这些功能也可以用 Poudriere 来测试。添加 -c

# poudriere testport -c -o www/firefox

在 port 建立之前,呈现出 port 配置对话框。在 -o 后面给出的格式为 category/portname 的 ports 将使用指定的选项,所有依赖的 ports 将使用默认选项。使用非默认选项来测试依赖的 port 可以通过使用集合来完成, 请参阅 Using Sets

技巧

在测试 port 时, 如果 pkg-plist 在联编过程中会根据所选的选项而改变, 建议在所有选项都被选中的情况下进行测试, 并在所有选项都被取消的情况下进行。

10.6.9. 使用 Set

对于所有涉及联编的操作, 可以使用 -z setname 来指定一个所谓的集合 。 一个集合指的是一个完全独立的构建。例如,这允许在使用 testport 时,对依赖的 port 使用非标准的选项。

要使用集合, Poudriere 希望有一个类似于 PORT_DBDIR 的现有目录结构, 默认是其配置目录中的 /var/db/ports 。然后, 这个目录将被 nullfs(5) 挂载到 port 及其依赖关系所在的 jail 中。通常可以通过递归地将现有的 PORT_DBDIR 复制到 /usr/local/etc/poudriere.d/jailename-portname-setname-options 来获得一个合适的起点。 这在 poudriere(8) 中有详细描述。例如,在一个名为 devset 的特定集合中测试 www/firefox,在 testport 命令中添加 -z devset 参数。

# poudriere testport -j 131Ramd64 -p development -z devset -o www/firefox

这将按照这个顺序寻找这些目录的存在:

  • /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) 挂载将第一个现有的目录树挂载到联编 jails 的 /var/db/ports 目录中。因此, 在这次运行 testport 的过程中, 所有的自定义选项都被用于所有的 port。

在提供了一套目录结构之后, 就可以改变某个特定 port 的选项了。例如:

# poudriere options -c www/firefox -z devset

显示了 www/firefox 的配置对话框,可以对选项进行编辑。 所选的选项会被保存到 devset 集合。

注意

Poudriere 在选项配置方面非常灵活。它们可以通过一个命令为特定的 jails、ports 以及多个 ports 进行设置。详情请参考 poudriere(8)

10.6.10. 提供一个自定义的 make.conf 文件

与使用集合类似, 如果提供了自定义的 make.conf , Poudriere 也会使用它。不需要特别的命令行参数。相反,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

与集合不同的是,所有找到的文件都会按 顺序 被追加到构建 jails 内的一个 make.conf 中。 因此,我们可以在 /usr/local/etc/poudriere.d/make.conf 中设置一般的 make 变量,以影响所有的构建。 可以在专门的 make.conf 文件中设置只影响某些 jail 或集合的特殊变量,即,,例如 /usr/local/etc/poudriere.d/131Ramd64-development-devset-make.conf

例1. 使用 make.conf 来改变默认的 Perl

要使用一个名为 perl5-20 的程序集来构建一个非默认的 Perl 版本,例如 5.20,请创建一个 perl5-20-make.conf ,其中包含这一行:

DEFAULT_VERSIONS+= perl=5.20

注意 += 的使用,这样如果该变量已经在默认的 make.conf 中设置,其内容就不会被覆盖了。

10.6.11. 修剪不再需要的磁盘文件

Poudriere 提供了一个内置的机制来删除那些不再被某一特定树的任何 port 使用的过时的 distfiles。命令是

# poudriere distclean -p portstree

将扫描 distfiles 文件夹, 即 poudriere.conf 中的 DISTFILES_CACHE, 并与 -p portstree 参数给出的 ports 进行对比, 然后提示删除这些 distfiles。要跳过提示并无条件地删除所有未使用的文件, 可以添加 -y 参数。

# poudriere distclean -p portstree -y

最后更新于

FreeBSD 中文社区