第十六章:使用ports定制软件

软件包提供了最理想程序的最常见配置。如果你正在构建一个通用的web服务器,那么nginx、lighttpd或任何你喜欢的web服务器的官方FreeBSD包都可能足够了。如果您有特殊的环境或不太常见的需求,那就是Ports Collection的用武之地。Ports Collection是一个可以轻松构建许多软件包的自定义版本的工具。它以标准的机器和人类可读格式组合了依赖性、许可、维护者和所有其他软件信息。端口允许您设置系统选项,如“禁止第三方GPL许可代码”(对嵌入式供应商有用)、“在所有内容中添加LDAP”或“禁用X11”。

从长远来看,ports最好使用 poudriere 包构建系统(package-building system)进行管理。不过,在使用 poudriere 之前,您必须了解ports是如何工作的。我鼓励您在测试系统上探索ports。不过,与其在单个服务器上部署ports,不如使用 poudriere 构建自己的包存储库。完全使用软件包管理您的服务器。切勿在包构建器之外的生产服务器上使用ports tree。

在我们深入探讨ports之前,让我们先来谈谈构建软件的一般情况。

制作软件

传统的软件构建很复杂,因为必须非常具体地处理源代码才能创建一个可用的、正在运行的程序,更不用说一个运行良好的程序了!这是一个与使用JavaScript编译器完全不同的过程。虽然程序员可以在每个程序中包含安装说明,其中充满了像 Now type ar cru.libs/lib20_zlib_plugin.a istream-zlib.o zlib-plugin.o 这样的行,但这将是彻头彻尾的虐待狂。虽然Unix管理员似乎赞成虐待狂,但他们坚决反对针对自己的残忍行为;如果某件事可以自动化,它就会自动化。

构建软件的主要工具是 make(1)。运行时,make会在当前目录中查找一个名为 Makefile 的文件,该文件充满了指令,与前一段中的可怕示例非常相似。它读取指令并执行,使安装过程自动化,无论它有多复杂。你不必真正了解 Makefile 的内部,所以我们不会剖析它。

每个 Makefile 都包含一个或多个 targets ,或要执行的指令集。例如,键入 make install 命令 make(1) 检查 Makefile 中名为 install 的目标,如果找到,则执行它。目标的名称通常与要执行的进程有关,因此您可以放心地假设 make install 安装软件。您将找到安装、配置和卸载大多数软件的目标。make(1) 处理各种各样的功能,其中一些远远超出了创建者的初衷。但这正是Unix的乐趣所在!

源代码和软件

源代码是人类可读的指令,用于构建构成可运行程序的实际机器代码。您可能已经接触过某种形式的源代码。如果您从未见过它,请查看 /usr/src 下的一些文件或https://svnweb.freebsd.org/.即使是新手系统管理员也需要在三次尝试中识别两次源代码。

一旦你有了程序的源代码,你就可以在你想运行它的系统类型上构建(或compile——编译)程序。(通过交叉编译需求为国外平台构建软件在可能的情况下会更复杂。)如果程序是为与你构建它的平台足够相似的操作系统编写的,它就可以工作。如果你的平台与原始平台差异太大,它就会失败。一旦你在系统上成功构建了软件,你就可以将生成的程序(或binary ——二进制文件)复制到其他相同的系统上,它应该会运行。

有些程序编写得足够好,可以在许多不同的平台上编译。一些程序特别包括对差异很大的平台的支持;例如,Apache web服务器可以在Windows和类Unix系统上编译。这代表了软件作者的英勇努力,即便如此,在Windows上构建之前,您必须运行一些脚本并按照指示精确配置您的环境。

一般来说,如果你能从源代码构建一个程序,它可能会运行。它可能不会正确运行,可能不会做任何您期望的事情,但它会运行。经验丰富的系统管理员可以使用源代码和错误消息来了解程序无法构建或运行的原因。在许多情况下,问题很简单,只需付出最小的努力即可解决。这就是为什么访问源代码很重要的一个原因。

在每个系统管理员都是程序员的时候,调试软件占据了管理员的大部分时间。每个类Unix系统都略有不同,因此每个系统管理员都必须了解自己的平台、软件设计的平台以及两者之间的差异,然后才能希望运行一段代码。重复工作真的很可怕。

多年来,程序员开发了autoconf等工具来帮助解决这些跨平台问题。并非每个程序都使用这些工具,当它们崩溃时,系统管理员被踢回到了起点。系统管理员必须编辑源代码和Makefiles ,才有机会让程序正常工作。workingworking well 几乎不一样,更不用说 working correctly 了。

FreeBSD Ports Collection旨在为FreeBSD用户简化这一过程。

The Ports Collection

Ports Collection,也称为 ports tree 或简称为 ports,包含一个在FreeBSD上编译软件的自动化系统。

ports系统背后的基本思想是,如果必须修改源代码才能在FreeBSD上运行,那么修改应该是自动化的。如果您需要其他软件从源代码构建此程序或运行该软件,则应记录并跟踪这些依赖关系。如果你想自动化这些更改,你最好记录程序包含的内容,这样你就可以轻松地安装和卸载它。由于你有一个每次都会产生完全相同结果的软件构建过程,并且你已经记录了该过程创建的所有内容,你可以复制二进制文件并将其安装在任何类似的系统上。

除了创建包所需的信息外,Ports Collection还包含构建软件的法律限制、安全信息、许可细节等。

ports与包互操作。Ports Collection用于创建包。您可以根据需要从ports安装一些软件,也可以从软件包安装一些软件。您需要使用与构建包时使用的Ports Collection相同的版本,无论是季度分支还是最新版本。大多数端口用户都想要最新的软件,所以我们将重点关注这一点。

Ports

port 是一组指令,说明如何对一组源代码文件应用修复程序或 patch 程序,然后构建和安装这些文件。port包含创建完成的软件所需的所有内容的完整记录。这使系统管理员无需费力安装程序,也让他们难以配置程序。

Ports Tree 安装

如果您按照第3章中的安装说明进行操作,则已将端口树安装在 /usr/ports 中。在该目录中,您应该可以找到几个文件和几十个目录。如果你在 /usr/ports 中没有任何内容,你显然无法按照说明进行操作。没关系——我也不能——但你必须安装端口树才能继续。

FreeBSD支持几种不同的方法来获取ports tree。您可以使用 svn(1) 查看它,也可以从网上下载一份副本。建议系统管理员使用 portsnap(8) 下载端口树的最新(非季度)版本。

此处portsnap 搜索portsnap文件的镜像,在portsnap服务器上加密验证这些文件的完整性,下载文件,并验证下载本身的完整性。

你现在拥有所有FreeBSD ports的最新版本。要将现有的ports tree更新到最新版本,请在此运行 portsnap auto

如果你希望通过 cron(1) 安排定期运行portsnap更新,请使用 portsnap cron update 命令而不是 ·portsnap auto` 。这个命令告诉 portsnap在命令运行后60分钟内的某个随机时间更新ports tree。这有助于在FreeBSD portsnap服务器上分配负载。在root的crontab中安排一次 portsnap运行,时间在上午5点到6点之间,输入以下内容:

这将在上午5点到6点之间的随机时间启动实际更新,这比24个portsnap用户中有1个在上午5点钟同时访问下载服务器要有效得多。

Ports Tree 内容

您在这里看到的大多数目录都是软件类别。每个类别都包含另一层目录,每个目录都是一个软件。在我写这篇文章的时候,FreeBSD有28000多个ports,因此正确使用目录树和对软件进行分类至关重要。在此类别中不属于软件类别的文件和目录中,主要文件和目录在这里进行了描述。

The Ports 索引

ports索引文件包含在特定FreeBSD版本上构建的所有端口的列表。在FreeBSD 13上,这是/usr/ports/INDEX-13。Ports Collection将索引用于多种目的,包括搜索整个ports 树。

索引文件在一行中描述了每个端口,字段由管道符号(|)分隔。虽然这对系统工具来说很方便,但它并不是特别适合人类阅读。在 /usr/ports 中运行 make print-index 以获得更长、更易于理解的索引。此索引包含以下条目:

索引以端口名称和端口目录的完整路径开头。Info 对端口进行了非常简要的描述。Maint 标题列出了端口的维护人员,即负责将此软件集成到Ports Collection中的人员或团队。Index 空间列出了可能提交此端口的每个类别。列出的第一个类别是它出现在端口集合中的目录。在这种情况下,端口将出现在archivers目录中。

然后我们有依赖关系。B-deps 列出了构建依赖关系,即构建此端口必须安装的其他软件。R-deps 列出运行时依赖关系,这是实际运行所需的软件。这是一个Perl模块,因此它需要一个Perl解释器。某些软件必须使用 E-deps 中指定的特定工具进行提取或解压缩。P-deps 字段列出了修补软件的任何依赖关系——罕见的软件必须使用某种工具进行修补。F-deps 字段类似,指定了获取依赖关系,即必须用于下载软件的任何特殊软件。

最后,WWW 空间给出了软件的主页。

搜索索引

Ports Collection包括搜索索引的工具。如果你想要一个特定的程序,你最好用 pkg search找到ports目录,甚至 locate -i 。保留搜索ports Collection来回答“哪些端口使用SNMP?”之类的问题。

如果你知道某个软件的名称,请使用 make searchINDEX 中搜索它。在这里,我查找名称中包含 net-snmp 的ports:

在撰写本文时,FreeBSD有几个名称中带有net-snmp的ports。第一个是当前标准的net-snmp软件集合➊。其他包括在网络上使用SNMP但与net-snmn套件无关的Perl库、不再支持的旧版本的net-smpm以及与net-smpn的Tcl/Tk接口。描述中的字段直接取自 INDEX 文件。

如果你不需要这么多细节,试着进行 make quicksearch ,只获取port、路径、信息,以及(如果适用)关于它不再存在的原因的注释。

关键字搜索

您还可以使用port描述中的任何字段作为关键字进行搜索。删除键名中的所有连字符。您想要所有运行时依赖Perl的端口吗?

您可以在一个查询中组合多个搜索词。假设您希望所有名称中包含Apache但运行时依赖于Python的程序。

在关键字前加一个 x,从搜索结果中排除一个单词。在这里,我们寻找所有运行时依赖Python但名称中没有Apache的东西:

然而,这些按字段搜索并不适用于所有软件。例如,如果您正在查找Midnight Commander文件管理器,则可以按名称搜索。

嗯,这没什么帮助。在所有字段中搜索与术语 key 匹配的项。

这将扫描更多字段并返回更多点击。然而,如果你在搜索一个常见单词,key 搜索可能会提供太多的信息。用 quicksearch 修剪输出。

这将返回每个port,并在其描述、名称或依赖关系中包含字符串 middle 。我们很快就会知道Midnight Commander可以在 /usr/ports/misc/mc 下找到。

浏览Ports集合的其他方法

如果您更喜欢使用web浏览器,请构建HTML索引。只需转到 /usr/ports ,以root身份键入make readmes ,即可生成一个README.html文件,其中包含您的端口树索引和每个端口中的html文件。您可以点击各种类别,甚至查看每个端口的详细描述。

如果这些选项都不起作用,请尝试FreeBSD端口树搜索http://www.freebsd.org/cgi/ports.cgi.此外,FreshPorts搜索引擎位于http://www.freshports.org/提供了一个独立但非常好的搜索功能。

在网络浏览器和搜索引擎之间,你应该能够找到一款满足你需求的软件。找到所需的端口可能是使用端口时最困难的部分。

法律限制

虽然Ports Collection中的大多数软件都是免费的,但其中一些软件的许可证限制更为严格。/usr/ports/LEGAL文件列出了对ports Collection内容的法律限制。最常见的限制是禁止再分配;FreeBSD项目在其FTP站点或CD映像上不包含此类软件,但提供了如何构建它的说明。

法律限制出现在您可能意想不到的地方。您无法下载Oracle Java的已编译即用包,FreeBSD项目也无法重新分发Java源代码。FreeBSD可以并且确实分发了如何在FreeBSD上构建Oracle Java源代码的说明,但用户必须自己去Oracle网站下载代码。幸运的是,OpenJDK已经取代了Oracle Java用于大多数软件,FreeBSD也有一个高质量的软件包。

同样,一些软件禁止商业使用或嵌入商业产品中。由于商务部限制加密技术出口的规定,一些无法从美国出口。2如果您正在构建用于再分发、出口或商业用途的FreeBSD系统,则需要检查此文件。

幸运的是,Ports Collection中的大多数软件都可以免费用于商业或非商业用途。这些受限制的包是例外,而不是常态。

Port里面有什么?

从端口安装软件比使用软件包需要更长的时间,并且端口集合需要实时互联网连接。作为交换,Ports Collection可以产生比包更优的结果。让我们来看一个端口。这是dns/bind911的内部结构,ISC BIND名称服务器的9.11版本:

Makefile包含构建端口的基本说明。如果你阅读这个文件,你很快就会发现它只有几百行长。对于如此复杂的软件来说,这并不是一个庞大的指令量,而且大多数Makefile都要短得多。该文件的大部分内容专门用于很少使用的自定义。这里几乎没有关于BIND本身的信息,也没有太多关于如何在FreeBSD上构建软件的信息。大多数FreeBSD端口系统的Makefile都在/usr/ports/Mk中。

distinfo文件包含端口下载的各种文件的校验和,以便您的系统可以确保文件传输无误,并且在您获得文件之前没有人篡改过它。

files目录包含在FreeBSD上构建此端口所需的所有附加文件和补丁。BIND 9.11需要十几个补丁。这些补丁中的大多数都不需要构建,因为ISC支持FreeBSD上的DNS服务器。它们只提供与FreeBSD软件包系统的集成。

pkg-descr文件包含对软件的详细描述。

一些ports包含一个pkg-help文件,该文件提供了有关如何使用端口的更多详细信息。

一些ports(不是这个)有一个pkg-message文件,其中包含一个用于创建软件包安装消息的模板。

最后,pkg-plist文件是所有已安装文件的列表(“packing list”)。该端口仅安装装箱单中列出的文件。一些端口(如与Python相关的端口)使用自动生成的装箱单,所以如果装箱单丢失,不要感到惊讶。

这些文件组合在一起,构成了构建软件所需的工具和指令。

安装 Port

如果你熟悉源代码,你可能已经注意到port包含的实际源代码很少。当然,有补丁可以应用于源代码和在源代码上运行的脚本,但没有软件的源代码!你可能会问,没有源代码,从源代码构建软件应该如何工作?

ports和生产 我强烈建议您使用poudriere构建自己的包存储库,并从该存储库管理服务器的端口。升级直接安装在主机上的端口既烦人又困难。像portmaster和portupgrade这样的工具现在已经过时了,虽然它们可能会被更新或重写,但poudriere是永恒的方法。你已经被警告了。探索一次性测试系统上的端口。

当你激活一个端口时,FreeBSD会自动从包含的站点列表中下载相应的源代码。然后,端口检查下载的代码是否存在完整性错误,将代码提取到临时工作目录,对其进行修补,构建它,安装所有内容,并将安装记录在包数据库中。如果端口有依赖关系,但未安装这些依赖关系,则会中断当前端口的构建,以便从源构建依赖关系。要触发所有这些,您只需进入port目录并键入:

当端口执行工作时,您会看到大量文本在终端上滚动,当它完成时,您将收到命令提示符。

然而,随着您在从源代码构建方面越来越有经验,您会发现这种一体化的方法并不适合每种情况。不用担心;Ports Collection提供了将端口构建过程完全按照您的意愿进行的能力因为 make install 实际上会运行一系列子命令。如果指定其中一个子命令,make(1) 将运行所有前面的命令以及您指定的命令。例如,make extract 运行 make configmake fetchmake checksummake dependsmake extract。这些子命令按顺序为:

make config

许多ports都有可选组件。运行 make config 可以让您选择希望在此port中支持哪些选项。您选择的选项保存在 /var/db/ports 中,以备将来构建端口。这些选项会影响端口的构建方式——例如,如果您选择构建一个支持net-snmp的程序,则表示您添加了对net-snmps的依赖。我们将在本章后面第373页的“port自定义选项”中更详细地讨论 make config

make fetch

配置port后,系统会在预配置的互联网站点列表中搜索程序源代码。port的 Makefile 可能列出该文件的权威下载站点,也可能使用Ports Collection提供的几个权威列表之一。当port找到源代码时,它会下载它。原始的下载源代码称为 distfile ,存储在 /usr/ports/distfiles 中。

如果端口需要特定程序来获取distfile,则该端口会将该程序作为 make fetch 的一部分进行安装。

make checksum

make checksum 步骤计算distfile的加密哈希,并将其与端口的 distinfo 文件中记录的哈希进行比较。文件可能以多种方式损坏:在下载过程中,下载网站上的恶意入侵者,或者纯粹的随机破坏。校验和验证可检测任何原因导致的文件损坏,如果文件损坏,则停止构建。

此步骤不会努力确定文件损坏的原因或方式。出于port的目的,无论源代码在下载过程中是否损坏,或者在下载之前是否有恶意入侵者将其后门代码放入distfile中,都无关紧要。无论哪种方式,都不要浪费时间构建它,当然也不要安装它!

射击方法#839:忽略校验和 软件作者,尤其是自由软件作者,有时会对代码进行细微更改,但不会更改软件版本或distfile的文件名。FreeBSD移植正确地注意到了这个问题,并且在这样的更改后不起作用。如果你绝对确定distfile没有被破坏或损坏,你可以通过设置 make NO CHECKSUM=yes install 来覆盖此检查。 我强烈建议在这样做之前咨询软件的原始作者,而不是端口维护者。与作者联系可以确保您没有安装受损的软件,也有助于教育软件作者版本号和发布工程的重要性。

make depends

许多软件都是建立在其他软件之上的。虽然FreeBSD包含 make(1) 和编译器,但有些软件只能用特定的编译器编译,或者需要特定版本的make。也许distfile是用一种很少使用的算法进行分布式压缩的。也许它需要一个FreeBSD没有附带的第三方库。在 make depends 阶段,端口会检查缺少的依赖项,并尝试通过构建端口来解决它们。

依赖关系可以有自己的依赖关系。make depends 递归地处理依赖关系,直到端口拥有构建、安装和运行所需的一切。

make extract

一旦FreeBSD有了端口distfiles,它必须解压缩并提取它们。大多数源代码都是用 gzip(1)bzip(1)xz(1) 等压缩的,并用 tar(1) 进行整理。此命令在端口中创建一个 work 子目录,并在那里提取tarball。如果端口需要特定的程序来提取distfile,它现在就会安装它。

make patch

此命令将端口中的任何补丁应用于工作子目录中提取的源代码。如果端口需要特殊的补丁程序而不是基本系统的 patch(1) ,则port现在安装它。

make configure

接下来,FreeBSD会检查软件是否有配置脚本。这与port执行的 make config 步骤不同。如果软件附带了自己的配置脚本,则port会运行它。在此阶段,一些ports会中断构建以提示您提供信息,但大多数ports会静默运行。

make build

此步骤编译已检查、提取、修补和配置的软件。不编译任何东西的ports在这里可能有一个空步骤。有些ports的存在只是为了方便地打包一堆其他ports。

make install

最后,make install 并告诉软件包系统记录其存在。

port 自定义选项

许多软件包都具有广泛的自定义构建功能。虽然启用这些功能对任何单个软件来说都不难,但没有通用的方法来定义它们。使用一个软件,您可能需要编辑原始软件的 Makefile;对于另一个,您可能需要为配置脚本提供标志。学习如何做出这些改变需要时间,而且可能会很烦人。FreeBSD Ports Collection提供了两种方法来在您的系统上一致地配置这些选项。

make config 支持更新、更漂亮的方法。这将打开一个对话框,与您首次安装FreeBSD时看到的对话框非常相似。例如,流行的访问控制系统sudo(http://www.sudo.ws/)包括对LDAP、审计的支持,最重要的是,当用户输入密码错误时,会侮辱他们。如果您转到 /usr/ports/security/sudo 并键入 make config ,您将看到一个与图16-1所示非常相似的菜单。

使用空格键选择您喜欢的选项,使用箭头和TAB键四处移动。在“确定”或“取消”上按ENTER键完成。端口将您所需的选项记录在 /var/db/ports/<category>_<portname>/options 中。当您必须重建或升级端口时,端口会重用这些相同的选项,除非您运行 make config 来更改它们或 make rmconfig 来清除它们。

在命令行进行自定义

有时,您不希望有一个漂亮的箭头选择菜单,而是希望在命令行上有一个适当的单词系统界面。Ports Collection允许您跳过菜单,并在 make(1) 命令中提供所有配置选项。在你这样做之前,你会想关掉漂亮的菜单。在命令行上设置环境变量 BATCH=1 以关闭菜单。在这里,我们使用默认配置构建端口,就像FreeBSD包集群一样:

现在您已经放弃了烦人的菜单,看看port支持哪些配置选项。 make pretty-print-config 命令以易于阅读的格式显示当前设置。让我们看看security/sudo

每个选项都代表一个配置选项。标有加号的选项被打开,而标有减号的选项被关闭。这些选项是什么意思?运行 make showconfig 会显示port的所有选项及其作用。

虽然sudo支持LDAP和SSD以及各种复杂的信息源,但我真正需要的是sudo在用户输入错误密码时侮辱用户。我想要 INSULTS 选项。使用命令行上的 WITH 环境变量设置该选项。选项名称区分大小写。在这里,我设置了选项并再次检查配置:

现在已设置 INSULTS 选项。

使用引号启用多个选项。

同样,使用 WITHOUT 关闭选项。

如果在构建端口时启用菜单,则会出现 make config 图形菜单,但会设置您选择的选项。记住,使用 BATCH 变量关闭菜单。

在全局范围内使用自定义

您构建端口以获得软件中的特定功能。通常,您希望所有支持该功能的port都具有该功能。请考虑一下LDAP。如果您的企业使用LDAP,您可能希望所有软件都使用它。您希望LDAP成为默认设置。

FreeBSD将每次运行make时使用的设置存储在 /etc/make.conf 中。您可以在这里启用LDAP或LibreSSL或其他应在整个系统中显示的自定义设置。将您希望全局应用的任何选项放入 make.conf 中。与命令行不同,make.conf 使用变量 OPTIONS_SETOPTIONS_USET

在这里,我希望在每个端口上启用LDAP和INSULTS选项:

make.conf 设置对不支持该选项的port没有影响。许多ports对LDAP一无所知。我不知道除sudo之外的任何ports是否包含侮辱用户的可选功能,但如果该功能可用,我就需要它。

为什么在 make.conf 中使用单独的选项而不是命令行?优先。使用 OPTIONS_SET 设置的WITH 覆盖选项应用的选项。在这个例子中,我在全球范围内启用了insults。如果出于某种深不可测的原因,我需要一个特定的port来避免冒犯用户,我可以在构建port时在命令行上使用 WITHOUT=INSULTS 来覆盖全局默认值。

/etc/make.conf 和单端口

也许你想用特定的选项构建一个特定的port,但你不想在命令行上指定它。使用/etc/make.conf中的端口类别、下划线、port名称、另一个下划线和 SET 变量。

虽然port应该缓存配置,但这将提供额外的保护,防止胖手指错误。

设置默认版本

FreeBSD支持数十种port自定义选项。不过,并非所有这些都是明智的port选择。某些选项必须在整个端口集合中使用才能有效。最常见的例子是SSL库。您可以使用基本系统SSL库构建所有port,一切都会好起来的。您可以使用外部SSL库构建所有port,软件也可以正常工作。使用基本系统SSL和第三方SSL构建一些port会导致灾难。这同样适用于PostgreSQL数据库服务器和Python解释器的不同版本。不同的SSL库与不同的数据库服务器版本相结合,造成了我非常喜欢把这种崩溃交给一个初级系统管理员,他迫切需要一堂关于共享库如何工作的难忘课。

Ports Collection使用 DEFAULT_VERSIONS 变量列出应作为默认值使用的关键软件。这将替换 DEFAULT_MYSQL_VERWITH_DB_VER 等旧变量。获取完整变量列表的唯一方法是遍历 /usr/ports/Mk/ 。文件 bsd.default-versions.mkbsd.apache.mkmk/Uses 下的文件非常有用。

在这里,我告诉Ports Collection始终使用LibreSSL而不是基本系统的OpenSSL库构建ports,并使用Python 3.7。

我在单独的行中列出了每个默认版本,并使用 += 语法告诉端口系统将其添加到列表中。

我建议在构建第一个端口之前设置默认版本。否则,您将最终重建端口,以便它们与您的首选库链接。

不要将预构建的包与使用备用 DEFAULT_VERSIONS 构建的端口混合使用。从包构建的程序将使用默认库,而您的端口将使用首选库。如果你的系统在事后正常工作,那纯粹是偶然的。

前加载递归

有时,构建端口时的交互性不是问题。递归是问题所在。

假设你正在构建一个大型端口,如LibreOffice或GNOME。这些端口有数十甚至数百个依赖项。其中许多端口需要交互式配置。也许你决定在睡前启动KDE构建,以为醒来时会看到最新的窗口管理器,或者至少是一条有趣的错误消息。相反,你会发现一个依赖项的 make config菜单,在你离开30秒后,它一直在耐心地等待你的注意。

从端口构建软件的要点是,您可以对其进行自定义。不过,对于这些大型构建,您真的希望预先进行所有自定义。这就是 make config-recursive发挥作用的地方。

make config-recursive 遍历所需端口的树,并在每个端口上运行 make config。您将花费几分钟时间在每个端口中选择选项,或者只需在不关心的端口上单击“确定”即可。不过,一旦你完成了递归配置,你就可以在你真正想要的端口上安全地运行make install,然后去做其他事情。您将返回到已安装的端口或生成失败。

更改端口的构建选项可以添加或删除依赖关系。如果你决定在LibreOffice中启用SNMP支持,4端口将需要适当的SNMP库。该库的端口需要配置。重新运行 make config-recursive ,直到您的决定都没有改变。

端口系统会缓存您的所有配置选项。要删除端口及其所有依赖项的缓存,请运行 make rmconfig-recursive

如果带宽时间是问题所在,您可以使用 make fetch-recursive 下载所有依赖项所需的所有distfile。如果你在南极洲这样的地方,这很有用,那里的构建时间和服务器冷却是无限的,但你每天只有几个小时的互联网。

打包依赖关系

有些软件有数百个依赖项,你可能不想构建所有的依赖项。虽然我可能想要一个自定义的Emacs版本,但我可能不想从源代码构建gmake和最新的GNU C编译器。make missing命令显示缺少的依赖项。您可以使用该命令来选择要构建的内容。

如果你不想从源代码构建任何依赖项,而是从包中安装它们,你可以将make missing输入到 pkg 命令中。

如果软件包可用,它将被安装。您只需要从port安装那些只能从port安装的东西。

Port 风味

一些ports具有复杂的依赖关系。虽然你可以用Python 2或Python 3构建Ansible,但与Python 2一起使用的Ansible包与Python 3的包非常不同。Flavors(风味)是一种在单一port中表达这些可能性的机制,最近被引入Ports Collection。风格尚未在整个ports系统中普及,但在我写这篇文章时,它们已经在Python、Perl、Qt和Emacs中实现。你可以期待越来越频繁地看到它们。

要查看port是否支持任何风格,请转到port目录并运行 make -V FLAVORS。在这里,我看到了流行的Python打包工具包Setuptools的哪些风格可用。

我目前的端口树支持Python 2.7、3.6、3.5和3.4。

要为特定的Python版本构建Setuptools,请在命令行上提供样式。

如果不指定风格,则port将使用当前默认的Python构建。要为您的系统设置默认Python,请在make.conf中设置 DEFAULT_VERSIONS

构建包

您可以从已安装的port创建包。然后,您可以将自定义port复制到其他计算机并安装它。 在创建包之前,请创建目录 /usr/ports/packages 。ports系统将内置包放在该目录中。如果没有packages目录,包就会出现在port目录中,而包文件会分散在文件系统中。

使用make包创建包。如果您不仅要打包当前port,还要打包其所有依赖项,请运行 make package-recursive

需要大量定制ports的人应该考虑使用poudriere建立自己的存储库(本章稍后讨论),但如果你有特殊情况或想为以后省去麻烦,一次性包构建是可以的。

卸载和重新安装 Ports

虽然您可以使用 pkg remove 卸载port,但也可以从port目录中卸载port。在port目录中运行 make deinstall 会从系统中删除程序,但会使port编译并准备重新安装。

卸载port后,编译后的程序和源文件仍位于port中的工作子目录下。运行 make restall 会重新安装编译后的软件。您可以根据需要多次卸载和重新安装。

跟踪 port构建状态

Ports Collection如何跟踪已经完成的工作?如果你可以运行 make extract 然后 make install ,FreeBSD怎么知道它已经完成了什么?Ports Collection使用隐藏文件(名称以点开头的文件)或 cookie 来跟踪已完成的步骤。通过列出port工作目录中的所有文件来查看这些文件:

文件 .configure_done.sudo_usr_local 表示 make configure 步骤已完成。

不止一次,在多个 make install/deinstall 周期后,我有一个port拒绝重新安装。这通常是由指示安装已完成的隐藏文件引起的。删除该文件,然后可以继续重新安装。

清理 Ports

ports可能会占用大量磁盘空间。具有许多依赖项的程序,如GNOME、KDE和LibreOffice,可能需要数十GB!其中大部分位于ports 的 工作 目录中,port将源代码文件和完成的二进制文件的所有中间部分放在那里。不过,一旦安装了port,您就不再需要这些文件。

使用 make clean 删除port的工作文件。这将擦除当前port的工作目录和所有依赖项,因此在执行此操作之前,请确保您对新程序感到满意。您还可以在安装后立即通过运行 make install clean 来清理port。

您可能还想删除存储在 /usr/ports/distfiles 中的原始distfiles。make distclean 命令删除当前port的distfile和所有依赖项。

要清理整个port树,请直接在 /usr/ports 下运行 make clean -DNOCLEANDEPENDS-DNOCLEANDEPENDS 是可选的,但它阻止了默认的递归清理。没有它,你会清理一些流行的ports几十次或几百次。虽然有更快的方法可以删除ports tree中的每个工作目录,但FreeBSD项目直接支持这种方法。

只读 Ports Tree

许多人不喜欢在 /usr/ports 中有临时文件甚至包。您可以将各种工作目录移动到文件系统的其他部分,以保持 /usr/ports 只读,更新除外。

使用 make.conf 中的 WRKDIRPREFIX 选项在单独的目录中构建port。许多人会将其设置为 /usr/obj 这样的位置。

PACKAGES 选项设置了一个新的包目录,而不是 /usr/ports/packages

最后,DISTDIR 设置一个位置来存储除 /usr/ports/distfiles 之外的distfiles。

另外,如果设置了这些目录的权限,以便构建器可以写入这些目录,则可以在不成为root的情况下构建port和包。但是,只有root可以安装软件。

更改安装路径

许多环境都有关于如何安装附加软件的标准。我曾在一些组织中,/usr/local 被保留用于特定于该机器的文件,并且禁止在该目录中安装软件。相反,软件安装必须进入 /opt 或其他强制位置。

使用 LOCALBASEPREFIX 变量设置备用安装位置。您可以在命令行上执行此操作,但如果您符合组织标准,请使用 make.conf 。无论你使用哪种方法,都要从构建 pkg(8) 本身开始。

port在此目录下安装其所有文件。例如,通常进入 /usr/local/bin 的程序最终会进入 /opt/bin

并非每个port都能处理从 /usr/local 更改 LOCALBASEPREFIX 。一些软件对 /usr/local 进行了硬编码依赖,而另一些软件则存在未发现的错误。如果更改安装路径时port阻塞,请提交PR(见第24章)。考虑看看port,找出它堵塞的原因。提交这样的修复程序是参与FreeBSD的最简单方法之一。

私有包存储库

软件包很棒,直到你需要定制版本;那么你需要port。同样,在你有几十台都需要定制port的机器之前,port是很好的。在一台主机上易于构建的东西很难在多台主机上维护,也不可能在大型服务器场中维护。当你的port数量超过时,你需要包。即,定制套餐。

FreeBSD项目使用poudriere(发音为poo-DRE-er)来构建包。为什么是poudrier?这是法语中火药桶(powderkeg)的意思。作为“tinderbox(火药盒)”工具的继任者, poudriere是一组利用现有FreeBSD基础设施的shell脚本,如jails和tmpfs以及Ports collection。

构建跨多个系统工作的包与构建在本地主机上工作的软件不同。任何由人类管理的东西都会积垢(accumulates cruft)。一旦我的桌面使用了几个月多,我非常有信心,我所做的一些细微更改会使它与任何新安装的系统略有不同。也许我在升级后保存了一个共享库。也许我手动安装了一些东西,却忘了。我不知道小精灵可能篡改了链接器。重要的是,我的主机与运行本应相同操作系统的其他主机并不完全相同。在此主机上构建和打包的port可能包括依赖关系、库,或者谁知道会阻止它在其他主机上工作。

poudriere通过在自己管理的jail中建造所有东西来逃避这个问题。一个poudrier可以为比它运行的主机更早的任何受支持的FreeBSD版本构建包。例如,你不能在12.4-release主机上为13.0-release构建包,因为内核缺乏必要的接口。

使用poudriere,您可以在一台主机上构建包,并将其分发到所有服务器上。虽然poudrier包含许多高级功能,但运行一个基本的存储库并不难。

Poudriere 资源

包构建需要系统资源。您可以限制在构建过程中使用多少处理器,这有助于减少其内存使用。然而,虽然poudriere本身只有几兆字节,但jail和构建环境可能会占用大量磁盘空间。官方的poudrier文档建议为每个jail分配至少4GB的磁盘,为ports tree分配3GB的磁盘空间。我通常使用ZFS为每个人使用大约1GB,但我鼓励你在遵循建议方面犯错。

Poudriere利用ZFS克隆和快照构建jail,大大减少了所需的磁盘空间,并不断提高了性能。你可以在UFS上运行poudriere,但它会占用更多空间,运行速度也会更慢。

更令人担忧的是建造ports所需的空间。我的网络服务器只运行几十个软件,其中许多都很小。Poudriere只需要几GB的磁盘来构建它们。如果你要构建数百或数千个包,你需要一大堆磁盘。多少?那么,你是在构建GnuPG还是在构建LibreOffice?要获得估计值,请使用port构建但不要清理所有包,然后看看 /usr/ports 有多大。

每个主机应只使用一个包存储库。是的,从技术上讲,可以构建本地软件包,并将其与官方FreeBSD存储库中的软件包一起安装。问题是包是相互依存的。你可以让你的主机先检查你的存储库,然后再回到官方存储库。然而,官方存储库每隔几天就会更新一次。更新之间的时间因构建集群中可用的硬件而异,但几天是一个很好的猜测。您的包的更新是否与官方存储库略微不规则的更新完全同步?您的ports tree是否与port集群上使用的ports tree完全相同?包旨在作为一个集成的集合工作,而不是来自两个不同集合的一堆东西。向任何Linux管理员询问他们关于从多个存储库安装的软件包的恐怖故事,然后承诺构建所有自己的软件包。相应地规划您的磁盘使用情况。

最后,从在与您打算安装它们的架构相同的主机上构建包开始。如果您正在为arm64系统构建包,请使用arm64主机作为poudrier。你可以在amd64上构建i386软件包,但amd64硬件实际上是为运行i386代码而设计的。一旦你熟悉了poudriere,你就可以使用qemu用户静态包为慢速平台交叉构建包。

您可以将poudrier添加到现有的生产主机中吗?也许 吧。在测试系统上运行几次poudires可以深入了解您的环境所需的资源。

安装和配置 Poudriere

Poudriere没有构建选项,因此请从软件包中安装。

/usr/local/etc 中配置poudriere。您将找到一个用于配置特定包构建的目录 poudriere.d ,但我们将从通用配置文件 poudrier.conf 开始。在这里,您将告诉poudriere如何操作。虽然您可以自定义目录和路径,但我们将坚持使用默认值。

您必须通过设置 FreeBSD_HOST 变量来告诉poudriere从哪里下载FreeBSD安装文件。如果您没有本地安装镜像,请使用默认的 download.freebsd.org

Poudriere包括ZFS感知功能。当然,对于poudrier来说,ZFS不是必需的,但如果它在ZFS上运行,它将根据需要创建、克隆和销毁数据集。在UFS上运行不会妨碍poudriere,但复制文件比克隆慢。如果您使用的是UFS,请取消注释 NO_ZFS=yes 配置选项。就是这样。

ZFS用户需要指定将使用的ZFS池poudriere 。我的主要操作安装可能在 zroot 池上,但该池在一对闪存SATADOM上,我不想滥用它。我有一个专门用于处理数据的 scratch 池。在 poudriere.conf 中设置 ZPOOL

在第一次运行poudriere之前,创建一个 /usr/local/poudrire 数据集。你会更快乐。

poudriere的所有工作文件都放在 /usr/local/poudrire 下。如果您使用的是单独的ZFS池,则该池上数据集的装载点将设置为 /usr/local/poudriere 下的不同位置。在UFS上,它和其他目录一样。

我的示例在ZFS上运行,因为我可以。Poudriere的输出在UFS系统上可能看起来略有不同,但无论底层文件系统如何,您运行的命令都是相同的。

稍后我们将介绍一些poudriere 定制,但这将帮助您开始。现在为您的包创建jails。

Poudriere Jail 创建

Poudriere可以从各种不同的来源创建jails。您可以从几个不同的源下载,从源代码树构建等等。阅读 poudriere(8) 了解完整列表。在这里,我将使用我最喜欢的三种方法安装三个不同的jail:从互联网、安装映像和我定制的 /usr/src/usr/obj 。所有安装命令都使用相同的通用语法。一些安装方法会添加一个新选项,但一切都是从这些开始的。

jail 子命令告诉poudriere 在jail中工作。-c 标志表示创建,-j 允许您为jail命名。jail可以有任何不包括period的名字。我以版本类型和版本号来命名我的jails,用破折号代替任何点。这给了我amd64-12-0amd64-11-4 等jails。-v 标志接受一个参数,即 uname -r中的FreeBSD版本,但没有任何补丁级别的信息。如果您的主机当前运行的是12.3-RELEASE-p20,请使用12.3-RELEASE。补丁级别将在后续的poudrier运行中发生变化——是的,poudriere将安全补丁应用于jails。

从网络安装Jail

默认的jail安装从 poudriere.conf 中指定的下载站点获取FreeBSD软件。FreeBSD的主下载站点在地理上是负载平衡的,因此除非你有自己的镜像,否则不需要使用任何其他站点。在这里,我创建了一个名为 amd64-11-1 的jail,用于构建11.1包:

Poudriere访问网站并开始下载分发文件。一旦它在本地拥有所有文件,它就会将 /etc/resolv.conf 复制到jail中,并运行 freebsd-update 以获取所有最新的安全补丁。poudriere结束于:

你现在可以配置这个jail了。

从介质安装jail

从互联网下载是可以的,但如果你在本地有安装介质呢?为什么要重新下载ISO或记忆棒映像上已有的内容?将这些分发文件解压缩到本地硬盘上,您可以根据需要将它们用于任意数量的jail。对于ISO,使用 tar(1)

记忆棒映像(.img)稍微复杂一些;遗憾的是,libarchive还不能打开磁盘映像。您必须将映像附加到内存设备并装载它。

如果你尝试挂载 /dev/md0 ,你会得到一个错误。它不是一个文件系统;它是一个分区磁盘映像。识别磁盘上的分区。

分区3是一个UFS文件系统。这看起来很有希望,挂载它:

分发文件现在可以在 /mnt/usr/fibesd-dist 中找到。我可以将它们复制出来,也可以从当前位置安装。

在这里,我为构建FreeBSD 11.0包创建了一个jail。它将被命名为 amd64-11-0 ,并使用安装的记忆棒中的文件。使用 -m 标志指定poudriere应从何处获取文件。

请注意,-m 的参数是一个URL。我可以在这里指定一个网站,但 file:// 是一种完全有效的URL类型。在Unix主机上,file:// URL有第三个斜线表示文件系统根。

从本地版本安装Jail

我运行最新版本(-current),并定期从源代码构建。我想为我的自定义构建构建构建包,所以jail需要一个与我的主机匹配的FreeBSD版本。最简单的方法是从构建主机的 /usr/src 安装。(您也可以使用Subversion下载用于构建此系统的源代码的新副本,但这需要理解Subversion。)使用 -m 将位置指定给源目录。

Poudriere在 /usr/obj 中的预构建世界上运行 make installworld 来创建你的监狱。它不会运行 freebsd-update ,因为-current不支持它。

在未来的所有示例中,我们将使用 amd64-current jail。

查看 Jails

要查看poudrier设置的所有jail,请运行 poudriere jail -l。输出范围很广,所以我无法在本书中重现,但你会看到监狱的名称、FreeBSD的安装版本、硬件架构、安装方法、安装时间戳和监狱路径。

安装 Poudriere ports tree

Poudriere可以为不同的构建使用不同的ports tree。您可能会为一台主机使用季度ports分支,为另一台使用当前ports tree,为第三台使用去年的ports tree。(你需要使用Subversion从FreeBSD镜像中提取特定的ports tree,所以我们不会介绍它们。)支持多个ports tree的可能性意味着你必须为你安装的每个ports tree分配一个名称。多个jails可以共享一个ports tree。默认值是当前ports tree。

使用 poudriere ports 子命令执行所有与端口相关的操作。-c 标志告诉poudriere创建一个ports tree,-p 标志让您指定名称。

Poudriere利用了 portsnap(8),我们在本章前面讨论过。

如果安装了多个端口树,请使用 poudriere ports -l 查看它们。

配置 Poudriere Ports

构建port的全部意义在于对其进行自定义。不过,您不需要将整个ports tree构建为包——除非您正在运行FreeBSD包构建集群或类似的东西!你必须告诉poudriere要建造哪些ports。一旦你有了这个列表,你可能需要某些ports的特定选项,但你也可能需要全局选项。您通常会使用 /etc/make.conf 来设置这些选项,但您不希望poudriere使用系统的设置。Poudriere需要一个独立的 make.conf 。同样,您可能会使用 make config 来设置port,但如何在Poudriere中做到这一点呢?

包清单

首先定义您希望poudriere构建的包列表。此列表通常位于 /usr/local/etc/poudriere.d/pkglist 文件中,但您也可以将其放在任何位置。按类别和目录指定每个port。要构建poudires本身,请使用以下条目:

这里的难点是建立一个基本包集。您必须构建主机所需的所有包。一个主机可能需要几十个或几百个包。你真的需要所有这些包裹吗?所有这些包是怎么进入这个系统的?

请记住,您可能没有选择安装所有这些软件包。你安装了一个像Emacs、Apache或LibreOffice这样的应用程序,该应用程序拖入了所有这些依赖项。你只关心这些依赖关系,因为它们会影响你想要的软件。如果LibreOffice失去了依赖性,你就不希望poudriere再建立这种依赖性了。Poudriere会自动构建和包依赖关系。您只需指定所需的应用程序,其余的工作由poudriere完成。

使用 pkg-query(8) 获取生产系统上所有非自动安装软件的列表。

将此作为包列表的基础。检查一下不需要的东西。从其他生产主机获取类似的列表。使用它们来组装存储库的包列表。

Poudriere make.conf

Poudriere从 /usr/local/etc/Poudriere.d/ 中的文件为每个jail组装一个唯一的 make.conf 。文件 /usr/local/etc/poudriere.d/make.conf 包含您希望为所有监狱设置的全局 make.conf 选项。其他 make.conf 文件可以覆盖这些设置,如 poudriere(8) 中所述,但我们将重点介绍每个jail的 make.conf 文件。

假设我希望LDAP在整个企业中无处不在。Poudriere的 /usr/local/etc/Poudriere.d/make.conf 将包含:

不过,运行我的自定义FreeBSD构建的主机都使用LibreSSL。我会为那个jail创建一个单独的 make.conf ,名为 amd64-current-make.conf 。它将包含LibreSSL配置。

更具体的文件会覆盖常规文件。每个监狱文件中的设置会覆盖poudriere的全局 make.conf 。即使启用LibreSSL,我也可以关闭这个jail上的LDAP。

运行make配置

使用 poudriere optins 为您的jail运行 make config 。jail和ports树的每种组合都可以有自己独特的port选项,因此您需要在命令行上指定它们。您必须用 -j 指定jail,用 -p 指定ports树的名称,用 -f 指定包文件。

Poudriere找出实际建造的port及其所有依赖关系。它会让你逐一完成它们的 make config

记下你选择的选项;其中一些应该进入全球或每个jail的 make.conf 吗?将它们设置为默认值可以为您在未来的poudriere中省去麻烦。

现在,您可以构建包存储库。

运行 Poudriere

poudrier bulk 子命令批量构建包。使用 -j 指定jail,-p 指定ports树名称,-f 指定包列表文件。(是的,这些标志与配置端口的标志相同;就像储物箱设计师希望保持一致或其他什么。)

Poudriere启动jail,挂载所有ports,将各种配置文件复制到jail中,决定以何种顺序构建东西,然后开始构建。在开始构建时,您将看到每个port的名称。

其中一些ports构建可能会运行一段时间。点击 CTRL-T 以获取当前状态,或查看日志以查看当前状态。

在构建结束时,您将看到已构建的所有ports的列表和未能构建的ports的列表。以下是一个小小的pkglist的结果:

pkgpkgconflibressl ports构建良好。它们可能不会运行,但ports collection可以构建和打包它们。但是,obhttpd 包没有构建。如果这个包很关键,我想在让我的客户使用这个存储库之前解决这个问题。

让我们先看看问题,然后检查存储库。

问题 Ports

在生成ports列表后,您将看到一条消息,指出在哪里可以找到日志。

日志位于一个以jail和ports tree命名的目录中,其中有一个子目录按日期排列。如果你不想输入日期,有一个方便的 latest (最新)日期,可以直接带你到最新的日志目录。

你在这里不会只找到日志,还会找到一个网站。如果您将web服务器配置为提供 /usr/local/poudriere/data ,则可以使用web浏览器检查poudriere构建(以及向客户端提供存储库)。这里的 logs 子目录包含poudriere的每个port的构建日志。如果您不想对这些日志进行排序,logs/errors 子目录只包含失败构建的日志。

现在你需要做一些非常激进的事情:阅读错误日志。也许poudriere无法获取distfile。可能主机磁盘空间不足。也许真的发生了一些奇怪的事情。或者,也许,port实际上已经被您选择的构建选项破坏了。并非所有ports都是始终使用所有选项构建的;port维护人员很容易忽略一个很少使用的功能被破坏。不过,请记住,poudriere是FreeBSD的官方port构建机制。如果一个端口在poudriere下无法构建,那么它就被破坏了,你应该考虑提交一个bug(见第24章)。

Package 存储库

/usr/local/pourrier/data/packages 下查找已完成的软件包。jail和ports树的每个组合都有自己的子目录。我使用ports树头在jail amd64-current上构建了这组包,因此我的新存储库位于 /usr/local/pourdre/data/packages/amd64-current-head 中。您会发现目录是各种 .txz 文件,最新软件包的 Latest 子目录是最新的。

祝贺 你。您有一个私有包存储库。现在让你的客户使用它。

使用私有存储库

使用私有存储库的最简单方法是在poudriere主机本身上。pkg(8) 的本地存储库配置位于 /usr/local/etc/pkg/repos 中。默认情况下,该目录不存在,因此请创建它。

在其中创建一个 FreeBSD.conf 文件。本地存储库配置增强或覆盖系统默认值——这是UCL内置的。我们需要在 /etc/pkg/FreeBSD.conf 中的默认存储库配置中添加一个设置。

这使得 /etc/pkg/FreeBSD.conf 文件保持不变,但将名为 FreeBSD 的存储库设置为 no 。默认存储库已不复存在。

现在为我们的自定义存储库创建一个单独的配置文件。我将这个仓库命名为 amd64-current ,以jail命名。

您的主机现在已准备好使用这些包。您需要强制重新安装所有当前的软件包,以停止使用FreeBSD存储库的版本并使用您的本地版本。

pkg(8) 程序将下载存储库目录,但下载看起来与平时略有不同。

与官方存储库目录相比,这个目录非常小。它在一秒钟内提取目录和元数据。最后一行显示此存储库只有62个包。您正在使用新的存储库。安装您的自定义软件包!

远程自定义存储库

包存储库的全部意义在于,您只需构建一次包,即可将其部署到任何地方。您可以使用只读NFS导出向本地计算机提供包,但互联网喜欢滥用可公开访问的NFS服务器。pkg.conf 文件使用URL定义了存储库位置。虽然我使用了一个文件作为URL,但这个存储库没有理由不能使用网站。在包构建器上安装一个web服务器,并让它向其他服务器提供 /usr/local/pourrier/data/packages 的内容。然后为应该使用该仓库的其他主机提供自己的存储库配置。

我们所有的机器现在都有一组相同的定制ports。这一变化让我的胖伯特不再在十几台机器上建造ports,而是开始抛光我的汽车。

所有 Poudrieres, 大的和小的

Poudriere默认情况下表现良好,但有几个选项可以帮助小型和大型系统。

小型系统

如果你有一个资源有限的主机,你不想让poudriere失控。这里有几个 poudriere.conf 选项来限制它。

一般来说,如果你能在主机上构建一个port,poudrier也可以构建该port。你不希望多个poudriere同时运行而淹没主机。Poudriere通常会同时运行与主机中处理器数量相同的进程。使用 PARALLE_JOBS 选项限制并行构建的数量。

其他限制,比如减少poudrier构建可以使用的内存量,并没有你想象的那么有用。一个软件需要尽可能多的内存来构建。用1GB的RAM构建LibreOffice不会有好结果。

请记住,您还可以使用 nice(1) 在全局范围内降低poudrier的优先级,如第21章所述。

大型系统

Poudriere可以利用强大的系统来加速构建。您无法加速磁盘,但可以利用内存将 tmpfs(5) 用于构建的关键部分。设置 USE_TMPFS 选项以使用工作目录的内存。

您可以将 tmpfs(5) 用于工作目录之外的构建部分,但我们中很少有人有那么多内存。有关详细信息,请阅读 poudriere.conf.sample

如果您构建了许多包存储库,请调查poudriere的缓存(https://ccache.samba.org/)支持。每个jail将使用大约5GB的磁盘空间,但可以节省大量重建包的时间。

升级 Poudriere

不断添加新ports,并提供新选项。其他软件项目不断发布新版本,FreeBSD port也相应更新。你会希望你的服务器上有这些新版本。如果你用poudriere构建你的port,更新非常简单。你需要更新你的jail和ports tree。不过,在更新之前,请确保 poudriere.conf 已设置为处理更新。

/USR/PORTS/更新 在更新端口之前,请查看 /usr/ports/updating ,了解可能影响您环境的任何特殊说明。Python或Perl默认版本的意外更改可能会毁掉你的一整天。

Poudriere有两种处理依赖关系更改的选项。您需要同时启用这两个功能。CHECK_CHANGED_DEPS 告诉poudriere不要信任早期的依赖性计算,并再次执行这些检查。这捕获了底层Perl、Python等的变化。类似地,CHECK_CHANGED_OPTIONS 命令poudriere验证每个端口的选项。将其设置为 verbose 会告诉poudriere向您显示任何更改。

现在,您可以更新jail和ports tree。使用 -u 标志更新监狱。用 -j 说出jail的名字。在这里,我更新了波德莱尔的amd-11-1监狱。

对于从官方媒体安装的jails,poudriere会运行 freebsd-update(8) 并应用任何缺失的安全补丁。如果是从源代码处安装的,poudrier会重复安装过程。

同样,用 -u 更新端口树。用 -p 指定ports tree的名称。

您将看到poudriere使用 portsnap(8) 获取最新更新。现在,您可以构建包存储库的新版本,就像第一次一样。

Poudriere确定哪些需要更新,哪些必须重建,并相应地进行。构建完成后,您的客户端可以从存储库升级其软件包。

更多 Poudriere

Poudriere的功能比我在这里介绍的要多得多。您可以使用 PKG_REPO_SIGNING_KEY 变量对包进行加密签名。包集允许您为不同的存储库定义不同的构建选项。你想构建一个使用最新Python运行的实验包吗?看看包装套装。您可以将端口列入黑名单,这样它们就永远不会被构建,即使被称为依赖项。有关各种漂亮的东西,请参阅poudriere(8)

在端口和浇注器之间,您现在可以根据需要自定义软件。如果你真的想了解Ports Collection的细节,请查看FreeBSD Porter手册https://www.freebsd.org/.我们其他人将继续介绍FreeBSD的一些高级软件功能。