如何使用 Buildbot 和 Poudriere 为 FreeBSD 服务器构建和部署软件包

_ 作者选择了 免费和开源基金作为 写给捐款计划的一部分接受捐款。

介绍

[FreeBSD端口和软件包集 (https://www.freebsd.org/ports/),后称为_ports tree_,是FreeBSD用于外部软件的构建系统. 它提供一种基于Makefile的,连贯的建设套件方式. _port_指构建食谱,即Makefile和相关文件;而_package_指将一个端口建为包文件及其元信息的二进制(压缩)档案的输出.

手动建造和安装一个子集或所有30 000多个端口是有可能的。 然而,这栋大楼会运行在您的服务器上 而不是一个干净的环境。 对于生产使用案例,人工构建也意味着每个主机都需要相同的端口树修订,需要自行编译出所有包. 这意味着人类和服务器重复的,容易出错的工作. 最好在每个主机上取回并使用相同的,预建的二进制包,并从一个中央安全包寄存器中服务.

为此,Poudriere是FreeBSD上用于构建,测试,审计包以及维护包寄存器的标准工具. 每个构件被隔离在一个新鲜的 [jail (https://andsky.com/tech/tutorials/how-to-install-buildbot-freebsd# step-1-%E2%80%93-setting-up-jails-for-the-buildbot-master-and-worker) 中运行,运行所期望的FreeBSD版本,并开始没有安装软件包. 只有基础系统,加上任何明确规定的依赖性,可以用于清洁建筑. Poudriere负责在必要时重建软件包,并在一个构建完成后更新软件包寄存器. `poudriere'命令行工具是管理不同端口树、FreeBSD版本、端口构建选项以及最后运行构建的核心.

在本教程中,您将配置Poudriere,构建一组所需的包,设置基于HTTP的包托管,并使用Buildbot作为连续集成平台自动构建。

<$>[note] 注: 要涵盖类似生产的使用案例,教程示例使用 四分之一稳定分支的端口树)。 留在其中一个分支保护您免受改变,并在必要时提供安全性和修复,如果您定期更新树从上游(Subversion,或其GitHub镜子)。 您可以选择留在一个分支一个更长的时间,取决于您的系统更新可以由开发人员/基础设施团队处理的速度。 端口集合支持FreeBSD发布,直到它们成为终止寿命(EOL) - 参见 支持的FreeBSD发布 - 这样 OS 和包更新可以独立处理。 另一种方式,您可以考虑从上游树克隆的

前提条件

注意:从 2022 年 7 月 1 日开始,DigitalOcean 不再支持通过控制面板或 API 创建新的 FreeBSD Droplets. 但是,您仍然可以使用自定义图像创建 FreeBSD Droplets。

在开始本指南之前,您将需要:

如果您是新手使用 FreeBSD 11.2 的服务器,您可能会发现通过遵循我们在 How to Get Started with FreeBSD上的指南来定制此服务器有帮助。 ** 注意:** FreeBSD 12.0 目前有一个 与嵌入式监狱的问题的问题,首先需要在 12.x 之前进行修复,可以用于本教程。

  • 10 GB的自由磁盘空间或更多,足以存储包和日志。

步骤 1 — 安装Pudriere用于Buildbot Worker

完成前提教程后,你将有一个工作 Buildbot 主和工人监狱加上 Nginx 设置. 你将在以下步骤中建立这个现有设置。

连接到您的服务器托管 Buildbot,并使用以下命令在工人监狱中打开一个 root 壳:

1sudo jexec buildbot-worker0 csh

安装Pudriere作为一个包:

1[environment third]
2pkg install poudriere

然后通过按y来确认安装,然后按ENTER

<$>[注] ** 注意:** 最好使用官方的 FreeBSD 包存库来安装 Buildbot、Poudriere 等等. 如果你自己构建这些工具包,你会从一个鸡和鸡的情况开始:想要安装外部软件,但需要 Poudriere 安装才能获得清洁的包装。

如果你遵循了前提教程,这已经是情况,你可以继续不遵循这个注释。

美元

您已成功安装了最新的 Poudriere 工具和依赖程序. 在接下来的几个步骤中,您将通过配置 Poudriere 的准备工作进行。

步骤 2 — 创建包签名密钥(可选)

建议为嵌入式包设置数字签名,以提供更大的安全性。如果您想在以后或以不同的方式保护您的安装,请跳过此步骤。否则,让我们继续创建一个用于签名包(使用私钥)和验证包(使用公共部分)的密钥对。

文件包,默认情况下,是构建为 .txz 文件,这是强烈压缩的包内容。压缩文件的检查组合,以及通过 HTTP/HTTPS (TCP 检查组合) 服务的文件,已经提供了一些保护免受损坏的数据。 包内容通常包括文件和目录,加上 meta 信息,如包名称,版本和不同选项。 文件甚至可能包括 setuid-able 程序 (如在 sudo 包中看到 - 尽管 sudo 不是内置在 FreeBSD 中),并且安装时间脚本运行为 ** root 用户。 因此,从未经验证的来源安装带来安全风险。

通过通过 HTTPS 服务包,您无法检测是否有人篡改了磁盘上的包裹。 您可以通过配置 Poudriere 以使用 RSA 私钥签署包裹存储库来增加包裹的完整性和真实性。

在此步骤中,您将创建运行构建的密钥对(工人监狱),并下载公共部分以便在后续使用于包客户端(在稍后一步中讨论)。

确保你仍然在工人监狱 root 壳中。

创建一个新的 RSA 私钥:

1[environment third]
2openssl genrsa -out /usr/local/etc/poudriere.key 4096

只有 root 才能访问私钥文件,即运行 Poudriere 的用户。

1[environment third]
2chmod 0600 /usr/local/etc/poudriere.key

稍后,您将需要客户端可用的公钥部分来验证包签名,现在让我们提取公钥:

1[environment third]
2openssl rsa -in /usr/local/etc/poudriere.key -pubout -out /tmp/poudriere.pub

最后,从自己的计算机下载公钥文件:

1[environment local]
2scp your-server:/usr/jails/buildbot-worker0/tmp/poudriere.pub /tmp/poudriere.pub

这结束了为包签名创建可选的密钥对,您将随后配置实际签名,并在客户端上使用下载的公共密钥文件进行验证。

另一个可选步骤是:如果您使用 ZFS 文件系统,Poudriere 可以使用它来加速构建,否则,您可以跳过 步骤 4来配置 Poudriere,以便为运行第一个构建做好准备。

步骤 3 — 设置 ZFS (可选)

此步骤仅适用于在 ZFS 文件系统上运行 FreeBSD 系统时。 在此步骤中,您将创建可用于创建和管理监狱的文件系统,从而更快地加速您的构建。

您可以通过列出池列表来确定您是否使用 ZFS. 确保您在服务器的壳中,而不是监狱里。

1[environment third]
2exit

运行以下命令列出 zpools:

1sudo zpool list

如果有任何池可用,它将打印有关其信息:

1[secondary_label Output]
2NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
3zroot 148G 94.4G 54.1G        -         -    66%    63%  1.00x ONLINE  -

否则,如果没有 ZFS 支持,该工具将打印没有可用池未能初始化 ZFS 库,这意味着您的系统中没有使用 ZFS;在这种情况下,跳过下一步。

如果您打算使用 ZFS,请记住您要存储与构建相关的数据的打印池名称。

ZFS有助于分离Pudriere的各种数据集,如构建监狱,港口树,日志,包和其他数据,这些数据是独立存储的,因此可以快速删除,以确保不会留下空缺空间或痕迹。

为了让 Poudriere 使用 ZFS,你需要做三件事:创建一个主 ZFS 数据集,允许创建和删除 ZFS 数据集(Buildbot 工人监狱或任何其他监狱默认不能做),并相应地编辑 Poudriere 的配置。

在前提教程中,您将 Buildbot 工人监狱配置为 /etc/jail.buildbot-worker0.conf. 使用您喜爱的文本编辑器打开此文件,并添加以下突出的行来授权一个家长数据集,以便监狱在家长下面管理 ZFS 数据集。

1sudo ee /etc/jail.buildbot-worker0.conf
 1[label /etc/jail.buildbot-worker0.conf]
 2buildbot-worker0 {
 3    host.hostname = buildbot-worker0.localdomain;
 4    ip4.addr = "lo1|10.0.0.3/24";
 5    path = "/usr/jails/buildbot-worker0";
 6    exec.start = "/bin/sh /etc/rc";
 7    exec.stop = "/bin/sh /etc/rc.shutdown";
 8    mount.devfs; # need /dev/*random for Python
 9    persist;
10
11    exec.poststart = "/sbin/zfs jail buildbot-worker0 zroot/pdr/w0";
12}

在本文中,我们将存储与构建相关的数据在ZFS池中的zroot - 请在本文中以及在其他文章中调整这个与ZFS相关的配置,如果您选择了不同的名字。

添加此内容后,保存并退出编辑器. 如果您使用ee,请按CTRL+C,键入exit,然后按ENTER

创建在配置文件中提到的主 ZFS 数据集:

1sudo zfs create zroot/pdr
2sudo zfs create zroot/pdr/w0

故意假设您可能希望在未来添加更多员工,因此为您的第一个工作者创建一个子数据集. 数据集名称故意短,因为 FreeBSD 的旧版本(12.0 之前)有 88 个字符的安装名称限制。

为了监狱能够控制父母的数据集并管理任何儿童,该数据集必须标记下列旗帜:

1sudo zfs set jailed=on zroot/pdr/w0

有了现在的先决条件,监狱将以新的配置正确地开始:

1sudo service jail restart buildbot-worker0

使用这些说明,您成功创建了所需的文件系统 - ZFS 数据集 - 并允许监狱管理主数据集. 在下一步,您将配置 Poudriere,其中包括指定所选的 zpool 和数据集用于存储与构建相关的数据。

步骤 4 – 配置Pudriere,构建监狱和港口树

到目前为止,您已经安装了 Poudriere 并可选地覆盖了包签名和 ZFS 的要求. 为了使 Poudriere 能够以被困的方式运行,即从 Buildbot 工人监狱内部正确运作,您需要向监狱提供某些权限。

让我们先配置 loopback IP 和所有权限,然后通过相应的含义进行修改。

普德里埃想开始每个构建的两个构建监狱:一个只有循环网络和一个有互联网接入。只有构建阶段应该到达互联网将使用后者。例如,fetch可以下载源塔尔巴尔,但build阶段不允许互联网接入。工人监狱的现有配置有ip4.addr =lo1 Átha10.0.0.3/24,允许互联网接入。为了让普德里埃分配一个循环地址给新开始的构建监狱,IP也必须传递给其父母(工人监狱)。为了做到这一点,请确保您从先决条件的教程中应用了最新版本的防火墙配置文件/rus/local/cetip/fw.rules,这将阻止循环接口lo0通过NAT打开连接

将突出的行添加到您的工人监狱配置中:

1sudo ee /etc/jail.buildbot-worker0.conf
 1[label /etc/jail.buildbot-worker0.conf]
 2buildbot-worker0 {
 3    host.hostname = buildbot-worker0.localdomain;
 4    ip4.addr = "lo1|10.0.0.3/24";
 5    ip4.addr += "lo0|127.0.0.3";
 6    path = "/usr/jails/buildbot-worker0";
 7    exec.start = "/bin/sh /etc/rc";
 8    exec.stop = "/bin/sh /etc/rc.shutdown";
 9    mount.devfs; # need /dev/*random for Python
10    persist;
11
12    # If you followed the ZFS setup step, you have this line
13    # already (keep it). For non-ZFS setup, this line must be absent.
14    exec.poststart = "/sbin/zfs jail buildbot-worker0 zroot/pdr/w0";
15
16    allow.chflags;
17    allow.mount;
18    allow.mount.devfs;
19    allow.mount.nullfs;
20    allow.mount.procfs;
21    allow.mount.tmpfs;
22    allow.mount.zfs; # only needed if you use ZFS
23    allow.raw_sockets; # optional
24    allow.socket_af; # optional
25    allow.sysvipc; # optional
26    children.max=16;
27    enforce_statfs=1;
28}

在这里你已经添加了以下内容(也参见 jail(8) manpage):

  • ip4.addr'lo0'|127.0.0.3'在监狱增加了另一个IPv4地址. 之后您将配置 Poudriere 的 LOIP4 变量, 以便指定这个回回地址来建造监狱, 这些监狱不应该与互联网或网络中的其他机器交谈, 如在 建设 阶段。 Poudriere支持一个变量ALLOW_NETWORKING_PACKAGES。 然而,在Poudriere允许互联网进入的 " 牵线搭桥 " 阶段,最好遵循最佳做法,进行下载,并更早地完成其他上网任务。 *allow.chflags'允许Poudriere在建造监狱中制作/bin/sh'等系统文件。
  • allow.mount'和另一个allow.mount.* 选项使Poudriere能够将某些必要的文件系统上载入已建监狱。 *allow.raw-sockets'允许使用生接头,而allow.socket-af'允许使用任何接头地址的家庭,两者都适用于互联网有能力的建设监狱。 这样做很有帮助,这样你就可以在互动模式下运行平`等工具,比如进入建设监狱去调试问题。
  • 'allow.sysvipc'被贬损,有利于三种独立的设置'sysvmsg'/'sysvsem'/'sysvshm',以限制监狱只能看到自己共享的记忆对象(通过"SYS V" IPC原始人). 然而,Poudriere只能通过allow.sysvipc'来建造监狱,因为它不能读取三个独立参数(如FreeBSD 11.2)的相关sysctl信息. 通过这种被贬损的配置,监狱可以读取监狱外过程的共同记忆. 这只与某些依赖于IPC特性的软件有关,如PostgreSQL,因此影响安全的机会很小. 您可以删除此配置, 除非您依赖于在构建过程中需要的端口 。 *Children.max=16'允许在工人监狱以下关押16所子监狱。 如果你有很多CPU和Poudriere试图制造比允许的更多建造监狱,你可以以后再增加这个数字. 每个波德里耶建筑将尝试每"工作"创建一个参考监狱并建造两个监狱,它的默认是使用CPU的数量(由‘sysctl-n hw.ncpu'输出)作为工作计数.
  • enforce-statfs=1'与allow.mount'一起需要 " 以挂载某些文件系统。

保存和退出配置文件。

重新启动监狱,以便其配置立即产生影响:

1sudo service jail restart buildbot-worker0

各自的内核模块必须加载,以便Poudriere可以执行安装。运行以下命令,在启动时立即加载模块:

1sudo sysrc -f /boot/loader.conf nullfs_load=YES
2sudo kldload -n nullfs
3sudo sysrc -f /boot/loader.conf tmpfs_load=YES
4sudo kldload -n tmpfs

您早些时候已经安装了 Poudriere 包,该包已将样本文件 /usr/local/etc/poudriere.conf.sample 复制到 /usr/local/etc/poudriere.conf. 接下来,您将对配置文件进行编辑。

对于下列命令,请确保您仍然在工人监狱中的 root 壳中:

1sudo jexec buildbot-worker0 csh

用以下命令打开文件:

1[environment third]
2ee /usr/local/etc/poudriere.conf

如果您已决定使用 ZFS,请填写您想要的 zpool 和家长数据集:

 1[label /usr/local/etc/poudriere.conf (snippet)]
 2. . .
 3# Poudriere can optionally use ZFS for its ports/jail storage. For
 4# ZFS define ZPOOL, otherwise set NO_ZFS=yes
 5#
 6#### ZFS
 7# The pool where poudriere will create all the filesystems it needs
 8# poudriere will use ${ZPOOL}/${ZROOTFS} as its root
 9#
10# You need at least 7GB of free space in this pool to have a working
11# poudriere.
12#
13ZPOOL=zroot
14
15### NO ZFS
16# To not use ZFS, define NO_ZFS=yes
17#NO_ZFS=yes
18
19# root of the poudriere zfs filesystem, by default /poudriere
20ZROOTFS=/pdr/w0
21. . .

否则,如果您决定反对 ZFS,请禁用 ZFS 支持:

 1[label /usr/local/etc/poudriere.conf (snippet)]
 2. . .
 3# Poudriere can optionally use ZFS for its ports/jail storage. For
 4# ZFS define ZPOOL, otherwise set NO_ZFS=yes
 5#
 6#### ZFS
 7# The pool where poudriere will create all the filesystems it needs
 8# poudriere will use ${ZPOOL}/${ZROOTFS} as its root
 9#
10# You need at least 7GB of free space in this pool to have a working
11# poudriere.
12#
13#ZPOOL=zroot
14
15### NO ZFS
16# To not use ZFS, define NO_ZFS=yes
17NO_ZFS=yes
18
19# root of the poudriere zfs filesystem, by default /poudriere
20# ZROOTFS=/poudriere
21. . .

後來你會指示Poudriere下載 FreeBSD 基礎系統,從而啟動第一個 build 監獄,這需要指定下載主機,添加以下突出的行:

 1[label /usr/local/etc/poudriere.conf (snippet)]
 2. . .
 3# the host where to download sets for the jails setup
 4# You can specify here a host or an IP
 5# replace _PROTO_ by http or ftp
 6# replace _CHANGE_THIS_ by the hostname of the mirrors where you want to fetch
 7# by default: ftp://ftp.freebsd.org
 8#
 9# Also note that every protocols supported by fetch(1) are supported here, even
10# file:///
11# Suggested: https://download.FreeBSD.org
12FREEBSD_HOST=https://download.FreeBSD.org

由于 Poudriere 将被关押,因此在 12.0 之前 FreeBSD 版本的 88 个字符的安装名称限制特别有害,因为监狱 /usr/jails/buildbot-worker0 的完整路径是每个安装路径的一部分。

1[label /usr/local/etc/poudriere.conf (snippet)]
2. . .
3# The directory where poudriere will store jails and ports
4BASEFS=/pdr

现在,创建这个目录:

1[environment third]
2mkdir /pdr

再次切换到您的poudriere.conf编辑器:

1[environment third]
2ee /usr/local/etc/poudriere.conf

Poudriere 在运行 Build 时将为 dist files (每个端口的源代码 tarballs) 设置一个中央目录,以便所有构建者共享相同的缓存。

1[label /usr/local/etc/poudriere.conf (snippet)]
2. . .
3# If set the given directory will be used for the distfiles
4# This allows to share the distfiles between jails and ports tree
5# If this is "no", poudriere must be supplied a ports tree that already has
6# the required distfiles.
7DISTFILES_CACHE=/usr/ports/distfiles

现在,创建这个目录:

1[environment third]
2mkdir -p /usr/ports/distfiles

如果您按照步骤 2 创建了包库签名密钥,请再次输入编辑器并指定它:

1[environment third]
2ee /usr/local/etc/poudriere.conf
1[label /usr/local/etc/poudriere.conf (snippet)]
2. . .
3# Path to the RSA key to sign the PKG repo with. See pkg-repo(8)
4PKG_REPO_SIGNING_KEY=/usr/local/etc/poudriere.key

如果您下次将 C/C++ 编译器和链接器输出缓存,Builds 将运行更快。Ports tree 通过利用工具 ccache直接支持此功能。请启用它并创建相应的缓存目录,如果您可以节省至少 5 GB 的空间(默认缓存大小):

1[label /usr/local/etc/poudriere.conf (snippet)]
2. . .
3# ccache support. Supply the path to your ccache cache directory.
4# It will be mounted into the jail and be shared among all jails.
5# It is recommended that extra ccache configuration be done with
6# ccache -o rather than from the environment.
7CCACHE_DIR=/var/cache/ccache
1[environment third]
2mkdir /var/cache/ccache

构建和运行Linux软件并不常见,所以在需要时禁用它:

1[environment third]
2ee /usr/local/etc/poudriere.conf
1[label /usr/local/etc/poudriere.conf (snippet)]
2. . .
3# Disable linux support
4NOLINUX=yes

我们可以继承监狱的IP,因为它是在一个仅限于循环的网络接口(lo1)。

1[label /usr/local/etc/poudriere.conf (snippet)]
2LOIP4=127.0.0.3

保存和退出配置文件。

对于工作构建,我们需要两种资源:一个FreeBSD基础系统作为构建监狱模板和一个最新的端口树。选择你正在瞄准的FreeBSD版本。在本教程中,我们将告诉Pudriere下载FreeBSD 11.2用于amd64架构。你可以随心所欲地命名监狱,但建议使用像112amd64这样的一致命名方案。 同时,要记住选择季度、稳定的端口树分支(在这里,我们使用2019Q2)和流血边缘分支,这可能会导致随时更新之后的破坏构建。

下载并创建构建监狱:

1[environment third]
2poudriere jail -c -j 112amd64 -v 11.2-RELEASE -a amd64

最后,让我们下载端口树. 默认下载方法是 portsnap,它使用不包含历史信息的压缩树的快照。 Subversion 或 Git 最好是合并上游变更或贡献回来。

如果你想从上游开始,官方的港口树:

1[environment third]
2poudriere ports -c -p 2019Q2 -m svn+https -B branches/2019Q2

方法 svn+https 将同步从 FreeBSD Subversion 主机(可在这里在线查看)。

<$>[注] 注: 作为替代方法,git从GitHub上的镜子(https://github.com/freebsd/freebsd-ports/)克隆树。

要使用头部分支,用-B头部(对于 Subversion)或-B大师(对于 Git)取代最后一个参数。

如果您更喜欢使用自己的 Git 存储库,则必须明确指定您的存储库 URL 和分支名称,假设您想要命名您的树自定义树,并使用自定义分支:

1[environment third]
2poudriere ports -c -p customtree -m git -B custom -U https://github.com/AndiDog/freebsd-ports.git

示例 URL 指向 GitHub 上的一些 freebsd 端口,但可能是 CI 服务器可以访问的任何 Git 或其他支持类型的存储库。

美元

可用的树木可以被列为 poudriere 端口 -l,从而产生类似的列表:

1[secondary_label Output]
2PORTSTREE METHOD TIMESTAMP PATH
32019Q2 svn+https 2019-04-20 19:23:19 /pdr/ports/2019Q2

您已经完成了 Poudriere 配置和资源的设置,您已经配置了 Poudriere 与所需的数据,以触发第一个构建,并允许监狱创建子格式。

步骤 5 – 运行手动测试构建

您可以使用poudriere bulk命令来构建一个或多个包和其所有依赖性。在第一次构建一个包后,Poudriere还会自动检测重建是否必要,或者否则将现有的包文件留下不受影响。而bulk子命令只构建包,运行使用poudriere testport构建还会使用端口的Makefile中提供的测试定义来测试指定的端口。对于本文的范围,我们只关心在客户端上提供安装的包,所以我们正在使用批量构建。

确保你仍然处于你安装了Poudriere的工人监狱的根壳中,后来,这也将是Buildbot工人流程自动运行的构建。

运行 build,用您之前选择的 build 监狱名和 ports 树名填充位置持有者:

1[environment third]
2poudriere bulk -j 112amd64 -p 2019Q2 ports-mgmt/pkg

这构建了端口 ports-mgmt/pkg. 官方树中的端口存储在一个 <category>/<name> 等级,这些路径(称为 package origin)被用来告诉Poudriere应该构建哪些包。 首先,我们选择只构建包管理器 pkg,它没有任何第三方依赖,因此是一个很好的,快速的配置检查。 如果一切顺利,你会看到这样的输出:

 1[secondary_label Output]
 2[00:00:00] Creating the reference jail... done
 3[00:00:06] Mounting system devices for 112amd64-2019Q2
 4[00:00:06] Mounting ports/packages/distfiles
 5[00:00:06] Using packages from previously failed build
 6[00:00:06] Mounting ccache from: /var/cache/ccache
 7[00:00:06] Mounting packages from: /pdr/data/packages/112amd64-2019Q2
 8/etc/resolv.conf -> /pdr/data/.m/112amd64-2019Q2/ref/etc/resolv.conf
 9[00:00:06] Starting jail 112amd64-2019Q2
10[00:00:07] Logs: /pdr/data/logs/bulk/112amd64-2019Q2/2019-04-20_19h35m00s
11[00:00:07] Loading MOVED for /pdr/data/.m/112amd64-2019Q2/ref/usr/ports
12[00:00:08] Ports supports: FLAVORS SELECTED_OPTIONS
13[00:00:08] Gathering ports metadata
14[00:00:08] Calculating ports order and dependencies
15[00:00:08] pkg package missing, skipping sanity
16[00:00:08] Skipping incremental rebuild and repository sanity checks
17[00:00:08] Cleaning the build queue
18[00:00:08] Sanity checking build queue
19[00:00:08] Processing PRIORITY_BOOST
20[00:00:08] Balancing pool
21[00:00:08] Recording filesystem state for prepkg... done
22[00:00:08] Building 1 packages using 1 builders
23[00:00:08] Starting/Cloning builders
24[00:00:14] Hit CTRL+t at any time to see build progress and stats
25[00:00:14] [01] [00:00:00] Building ports-mgmt/pkg | pkg-1.10.5_5
26[00:03:24] [01] [00:03:10] Finished ports-mgmt/pkg | pkg-1.10.5_5: Success
27[00:03:25] Stopping 1 builders
28[00:03:25] Creating pkg repository
29Creating repository in /tmp/packages: 100%
30Packing files for repository: 100%
31[00:03:25] Committing packages to repository
32[00:03:25] Removing old packages
33[00:03:25] Built ports: ports-mgmt/pkg
34[112amd64-2019Q2] [2019-04-20_19h35m00s] [committing:] Queued: 1 Built: 1 Failed: 0 Skipped: 0 Ignored: 0 Tobuild: 0 Time: 00:03:18
35[00:03:25] Logs: /pdr/data/logs/bulk/112amd64-2019Q2/2019-04-20_19h35m00s
36[00:03:25] Cleaning up
37[00:03:25] Unmounting file systems

此输出显示了在构建后包将到哪里去,以及如果不需要重新构建的现有包将从哪里来(这里: /pdr/data/packages/112amd64-2019Q2)。 此外,输出显示了在 Poudriere 运行时运行的 builds 的概述(您可以在互动壳中按 CTRL+T 来打印进展)。 在最后的总结中,您将看到一个包已经构建。 在日志目录中,您可以查看 verbose build 输出(`/pdr/data/logs/bulk/112amd64-2019Q2/*)。

如果 Poudriere 成功构建了至少一个软件包,它会自动将其连接到软件包存储库中,这意味着软件包仅在所有软件包完成后才可用,即使其他软件包未能构建,您现在在 Buildbot 工人监狱中有工作软件包存储库在 /pdr/data/packages/112amd64-2019Q2

您已经完成了返回工作 Poudriere 构建所需的所有配置,并且您已成功通过手动构建进行验证。在您在 Buildbot 中自动化大批量构建后,您将在教程中稍后看到相同的输出。

步骤 6 — 配置 Nginx 来服务 Poudriere Web 界面和包库

Poudriere提供几个输出文物,我们希望使用Web服务器来托管:

  • 包存存储库 被提供给客户端,以便他们可以使用常规的pkg更新pkg安装命令访问它们,使用HTTPS或HTTP作为运输。* ** 详细的构建日志** 对开发人员进行调试或调查问题构建输出有帮助。它们被存储在每个包和每个构建上 - 在Pudriere输出中,从最后一步,你可以看到日志被存储在每个构建的一个目录中,标记为日期和时间。* ** Poudriere的内置网页接口** 是每个构建的一个小,单一的HTML页面,它使用WebSockets来定期更新页面上显示的状态。

Nginx 的配置更改很短,因为只需要服务静态文件. 因为你将为外部世界提供服务,你现在要在外部监狱的服务器上配置现有的 Nginx 实例,以便从工人监狱内部的路径服务上述文件。

请退出监狱壳,因为你现在将在服务器上工作:

1[environment third]
2exit

使用 Nginx 配置 /usr/local/etc/nginx/nginx.conf 打开编辑器:

1sudo ee /usr/local/etc/nginx/nginx.conf

服务器 { 块中添加以下位置:

 1[label /usr/local/etc/nginx/nginx.conf]
 2. . .
 3http {
 4    . . .
 5    server {
 6        . . .
 7        location / {
 8            root /usr/local/www/nginx;
 9            index index.html index.htm;
10        }
11
12        # poudriere logs
13        location ~ ^/logs(/(.*))?$ {
14            include mime.types;
15            types {
16                text/plain log;
17            }
18
19            alias /usr/jails/buildbot-worker0/pdr/data/logs/bulk$1;
20            index index.html index.htm;
21            autoindex on;
22        }
23
24        # poudriere packages
25        location ~ ^/packages(/(.*))?$ {
26            alias /usr/jails/buildbot-worker0/pdr/data/packages$1;
27            index no-index-file-but-required-directive-to-list-dir-contents;
28            autoindex on;
29        }
30
31        location /buildbot/ {
32            proxy_pass http://10.0.0.2:8010/;
33        }
34
35        . . .
36    }
37}
38. . .

保存并关闭 Nginx 配置文件,然后重新加载 Nginx 服务:

1sudo service nginx reload

现在让我们看看第一个手动构建创建的文物,在本地机器上打开您喜爱的网页浏览器以访问资源。

package repository 在以下位置是 https://your-domain/packages/(或 http://your-server-ip/)。您将在根目录中找到元信息,例如 112amd64-2019Q2,并在子目录 All中找到所有内置的软件包:

Package repository listing

详细的构建日志 和 ** Poudriere的内置 Web 接口** 可以在下面找到:https://your-domain/logs/. 点击目录等级来访问您以前的手动构建的数据。 在此示例中,您可能会找到一个 URL 如:https://your-domain/logs/112amd64-2019Q2/latest/build.html

Poudriere web interface

如果您没有为您的服务器设置域名,则需要为这些示例输入服务器的公共 IP 地址,例如 http://your-server-ip/logs/

这结束了所有手动设置,以获得工作构建,并在输出(包和日志)中获得可见性。

步骤 7 — 为您的包设置一个Buildbot Builder

在此步骤中,你的目标是通过手动执行 Poudriere 来自动化批量组件构建,通过将其添加到现有的 Buildbot 样本配置中。

所有必要的更改都发生在 Buildbot 主配置中,所以请在主监狱中打开一个 root 壳:

1sudo jexec buildbot-master csh

在现有的配置 /var/buildbot-master/master.cfg,你会找到一个部分 ######### BUILDERS - 打开一个编辑器,并 代替 整个部分,直到下一个标题开始于 # ...,具有以下配置:

1[environment second]
2ee /var/buildbot-master/master.cfg
 1[label /var/buildbot-master/master.cfg (snippet)]
 2. . .
 3####### BUILDERS
 4
 5c['builders'] = []
 6
 7PORTS_TO_BUILD = {
 8    'security/sudo',
 9    'shells/bash',
10    'sysutils/tmux',
11}
12
13# Custom classes
14class PoudriereLogLineObserver(util.LogLineObserver):
15    _logsRe = re.compile(r'Logs: /pdr/data/logs/bulk(/[-_/0-9A-Za-z]+)$')
16
17    def __init__(self):
18        super().__init__()
19        self._hadUrls = False
20
21    def outLineReceived(self, line):
22        if not self._hadUrls:
23            m = self._logsRe.search(line.strip())
24            if m:
25                poudriereUiUrl = f'''{re.sub('/buildbot/$', '', c['buildbotURL'])}/logs{m.group(1)}'''
26                self.step.addURL('Poudriere build', poudriereUiUrl)
27                self.step.addURL('Poudriere logs', poudriereUiUrl + '/logs/')
28                self._hadUrls = True
29
30class PoudriereCompileStep(steps.Compile):
31    def __init__(self, *args, **kwargs):
32        super().__init__(*args, **kwargs)
33        self.addLogObserver('stdio', PoudriereLogLineObserver())
34
35# Poudriere bulk build
36bulkBuildFactory = util.BuildFactory()
37bulkBuildFactory.addSteps([
38    steps.ShellCommand(
39        name='update ports tree',
40        command=['sudo', 'poudriere', 'ports', '-u', '-p', '2019Q2', '-v'],
41        haltOnFailure=True,
42    ),
43    PoudriereCompileStep(
44        name='make bulk',
45        command=['sudo', 'poudriere', 'bulk', '-j', '112amd64', '-p', '2019Q2'] + list(sorted(PORTS_TO_BUILD)),
46        haltOnFailure=True,
47    ),
48])
49c['builders'].append(util.BuilderConfig(name='bulk-112amd64-2019Q2',
50                                        workernames=['worker0'],
51                                        factory=bulkBuildFactory))
52. . .

注意如何利用Buildbot的可扩展性:自定义类被用来观察和分析来自Poudriere的日志输出的信息,即PoudriereLogLineObserver被添加为日志观察员,即每当在构建过程中打印一个新的日志行时都会被调用。

在第一个构建步骤更新端口树中,我们使用Poudriere的内置更新命令(ports -u)将端口树的最新版本拉动。这将自动使用先前配置的方法(例如 SVN/Git)。

在顶部,列表PORTS_TO_BUILD指定哪些端口应该建造。它被用在块底部指定的 build factory 步骤中。Build factory 是一个用于实例化 build 的模板。Buildbot 每次启动一个 build 时创建一个独特的 build,而 Buildbot 使用当时为 Build factory 定义的步骤的副本。

  • 更新端口树. 由于此示例使用季度分支 2019Q2,它不会经常收到更改(通常只有安全和构建修复)。

要使添加的代码块工作,请将所需的导入添加到文件的顶部:

1[label /var/buildbot-master/master.cfg (snippet)]
2# -*- python -*-
3# ex: set filetype=python:
4
5import re
6
7from buildbot.plugins import *

Python中的re库实现了 regular expressions,该功能用于搜索或更换字符串的部分 - 该PoudriereLogLineObserver类用于搜索提到日志目录的行日志: /pdr/data/logs/...

构建命令使用sudo来运行某些命令,这是必要的,因为Poudriere在运行构建时需要超级用户权限 - 以创建,管理和破坏构建监狱 - 并且由Poudriere管理的端口树也是由 root 用户创建的。在上一课中,我们将运行 Buildbot 工人流程的用户配置为sysrc buildbot_worker_uid=buildbot-worker。因此,我们希望允许buildbot-worker用户以 root 来运行确切所需的命令,而不是其他命令(出于安全原因)。

这需要在工人监狱里做,而不是主人。请离开主监狱壳,进入工人监狱:

1[environment second]
2exit
1sudo jexec buildbot-worker0 csh

安装sudo包:

1[environment third]
2pkg install sudo

yENTER确认安装。

在 FreeBSD 上, sudo 包默认读取了从 /usr/local/etc/sudoers.d/ 的配置文件。

1[environment third]
2env EDITOR=ee visudo /usr/local/etc/sudoers.d/buildbot-worker

使用visudo是故意的,因为它会警告语法错误,并允许修复它们,而不是犯下错误的配置。

指定哪个命令buildbot-worker用户可以作为 root 运行而不需要任何密码:

1[label /usr/local/etc/sudoers.d/buildbot-worker]
2buildbot-worker ALL=(ALL) NOPASSWD: /usr/local/bin/poudriere bulk *
3buildbot-worker ALL=(ALL) NOPASSWD: /usr/local/bin/poudriere ports -u *

保存文件并返回主监狱,以便进一步配置 Buildbot 主机:

1[environment third]
2exit
1sudo jexec buildbot-master csh

但是,正如所提到的,每个 build 必须是 triggered 才能运行. Buildbot 使用 scheduler 术语来定义一个对象,该对象定义了什么时候启动一个 build,以及哪些额外的信息,例如哪个分支被更改。

1[environment second]
2ee /var/buildbot-master/master.cfg
 1[label /var/buildbot-master/master.cfg (snippet)]
 2. . .
 3####### SCHEDULERS
 4
 5c['schedulers'] = []
 6
 7# Forceful scheduler allowed for all builders
 8c['schedulers'].append(schedulers.ForceScheduler(
 9    name='force',
10    builderNames=[builder.name for builder in c['builders']]))
11
12# Watch ports tree for changes on given branch
13c['schedulers'].append(schedulers.SingleBranchScheduler(
14    name='sched-bulk-112amd64-2019Q2',
15    change_filter=util.ChangeFilter(project='freebsd-ports', branch='branches/2019Q2'),
16    builderNames=['bulk-112amd64-2019Q2']))
17. . .

这取代了样本配置,以便在每个构建器上出现一个 force 按钮。最重要的是,它创建了一个计时器,可以监控与所述项目/分支相关的所有更改,并为每个更改启动一个 build。然而,没有任何这样的更改事件可能发生――你必须首先创建一个 _change source。 通常,这些都是 SVN 或 Git 等版本控制系统,可以检测到一个分支的更改。 Buildbot 支持最受欢迎的,所以我们可以使用其功能来添加我们选择的上游端口树库作为源。

 1[label /var/buildbot-master/master.cfg (snippet)]
 2. . .
 3####### CHANGESOURCES
 4
 5c['change_source'] = []
 6
 7c['change_source'].append(changes.SVNPoller(
 8    'svn://svn.freebsd.org/ports/',
 9    project='freebsd-ports',
10    split_file=util.svn.split_file_branches,
11    svnbin='svnlite',
12    pollInterval=4 * 3600))
13
14# Example for Git:
15# c['change_source'].append(changes.GitPoller(
16#     repourl='https://github.com/AndiDog/freebsd-ports.git',
17#     project='freebsd-ports',
18#     branches=['custom'],
19#     pollInterval=4 * 3600))
20. . .

这在Buildbot主机上每四个小时都会对SVN存储库进行调查,任何新的(以前没有看到的)更改都会转发到匹配的日程表,这反过来会触发最终发送到我们单个Buildbot worker上运行的 builds。

通过重新启动 Buildbot 来应用新的配置文件:

1[environment second]
2service buildbot restart

在本示例中,您已经使用了来自svn://svn.freebsd.org/ports/的上游端口集合,并且每当分支2019Q2发生更改时,都会设置构建。

打开您的 Buildbot Web 界面(https://your-domain/buildbot/),导航到 Builds > Builders > bulk-112amd64-2019Q2 . 它还不会显示任何构建。

Bulk builder page – no builds yet

点击右上角的 force 按钮,然后点击 ** Start Build** . 这将触发使用其默认设置的构建,也就是说,原因,分支和其他值不会被夸大。

Successful build

点击其中一个链接( Poudriere build 和 ** Poudriere logs** )将带您到 Poudriere Web 界面,分别为此特定 build 创建日志(如步骤 6 所示)。

完成第一个构建后,这些包现在可用,如在步骤 6 中配置在 Nginx 中。在浏览器中点击 https://your-domain/packages/(或 http://your-server-ip/packages/),然后点击由 Poudriere 创建的包存库。一旦您输入其中一个库存,您可以找到实际的包存文件(*.txz)并导航到 All/ 子目录。

List of package repositories

现在,通过 HTTPS (或 HTTP 如果您选择) 提供包,并且自动建立在端口树变更上,您可以配置一个或多个主机来使用这些包。

第8步:配置包客户端

在此步骤中,您需要第二台 FreeBSD 服务器,并将其设置为可以检索和安装 CI 服务器上的包。

SSH 进入 客户端 主机.本节中的大多数剩余指令将在 ** 客户端** 上执行:

1[environment local]
2ssh package-client

创建自定义包库配置目录:

1[environment fourth]
2sudo mkdir -p /usr/local/etc/pkg/repos

作为 root 用户,打开编辑器来创建文件 /usr/local/etc/pkg/repos/ci.conf,并指定如何以及从哪里获取包:

1[environment fourth]
2sudo ee /usr/local/etc/pkg/repos/ci.conf

如果您选择了包签名,请使用此内容:

1[label /usr/local/etc/pkg/repos/ci.conf]
2ci: {
3    url: "https://your-domain/packages/112amd64-2019Q2",
4    signature_type: "pubkey",
5    pubkey: "/usr/local/etc/pkg/repos/ci.pub",
6    enabled: yes
7}

或者,如果您决定不签名包,请如下禁用签名检查:

1[label /usr/local/etc/pkg/repos/ci.conf]
2ci: {
3    url: "https://your-domain/packages/112amd64-2019Q2",
4    signature_type: "none",
5    enabled: yes
6}

<$>[注] ** 注意:** 此注释仅适用于您按照步骤 2 创建包库签名密钥时。

从您的 本地机器 上传公共密钥到包客户端:

1scp /tmp/poudriere.pub package-client:/tmp/ci.pub

再次使用 客户端壳 ,将密钥移动到位,以便它可以验证包的真实性:

1[environment fourth]
2sudo mv /tmp/ci.pub /usr/local/etc/pkg/repos/ci.pub

美元

您已完成配置包库并启用它,但在正常的FreeBSD安装中,官方的包库FreeBSD也将被启用。混合来自不同来源的安装包是一种无误的方式,以便您的生产软件在某个时候由于不兼容的软件版本或不同的ABI、API或构建选项而崩溃。

官方存储库的默认配置存储在 /etc/pkg/FreeBSD.conf 中。 该文件属于基础系统,不应该被触摸。 但是,您可以取消其设置,即,我们希望完全禁用存储库,通过在 /usr/local/etc/pkg/repos下配置文件中添加相应的旗帜,其中也配置了您自己的存储库。 请使用编辑器创建一个新的 /usr/local/etc/pkg/repos/FreeBSD.conf’ 文件,并使用以下内容禁用 FreeBSD 存储库:

1[environment fourth]
2sudo ee /usr/local/etc/pkg/repos/FreeBSD.conf
1[label /usr/local/etc/pkg/repos/FreeBSD.conf]
2FreeBSD: {
3    enabled: no
4}

如果您在一个完全原始的 package client 主机上,尚未安装任何包裹,并且您可以立即开始使用自己的包裹存储库。 但是,如果仅有一个包裹从另一个源头安装,建议您将这些包装卸载,并从零开始使用自己的源头。 包裹管理器pkg本身作为一个包装被安装,以解决鸡蛋问题,FreeBSD 的基层系统将配备一个小型可执行的 /usr/sbin/pkg,这可以启动包装管理器。 也就是说,下载 pkg包,并将其安装为系统上的第一个包装。 从那时起,该包的可执行的/usr/local/sbin/pkg 将支持您作为完整的包装管理器。

运行下列命令来 bootstrap pkg:

1[environment fourth]
2sudo pkg bootstrap

在「pkg bootstrap」的输出中,你应该看到包是从你自己的包库中提取的,我们在配置文件中称之为「ci」。

1[secondary_label Output]
2The package management tool is not yet installed on your system.
3Do you want to fetch and install it now? [y/N]: y
4Bootstrapping pkg from https://your-domain/packages/112amd64-2019Q2, please wait...
5Verifying signature with public key /usr/local/etc/pkg/repos/ci.pub... done
6Installing pkg-1.10.5_5...
7Extracting pkg-1.10.5_5: 100%

如果您看到此成功的输出,请跳过下一个笔记本,但是,如果软件包管理器或其他软件包已经从另一个来源安装,您会收到此错误:

1[secondary_label Output]
2pkg already bootstrapped at /usr/local/sbin/pkg

然后,请遵循笔记中的指示。

<$>[注] ** 注意 – 只有如果已启动了包管理器:**

您可以列出已安裝的套件,包含「pkg info」。在這種情況下,您應該卸載所有套件,包括「pkg」,然後稍後重新安裝。 要做到這一點,請先列出手動安裝的套件,包括「pkg query -e "%a==0" "%n"」。 請記住,您希望稍後重新安裝哪個套件。 例如,如果您使用的是不屬於基礎系統的一部分(例如, bash 是外部套件),您可能會想要稍後重新安裝,或者您可能無法再次登入。

以下命令将删除所有现有的包和包管理器,从您自己的包库中重新启动包管理器,并提供重新安装您想要的包的示例,如 bash. 但是请注意,您只将能够安装您通过 CI 构建的包,即列入 Buildbot 主配置(变量 PORTS_TO_BUILD)。

首先,在卸载sudo包之前,请打开一个 root 壳,否则您可能无法再获得超级用户权限,直到您通过教程启动pkg并成功重新安装sudo为止。

1[environment fourth]
2sudo sh

移除所有包,包括「pkg」:

1[environment fourth]
2pkg delete --all --force

Bootstrap 包管理器:

1[environment fourth]
2pkg bootstrap

通过按y来确认启动包管理器,然后按ENTER

美元

在您使用 Let's Encrypt 证书为 HTTPS 设置包主机的可能情况下,您将遇到鸡蛋问题,您的包主机不受信任,但您需要安装包 ca_root_nss(包含可信根证书权威)来信任 Let's Encrypt CA,从而也信任服务器托管您的自定义包。

1[secondary_label Output]
2The package management tool is not yet installed on your system.
3Do you want to fetch and install it now? [y/N]: y
4Bootstrapping pkg from https://example.com/packages/112amd64-2019Q2, please wait...
5Certificate verification failed for /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
634389740104:error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed:/usr/src/crypto/openssl/ssl/s3_clnt.c:1269:
7[...]

如果您看到此错误,请遵循下面的说明,否则,您将全部设置,可以跳过此部分,并在笔记后继续。

<$>[注] 注:仅在使用HTTPS和证书验证失败的情况下:

有一个简单的解决方案:信任包签名密钥的安全性,因此启动pkg并通过未加密的HTTP安装ca_root_nss包. 由于这并不总是是一个选择,因为隐私问题,封锁的HTTP端口等,我们应该更喜欢一种最佳实践方式。 官方的FreeBSD存储库也由Let’s Encrypt签名,所以我们不能简单地从那里安装ca_root_nss包。 无论它是哪个CA,您都建议设置您的包客户端用固定的HTTPS CAs来信任。 您可以确切地实现在接下来的几条指令中。 我们将假定这就是Let’s Encrypt,但指令将为您的自签名CA(您将需要其证书链

在您的 Web 浏览器中,请访问 Let's Encrypt 的证书列表在 https://letsencrypt.org/certificates/。 请确保网站是由浏览器信任的。 下载证书在 Root Certificates > Active > ISRG Root X1 (自签名) 和 ** Intermediate Certificates > Active > Let's Encrypt Authority X3 (由 ISRG Root X1 签名)** 的 PEM 格式下载到您的本地计算机上的 /tmp/root.pem/tmp/intermediate.pem

在下载成功后,将文件连接成一个证书链:

1cat /tmp/intermediate.pem /tmp/root.pem >/tmp/letsencrypt-chain.pem
1scp /tmp/letsencrypt-chain.pem package-client:/tmp/.

** 回到包客户端的壳中** ,您现在需要在包管理器配置中指定这个信任链 /usr/local/etc/pkg.conf,以便用于 TLS 验证。

1[environment fourth]
2sudo ee /usr/local/etc/pkg.conf
1[label /usr/local/etc/pkg.conf (snippet)]
2pkg_env: {
3    SSL_CA_CERT_FILE: "/usr/local/etc/pkg/repos/letsencrypt-chain.pem",
4}

把链子移动到位置:

1[environment fourth]
2sudo mv /tmp/letsencrypt-chain.pem /usr/local/etc/pkg/repos/.

如果您一直留在根壳中,因为 sudo 包被删除,则该命令必须在没有sudo的情况下运行。

有了这个设置,你可以再次尝试启动,并且不应该再收到任何TLS错误。有一个小转折点:内置的FreeBSD /usr/sbin/pkg,它启动了完整的包管理器,不尊重配置的 pkg_env设置,所以我们只需要一次重置相应的环境变量,使用相同的配置值:

1[environment fourth]
2sudo env SSL_CA_CERT_FILE=/usr/local/etc/pkg/repos/letsencrypt-chain.pem pkg bootstrap

美元

如果您之前已经删除了现有软件包,现在是重新安装必要的工具(例如 sudo)以及任何其他所需的软件包的好时机。

1[environment fourth]
2pkg install bash sudo

然后从根壳中掉下来,如果仍然是这样的话:

1[environment fourth]
2exit

要测试一切是否正常,请从 Buildbot 主配置中指定的列表中安装包(变量 PORTS_TO_BUILD)。

1[environment fourth]
2sudo pkg install bash sudo tmux

再次,通过按y来确认安装,然后按ENTER

您可以使用「pkg info」列出目前安装的软件包(包括依赖性,如果有)。 要验证没有来自其他来源的软件包被安装,可能导致冲突或不兼容性,您可以使用「pkg 查询"%n: autoinstalled=%a from repo=%R"」列出安装的软件包这些细节。

在此最后一步中,您在客户端配置了访问 CI 的包存库,可选地为安全目的启用了包签名验证,确保包只来自单个源,以避免兼容性问题,启动了包管理器pkg,并安装了 CI 所构建的所需包。

结论

在本教程中,您已经安装和配置了Poudriere,自动运行包构建,并从客户端主机配置了安全访问包库,最终安装了来自单一的中央源的最新内置包。

为了进一步增强当前的设置,您可以考虑选择后续步骤:

  • ** 只允许私人访问** : 默认情况下,Droplets在互联网上有一个公开的IP地址. 另外, Buildbot [支持认证] (http://docs.buildbot.net/latest/developer/auth.html) , 但默认是无保护的.
  • ** 关于建设问题的教训** : 请检查access-date=中的日期值 (帮助) Buildbot reports 如何设置起步.
  • ** 保持端口树的最新情况** : 在从教程中举出的例子中,使用了 [季行 (https://wiki.freebsd.org/Ports/QuarterlyBranch) 2019Q2,但您最终应该切换到更新的树上,或者使用您自己的版本控制寄存器来应用所期望的补丁.
  • ** 自有项目加建建筑物** : [FreeBSD Porter's Handbook] (https://www.freebsd.org/doc/en/books/porters-handbook/) 解释如果想要以 FreeBSD 软件包来构建和安装内部软件,如何写出构建的食谱(a_port_).
  • ** 客户端的监管器已过时包** : 您可以使用` sudo pkg 更新 -q sudo pkg 版本 - q -- not- like "=" 打印版本不完全匹配的所有软件包的输出, 比较客户端上安装的软件包和CI上最新的可用软件包。 详见pkg-version的网页.
  • ** 添加清理工作** : 久而久之,Buildbot工人监狱将充斥着旧的建筑日志文件,源出沥青球等可能腐烂的包裹. 使用命令 `doudriere {logclean, distlean, pkgclean } 来清理(见 [poudriere manpage of poudriere] (https://www.freebsd.org/cgi/man.cgi?query=poudriere&sektion=8&manpath=freebsd-release-ports ).
Published At
Categories with 技术
comments powered by Disqus