作者选择开放互联网 / 自由言论基金接受捐赠作为写作捐赠计划的一部分。

引言

Buildbot 是一种用于连续集成(CI)的作业调度系统。 Ci 是一种软件开发实践,通常包括定期自动构建和测试您的软件,并对每一个变更进行测试。 尽管 Buildbot 通常用作 CI 平台,但它也可以用于任何在计算机上运行的自动化任务。 的任务执行配置包括四个组件:

  • 更改源代码: 这些代码检测更改——比如 Git 存储库中的更改——并通知调度程序
  • 调度器: 调度器根据输入的更改触发生成器
  • 生成器: 这些包含实际的生成步骤,例如编译软件项目
  • 记者: 记者使用构建结果发送失败的电子邮件或其他通知

构建机器人通过至少一个 Buildbot 主机运行和检查所有构建配置和其他设置,并将实际的构建分发给它的工作人员。 此外,主控提供了一个基于浏览器的用户界面子组件,如果启用该子组件,则用于触发或查看生成,并检查状态报告和其他设置。 还有一个或多个 Buildbot 工作人员连接到主服务器并接收命令,即运行构建。

在本指南中,您将使用 FreeBSD 监狱在一个单独的、独立的环境中安装和运行每个 Buildbot 组件。 然后,您将使用 Nginx web 服务器为 Buildbot 提供服务,并使用本地机器上的 web 浏览器访问它的 web 界面。 在完成本指南之后,您将有一个工作设置,其中包含一个示例项目构建,可以为您自己的 CI 或其他用例进行扩展。

先决条件

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

  • 一个运行 FreeBSD 11.2的服务器,尽管支持较新和较旧版本的 FreeBSD 也应该可以工作。 如果你是使用 FreeBSD 的新手,你可能会发现按照我们的指导如何使用 FreeBSD 来定制这个服务器是很有帮助的。
  • 安装在你的服务器上。 请阅读如何在 FreeBSD 11.2上安装 Nginx。

如果你想使用安全的 HTTPS 托管 Buildbot web 界面,你还需要以下几点:

  • 您拥有并控制的注册域名。 如果你还没有注册过域名,你可以向其他域名注册机构注册一个域名(例如 Namecheap、 GoDaddy 等)。
  • Dns 指向服务器公共 IP 地址的记录。 这是必需的,因为 Let’s Encrypt 验证了您拥有为其颁发证书的域。 例如,如果您希望获得一个证书,例如.com,那么域必须解析到您的服务器,验证过程才能正常工作。 您可以按照这个 DNS 快速启动指南详细了解如何添加这个。 在本教程中,我们将使用 example. com 作为域名的例子。
  • 域的 ssl / tls 证书。 按照如何在 FreeBSD 上使用 Let’s Encrypt 来保护 Nginx 来设置这个。

第一步——为建造机器人的主人和工人设立监狱

因为 Buildbot 允许外部贡献者在你的系统上运行代码,所以建议你隔离它的各种组件,以防止任意或恶意代码占用你的服务器资源。 在本教程中,您将使用 FreeBSD 监狱来完成此操作。

类似于 LXC、 Docker 和其他容器机制,FreeBSD 监狱提供了与主机系统的轻量级隔离。 在监狱中运行的进程只能访问监狱已经被授权访问的资源; 否则,它们的行为就像任何其他 FreeBSD 环境一样。 监狱共享同一个内核,但通常运行在一个文件系统上,该文件系统有一个 FreeBSD 基本系统的副本,可以是任何版本的 FreeBSD,并与主机内核兼容。 对于大多数工作负载,在主机上运行任务与在监狱中运行任务之间的性能差异并不明显。

有几个外部软件包可以帮助创建和管理 FreeBSD 监狱。 由于它们都不是行业标准,我们将使用操作系统内置的监狱配置机制。

首先,我们想为系统的监狱创建一个单独的网络接口。 在监狱中,内核重写分配给监狱的第一个 ipv4 / ipv6地址的网络连接。 例如,如果第一个分配的 IP 地址是公共的,监狱中的一个服务侦听127.0.0.1:1234,端口1234将是公共可访问的。 推荐的做法是为监狱设置一个单独的网络接口。 我们将按照这个建议将主回送接口(lo0)克隆到一个单独的接口(lo1)中。 我们将使用10.0.0.0 / 24网络,但是其他任何不重叠的网络也可以工作。

首先配置要在启动时创建的克隆接口。 这个 sysrc 命令将一个规则写入 / etc / rc。 文件,但不创建接口本身:

  • sudo sysrc cloned_interfaces+=lo1

接下来,使用以下命令创建网络接口:

  • sudo service netif cloneup

你可以通过以下方式检查接口状态和 IP:

  • ifconfig lo1
Output
lo1: flags=8008<LOOPBACK,MULTICAST> metric 0 mtu 16384 options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6> nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL> groups: lo

输出显示该接口存在,但尚未列出并附加任何 IP 地址。 其标志 LOOPBACK 意味着该接口仅在本地可用,并不代表实际的硬件设备。

接下来,使用首选的编辑器为主监狱打开一个新的配置文件。 这里,我们将使用 ee:

  • sudo ee /etc/jail.buildbot-master.conf

然后在文件中添加以下内容,它将配置一个名为 buildbot-master 的主监狱:

/etc/jail.buildbot-master.conf
buildbot-master {
    host.hostname = buildbot-master.localdomain;
    ip4.addr = "lo1|10.0.0.2/24";
    path = "/usr/jails/buildbot-master";
    exec.start = "/bin/sh /etc/rc";
    exec.stop = "/bin/sh /etc/rc.shutdown";
    mount.devfs; # need /dev/*random for Python
    persist;
}

该代码在 jail 网络接口(10.0.0.2)上分配一个固定的主机名和 IP 地址,并指定根文件系统 / usr / jails / buildbot-master。 这里使用的 exec.start 和 exec.stop 值声明监狱的启动和停止服务的行为类似于启动过程,并使用 / etc / 目录中的启动和关闭脚本。 Persist 选项允许 jail 继续运行,即使它的所有进程都已完成。

要了解更多关于主监狱的可能设置,请查看监狱手册。

添加此内容后,保存并退出编辑器。 如果您正在使用 ee,可以通过按 ctrl + c、键入 exit 并按 ENTER 来完成。

主监狱的配置文件独立于全局监狱配置文件 / etc / jail。 自信。 因此,你需要在已知的监狱名单中加上主监狱的名字:

  • sudo sysrc "jail_list+=buildbot-master"

然后启动监狱列表中列出的所有监狱,让它们自动启动:

  • sudo sysrc jail_enable=YES

如果你的系统中已经有了使用 / etc / jail 配置的监狱。 Conf 全局文件,但是您以前没有使用过监狱列表,启用这个设置意味着只有监狱列表中的监狱会自动启动,您可能希望将现有的监狱添加到列表中。

注意: 如果您使用 ZFS 文件系统,建议您为监狱文件创建一个单独的数据集,以便以后轻松备份、克隆或销毁它。 下面的命令假定您的 zpool 具有标准名称 zroot。 如果不确定 zpool 的名称,可以使用以下命令找到它: zpool list 首先,为所有监狱创建父数据集: sudo zfs create zroot / usr / jails 接下来,创建 master jail 的数据集: sudo zfs create zroot / usr / jails / buildbot-master

接下来,我们将创建主监狱的根目录并提取 FreeBSD 系统。

确保监狱的根文件系统目录存在。 如果你在前面的笔记中运行了 ZFS 命令,那么这个命令已经完成了,你可以跳过这个命令:

  • sudo mkdir -p /usr/jails/buildbot-master

然后下载一个 FreeBSD 11.2基本系统归档文件,我们首先安装 root 证书来信任下载服务器:

  • sudo pkg install ca_root_nss

这个命令将提示您批准安装 ca 根 nss 包。 按 y 键,然后输入。

下一步,下载档案:

  • fetch -o /tmp/base.txz "https://download.freebsd.org/ftp/releases/amd64/11.2-RELEASE/base.txz"

提取这个文件的内容作为监狱的根文件系统:

  • sudo tar -x -f /tmp/base.txz -C /usr/jails/buildbot-master

本指南描述了正好安装一个工人(也包含在一个监狱中)的过程,您将以与主机相同的方式配置它,重用刚刚下载的基础系统。 使用 ee 命令为工人监狱打开另一个新的配置文件:

  • sudo ee /etc/jail.buildbot-worker0.conf

在这个文件中添加以下内容:

/etc/jail.buildbot-worker0.conf
buildbot-worker0 {
    host.hostname = buildbot-worker0.localdomain;
    ip4.addr = "lo1|10.0.0.3/24";
    path = "/usr/jails/buildbot-worker0";
    exec.start = "/bin/sh /etc/rc";
    exec.stop = "/bin/sh /etc/rc.shutdown";
    mount.devfs; # need /dev/*random for Python
    persist;
}

查看这些代码行,注意 worker jail 与 master 有不同的主机名、 IP 和根文件系统目录。 保存并关闭此文件。

同样,因为我们使用的是单独的 jail 配置文件,而不是 global / etc / jail。 把这个名字添加到已知监狱的列表中:

  • sudo sysrc "jail_list+=buildbot-worker0"
注意: 与主监狱一样,如果您使用 ZFS 文件系统,建议您为工作监狱的文件创建一个单独的数据集。 同样,下面的命令创建工人监狱的数据集,并假定您的 zpool 具有标准名称 zroot: sudo zfs create zroot / usr / jails / buildbot-worker 0

提取已经下载的 FreeBSD 11.2基本系统,就像您对主系统所做的那样:

  • sudo mkdir /usr/jails/buildbot-worker0
  • sudo tar -x -f /tmp/base.txz -C /usr/jails/buildbot-worker0

此时,两个监狱都已经配置好了,并且包含了一个 FreeBSD 基本系统,没有安装任何额外的包。 让我们开始监狱:

  • sudo service jail start

使用以下命令列出系统中所有正在运行的监狱,检查启动是否成功:

  • jls

这将返回一个类似于下面的输出,显示当前在你的服务器上运行的监狱:

Output
JID IP Address Hostname Path 1 10.0.0.2 buildbot-master.localdomain /usr/jails/buildbot-master 2 10.0.0.3 buildbot-worker0.localdomain /usr/jails/buildbot-worker0

这证实了监狱的运行正如预期的那样。 然而,在这一点上,他们不能访问互联网,这意味着你不能在他们内部安装 Buildbot 软件包。 继续阅读来解决这个问题。

第二步: 建立监狱的网络连接

虽然主人监狱和工人监狱都在运行,但它们都与互联网隔绝。 开放他们到互联网是必要的,因为他们必须能够安装软件包以及相互通信。

为了解决这个问题,将主机的 DNS 解析器配置复制到两个监狱:

  • sudo cp /etc/resolv.conf /usr/jails/buildbot-master/etc/resolv.conf
  • sudo cp /etc/resolv.conf /usr/jails/buildbot-worker0/etc/resolv.conf

接下来,从监狱发送出去的互联网流量。 要做到这一点,使用 IPFW-FreeBSD 的内置防火墙-来设置 NAT (网络地址转换)网络规则。 当您完成这个步骤时,出监狱网络的流量将转换为您主机的公共 IP 地址。

如果您根据先决条件遵循了 Let’s Encrypt 教程,那么您已经将防火墙配置为允许访问您的 web 服务器。 在这种情况下,下面的一些步骤是多余的,但是重复一遍也没什么坏处。

警告: 对防火墙配置执行错误的更改可能导致远程主机通过 SSH 无法访问,因此确保有可用于登录到计算机的替代方法非常重要。 例如,如果您正在使用从 DigitalOcean 获得的服务器,您可以通过“控制台访问”功能访问它。 要通过此特性启用访问,请使用以下命令设置 root 密码: sudo passwd 或者,您可以通过输入: passwd 为当前用户设置密码

使用以下命令在 rc.conf 文件中包含预定义的工作站防火墙规则。 工作站规则保护服务器,但仍然允许基本服务通过,比如 ping 主机或 DHCP:

  • sudo sysrc firewall_type="workstation"

接下来,允许从外部访问 web 服务器端口。 下面的命令允许通过端口22进行通信,对于 SSH; 端口80,允许通过 HTTP 服务 Buildbot; 以及端口443,允许通过 HTTPS 服务 Buildbot。 如果你已经用 Let’ s Encrypt 保护了你的服务器,那么所有这三个端口都是必需的,但是如果你没有这样做,也不打算这样做,那么你可以排除端口443:

  • sudo sysrc firewall_myservices="22/tcp 80/tcp 443/tcp"

允许从任何 IP 地址访问防火墙 myservices 指令中指定的端口:

  • sudo sysrc firewall_allowservices="any"

配置防火墙在启动时启动:

  • sudo sysrc firewall_enable=YES

然后用基本规则启动防火墙。 下面的 nohup 命令避免了防火墙启动的中断,还将 stderr 和 stdout 重定向到一个临时日志文件。 这一点很重要,所以不要让防火墙规则处于不一致的状态,这可能会使远程主机通过 SSH 无法访问:

  • sudo nohup service ipfw start >/tmp/ipfw.log 2>&1

如果您使用 csh 或 tcsh shell,这个重定向将导致暧昧输出重定向。 出现在你的作品中。 如果您正在使用这两个 shell 中的任何一个,请运行 sudo nohup service ipfw start & / tmp / ipfw。 登录以下代替开始 ipfw:

此时,防火墙服务将启动并开始保护主机免受到不安全端口的连接。

注意: 如果出了问题或者您使用了不同的防火墙类型,防火墙可能还不知道您的 SSH 连接的状态,从而导致您与服务器的连接中断。 您可以通过在 shell 中键入一些内容来查找。 在失速连接期间,字符将不会在远程端打印。 如果是这种情况,您可以等到 SSH 通知超时,或者通过一个接一个地按下这些键退出挂起终端: ENTER,~ ,。 关闭 SSH 连接之后,从本地机器重新连接到服务器: SSH [email protected] server ip 如果 SSH 连接无法重新建立,您将需要使用替代方法连接到服务器。 例如,如果您正在使用 DigitalOcean 雾滴,您可以使用它的“控制台访问”功能,以根用户身份使用您先前设置的密码登录。 一旦您重新获得访问权限,禁用防火墙: sudo 服务 ipfw stop 随着防火墙停止,您将可以自由地调试问题。

接下来,您需要确定连接到互联网的主机的网络接口:

  • ifconfig

这个命令可以输出两个不同的接口。 主机用于连接到互联网的 IP 地址包括服务器的公共 IP 地址。 为了说明这一点,下面的输出示例显示 vtnet0是主机使用的网络接口:

Output
vtnet0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=6c07bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6> ether 9a:3e:fa:2a:5f:56 hwaddr 9a:3e:fa:2a:5f:56 inet6 fe80::983e:faff:fe2a:5f56%vtnet0 prefixlen 64 scopeid 0x1 inet public_server_ip netmask 0xffffffc0 broadcast broadcast_ip inet 10.10.0.23 netmask 0xffff0000 broadcast 10.10.255.255 nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL> media: Ethernet 10Gbase-T <full-duplex> status: active lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384 options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6> inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2 inet 127.0.0.1 netmask 0xff000000 nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL> groups: lo lo1: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384 options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6> inet 10.0.0.2 netmask 0xffffff00 inet 10.0.0.3 netmask 0xffffff00 inet6 fe80::1%lo1 prefixlen 64 scopeid 0x3 nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL> groups: lo

记下这个界面,然后全局配置它的名称:

  • sudo sysrc firewall_nat_interface=vtnet0

打开新的防火墙配置脚本文件:

  • sudo ee /usr/local/etc/ipfw.rules

然后在文件中添加以下内容,定义 IPFW 的防火墙规则:

/usr/local/etc/ipfw.rules
#!/bin/sh
set -e

# Add basic rules as defined by firewall_type, firewall_myservices, etc.
. /etc/rc.firewall

# External network interface
ext_if="$firewall_nat_interface"

# The interface we chose for communication between jails
jail_if="lo1"

for interface in "$ext_if" "$jail_if"; do
    if [ -z "$interface" ]; then
        >&2 echo "Missing network interface"
        exit 1
    fi
    if ! ifconfig $interface >/dev/null 2>&1; then
        >2 echo "No such network interface: $interface"
        exit 1
    fi
done

ipfw nat 123 config if $ext_if
ipfw add 1 allow all from any to any via $jail_if
ipfw add 2 nat 123 ip4 from any to any in via $ext_if
ipfw add 501 skipto 20000 udp from any to any 53 out via $ext_if keep-state
ipfw add 502 skipto 20000 udp from any to any 67 out via $ext_if keep-state
ipfw add 503 skipto 20000 tcp from any to any out via $ext_if setup keep-state
ipfw add 504 skipto 20000 icmp from any to any out via $ext_if keep-state
ipfw add 19999 deny all from any to any
ipfw add 20000 nat 123 ip4 from any to any out via $ext_if
ipfw add 20001 allow ip from any to any

以下是剧本的每一部分:

  • . / etc / rc. 防火墙包括系统预定义的 IPFW 规则脚本,它根据 / etc / rc 中防火墙 * 变量的配置添加基本规则。 自信。
  • 下一个块检查是否所有配置的接口都存在。 这是为了您的安全,如果出现错误配置,请尽早退出脚本。
  • 以 ipfw 开头的指令添加了实际的防火墙配置和规则。 在以 ipfw add-开头的行中添加的每个规则都有一个数字。 防火墙使用这些数字按顺序计算规则。 Ipfw NAT 123 config if $ext if 创建一个 ID 为“123”的内核 NAT 设施来使用面向公众的网络接口转换流量。 如果允许监狱之间的所有交通,则允许从任何到任何 via $jail 的所有交通。 请注意,如果允许规则匹配,则停止规则处理并允许数据包通过。 2 nat 123 ip4 from any to any in via $ext if translation all incoming IPv4 packets on the external interface. 正如 ipfw add 20000... 的解释中所描述的那样,这是需要作为对外发数据包的翻译的副本。 Ipfw 通过 $ext if keep-state 将501 skipto 20000 udp 从 any 添加到任何53 out,以下 skipto 规则定义允许哪些出站通信,并考虑进行网络地址转换。 如果有匹配,处理将跳转到执行 NAT 的规则20000。 规则501有意地出现在默认的回送规则之后,这些规则拒绝来自本地网络的流量(127.0.0.0.0 / 8和: : 1) ,比如00300 deny ip from 127.0.0.0 / 8 to any。 运行 sudo ipfw list 查看当前活动的防火墙规则(但请注意,我们还没有应用上述更改)。 除了船长规则之外,在规则2和1999之间有一个故意的差距,其中 / etc / rc。 防火墙脚本插入某些基本规则。 如果以上所有的 skipto 规则都不匹配,那么基本的规则将负责允许不同类型的流量,包括回送、传入 ICMP ping 消息和防火墙 myservices 指定的端口。 1999 deny all from any to any comes after all the basic rules and preserved the end of non-NAT rule processing,实质上是禁止所有未与之前允许规则匹配的流量。 如果将所有离开外部接口的出站 IPv4包的地址转换为外部接口,则 ipfw 添加20000 nat 123 ip4。 这里只需要 IPv4,因为在本教程中,监狱只分配 IPv4地址。 Ipfw add 20001允许 ip from any to any 仅当您关闭了 nat rules 的单通模式时才是必需的,在这种情况下,处理将在通过 rule 20000之后继续,要求您使用单独的规则显式地允许这些包通过。 对于默认的单通模式,防火墙将在 nat rule 处停止处理,因此忽略 rule 20001。

保存文件并退出编辑器。

因为我们想用 ipfw.rules 脚本中定义的规则修改预定义的基本防火墙规则,所以必须指向 rc.conf 文件中的这个脚本。 以下命令将脚本配置为在防火墙启动时执行:

  • sudo sysrc firewall_script="/usr/local/etc/ipfw.rules"

这种设置使用 IPFW 的内核 NAT 支持,因此您必须告诉系统在引导时加载相应的内核模块。 此外,立即加载模块而不需要重新启动:

  • sudo sysrc -f /boot/loader.conf ipfw_nat_load=YES
  • sudo kldload ipfw_nat

重新启动防火墙,使扩展的防火墙规则脚本生效:

  • sudo nohup service ipfw restart >/tmp/ipfw.log 2>&1

同样,如果您正在使用 csh shell 或其派生程序(如 tcsh) ,请运行 sudo nohup 服务 ipfw restart & / tmp / ipfw。 而不是先前的命令来重启防火墙:

检查防火墙规则是否已正确加载:

  • cat /tmp/ipfw.log

这里列出了防火墙规则,然后是一条成功的消息:

Output
Flushed all rules. 00100 allow ip from any to any via lo0 [...] 65500 deny ip from any to any Firewall rules loaded.

你也可以随时使用以下软件查看已安装的防火墙规则:

  • sudo ipfw list
Output
00001 allow ip from any to any via lo1 00002 nat 123 ip from any to any in via em0 [...] 65535 deny ip from any to any

有了所有的防火墙规则,你们的监狱现在可以访问互联网了。 你可以试着从监狱里下载一个网页:

  • sudo jexec buildbot-master fetch -q -o- http://example.com/
Output
<!doctype html> <html> <head> <title>Example Domain</title> [...]

有了这些,你已经成功地让这两个监狱像正常的操作系统一样运行,为每个监狱设置了互联网接入,并启动了这两个监狱。 本教程接下来的两个步骤将指导您安装主组件和辅助组件,然后将它们作为服务运行。

步骤3-安装和运行 Buildbot Master

Buildbot 的组件被分成几个包。 您只需安装 py36-buildbot 包就可以运行主组件,但是在本指南中,我们还将介绍如何安装 web 界面包 py36-buildbot-www。

因为我们使用 jail 来分割各个组件,所以从在 master jail 中打开一个 root shell 开始:

  • sudo jexec buildbot-master csh

请注意,在本指南中,如果 shell 命令块必须在 jailshell 中执行,则会用不同的颜色标记它们。 此外,命令提示符将反映监狱的哪些用户配置文件——根用户或无特权的构建 bot-master 用户——命令必须在这些配置文件下运行。

安装软件包:

  • pkg install py36-buildbot py36-buildbot-www

如果你还没有在这个监狱安装或使用 pkg 包管理器,它会提示你确认你允许它自己引导。 要做到这一点,请按 y 然后输入。 然后,通过再次输入 y 来批准 Buildbot 包的安装。

接下来,创建一个普通的、无特权的用户来运行主服务。 下面的命令将为这个用户分配一个随机密码,但是你不需要记住它,因为主机的 root 用户(监狱外的)可以更改它或者成为监狱内的任何用户,而不需要密码:

  • pw useradd -n buildbot-master -m -w random

接下来,创建主目录来存储配置:

  • mkdir /var/buildbot-master

并将所有权赋予服务用户:

  • chown buildbot-master:buildbot-master /var/buildbot-master

从现在开始,所有与主服务器相关的设置和更改都应该作为非特权用户执行,因为这将有助于保持所有权和权限的一致性。

切换到非特权用户:

  • su -l buildbot-master

然后使用内置的 buildbot 工具在指定的目录中创建一个目录和配置结构:

  • buildbot-3.6 create-master /var/buildbot-master

与像 Jenkins 这样的其他 CI 软件不同,Buildbot 的行为是直接在其配置文件中定义的,配置文件用 Python 进行解释。 这允许对你的配置进行简化版本控制,同时使用脚本语言版本控制允许自由编写自定义构建配置和扩展现有的 Buildbot 功能。

Buildbot 包附带了一个示例主配置文件,您可以将其用作自己配置的模板。 复制示例配置并将其命名为 master.cfg:

  • cp /var/buildbot-master/master.cfg.sample /var/buildbot-master/master.cfg

然后用你喜欢的文本编辑器打开基本配置文件:

  • ee /var/buildbot-master/master.cfg

配置文件包含工作人员连接到主服务器所需的密码。 用您选择的安全密码替换默认密码。 此外,我们的工人的名字将是 worker0,所以在 WORKERS 和 BUILDERS 部分中也将 example-worker 替换为 worker0。

完成后,你需要编辑的文件部分看起来如下:

/var/buildbot-master/master.cfg
####### WORKERS

# ...
c['workers'] = [worker.Worker("worker0", "your_secure_password")]
# ...

####### BUILDERS

# ...
c['builders'] = []
c['builders'].append(
    util.BuilderConfig(name="runtests",
      workernames=["worker0"],
      factory=factory))
# ...

保存并关闭这个文件,然后运行 exit 命令切换回监狱中的 root 用户:

  • exit

由于示例配置将 Git 仓库 Git: / / github.com/buildbot/hello-world.Git 作为其更改源,因此您还需要安装 Git:

  • pkg install git-lite

这样,您已经创建了主目录结构和配置,但是服务还没有运行。 要手动运行 Buildbot,可以从 master 目录 / var / Buildbot-master 运行命令 Buildbot start。 但是,这并不考虑启动时的启动或其他系统范围的配置。 相反,我们将使用 rc 脚本,这是 FreeBSD 运行服务的标准方法。 具体来说,我们将使用服务实用程序来实现这一点。

出于本教程的目的,我们希望在每次引导时都启用该服务。 就监狱而言,这意味着监狱的开始事件。 使用以下命令定义主目录的位置:

  • sysrc buildbot_basedir=/var/buildbot-master

然后指定该服务应该在 buildbot-master 用户下运行:

  • sysrc buildbot_user=buildbot-master

接下来,在 jail startup 中启用该服务:

  • sysrc buildbot_enable=YES

在撰写本文时,py36-buildbot 包有一个 bug,它阻止服务启动(请参阅这个 bug 报告)。 在这个问题解决之前,你需要在你的 buildbot-master 监狱中运行以下命令手动修补开始脚本:

  • sed -i '' 's|command="/usr/local/bin/buildbot"|command="/usr/local/bin/buildbot-3.6"|' /usr/local/etc/rc.d/buildbot

然后,启动服务:

  • service buildbot start

服务开始时没有错误。您可以通过查看日志文件的内容来验证是否成功:

  • tail /var/buildbot-master/twistd.log
Output
2018-06-08 15:14:52+0000 [-] Starting BuildMaster -- buildbot.version: 0.9.11 2018-06-08 15:14:52+0000 [-] Loading configuration from '/var/buildbot-master/master.cfg' [...] 2018-06-08 15:14:52+0000 [-] BuildMaster is running

要返回到主 shell,运行从 jail shell 退出:

  • exit

您已经成功地配置并启动了 Buildbot 主服务。 第二个组件,即 worker,需要实际运行构建。 您将在第二个监狱的下一节中安装一个 worker,然后配置它与主服务的连接。

步骤4-安装和运行 Buildbot 工作程序

尽管 Buildbot 主机正在运行,但由于至少需要一个工作者运行,因此不会发生任何构建。 这一步与前一步类似,我们将首先建立一个单独的监狱,然后安装服务。 但是,这一次 Buildbot 工作组件将连接到主机,以侦听命令并报告结果。

这个步骤中的指令几乎与主设置相同,只是辅助组件是另一个包的一部分,而您将做的唯一配置更改包括添加关于将其连接到主设置的详细信息以及关于辅助组件本身的一些显示信息。

确保您在主机 shell 中,而不是在监狱中。 然后在工人监狱中打开一个 root shell:

  • sudo jexec buildbot-worker0 csh

请记住,在本指南中,如果命令块必须在 jail shell 中执行,那么它们将被标记为不同的颜色,并且命令提示符将反映命令应该在哪个用户配置文件下运行。

使用以下命令安装 Buildbot 工人包:

  • pkg install py36-buildbot-worker

当该命令运行时,它将提示您确认是否要引导 pkg 包管理实用程序。 输入 y 即可。 它还会要求您确认您批准了包的安装,因此在提示时再次输入 y。

接下来,创建一个普通的、无特权的用户来运行 worker 服务:

  • pw useradd -n buildbot-worker -m -w random

然后创建工作目录。 这是存储工作者配置、显示信息和构建目录的位置:

  • mkdir /var/buildbot-worker

给予服务使用者所有权:

  • chown buildbot-worker:buildbot-worker /var/buildbot-worker

从现在开始,所有与工作者相关的设置和更改都应该作为非特权用户执行。 为此,切换到 buildbot-worker 用户:

  • su -l buildbot-worker

使用内置的 buildbot-worker 实用程序在 / var / buildbot-worker 目录中创建目录和配置结构。 指定主监狱的 IP 地址ー10.0.0.2,我们在前面的步骤中选择了这个地址ー这样工作人员就可以连接到主监狱,并用您在主配置文件中定义的密码替换 pass:

  • buildbot-worker-3.6 create-worker /var/buildbot-worker 10.0.0.2 worker0 'pass'

为了完成设置,填写一些关于系统管理员和工人目的的细节:

  • echo 'Your Name <[email protected]>' >/var/buildbot-worker/info/admin
  • echo 'Description of this worker' >/var/buildbot-worker/info/host

然后,运行 exit 命令切换回监狱中的 root 用户:

  • exit

因为示例配置克隆了 Git 存储库 Git: / / github.com/buildbot/hello-world.Git 来构建示例项目,所以您还需要在这个监狱中安装 Git。 注意 Buildbot 主机还需要 Git,因为变更源在主机上运行。 此外,构建器使用了一个叫做 trial 的测试运行器,它是 py27-twisted 包的一部分,所以把它和 git-lite 一起安装:

  • pkg install git-lite py27-twisted

用于运行一个 worker 的内置机制是 buildbot-worker start,它应该从 worker 目录 / var / buildbot-worker 运行。 但是,这并不考虑启动时的启动,也不能确保它在正确的用户下运行。 正如对 master 所做的那样,通过使用服务实用程序利用打包的 rc 脚本来管理服务。

使用以下命令定义工作目录以及服务应在其下运行的用户和组:

  • sysrc buildbot_worker_basedir=/var/buildbot-worker
  • sysrc buildbot_worker_uid=buildbot-worker
  • sysrc buildbot_worker_gid=buildbot-worker

接下来,在 jail startup 中启用该服务:

  • sysrc buildbot_worker_enable=YES

在编写本文时,py36-buildbot-worker 包有一个 bug,它阻止服务启动(请参阅这个 bug 报告)。 在这个问题解决之前,你需要从你的 buildbot-worker0监狱运行以下命令手动修补开始脚本:

  • sed -i '' 's|command="/usr/local/bin/twistd"|command="/usr/local/bin/twistd-3.6"|' /usr/local/etc/rc.d/buildbot-worker

最后,启动工作组件:

  • service buildbot-worker start

服务应该在没有错误的情况下启动。 您可以通过查看日志文件中的最新条目来验证它是否成功:

  • tail /var/buildbot-worker/twistd.log

如果服务成功启动,将在日志文件中显示诸如 Connected to 10.0.0.2:9989; worker is ready 之类的消息。 如果在此步骤的前面忘记指定新密码,服务将无法连接到主服务器。 在本例中,编辑文件 / var / buildbot-worker / buildbot。 然后运行服务 build-bot-worker restart 来纠正这个问题。

一旦服务正确启动,通过从 jail shell 运行 exit 命令退出到 host shell:

  • exit

有了这个,第二个监狱已经配置好了,您就拥有了操作 Buildbot 所需的所有基本组件。 为了便于用户使用,建议您也设置基于 web 的用户界面。 这样做可以让您更方便地控制 Buildbot 并查看构建结果。

步骤5-建立 Buildbot 网页界面

Buildbot 具有一个基于 web 的用户界面,显示构建概览和结果,并允许您在配置“强制”调度程序时手动触发构建,例如在示例配置中的情况。

您的主配置已经设置了 www 组件来通过端口8010提供 HTTP 服务。 在生产环境中,您不会向外部提供未加密的 HTTP 或打开非标准端口8010,因为这会使您的系统暴露出安全漏洞。 此外,web 界面可以从任何 URL 路径服务,这意味着它不需要是您的域上的唯一应用程序。 例如,您可以向用户提供构建输出或日志。 因此,我们将提供用户界面与一个单独的网络服务器-Nginx-为了支持 HTTPS,保护内部端口,并获得服务其他内容与 Buildbot 网络界面的能力。

打开 Nginx 配置文件进行编辑:

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

在文件的现有服务器块中添加以下高亮显示的位置块:

/usr/local/etc/nginx/nginx.conf
 . . .
http {
 . . .
    server {

 . . .
        location / {
            root /usr/local/www/nginx;
            index index.html index.htm;
        }

        location /buildbot/ {
            proxy_pass http://10.0.0.2:8010/;
        }
        location /buildbot/sse/ {
            # proxy buffering will prevent sse to work
            proxy_buffering off;
            proxy_pass http://10.0.0.2:8010/sse/;
        }
        # required for websocket
        location /buildbot/ws {
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_pass http://10.0.0.2:8010/ws;
            # raise the proxy timeout for the websocket
            proxy_read_timeout 6000s;
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root /usr/local/www/nginx-dist;
        }

                . . .

    }
}

这个配置将 URL 路径 / buildbot / 之下的所有请求转发到 web 界面,并启用 WebSocket 支持,该界面使用 WebSocket 接收将显示的更新,例如正在运行的构建的日志输出。

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

  • sudo service nginx reload

在你的本地机器上打开你喜欢的网页浏览器,通过下面的 URL 访问 Buildbot 网页界面:

https://example.com/buildbot/

或者,如果没有为服务器设置域名,则需要输入服务器的公共 IP 地址 http: / / your server IP / buildbot / 。

当你到达界面时,你会看到一个类似于下面的概述:

主页面可能会显示一个警告,表明 Buildbot URL 配置错误。 如果 nginx.conf 文件中提供的主机名与主 Buildbot 配置中列出的主机名不匹配,就会发生这种情况。 由于构建结果电子邮件包含链接到 Buildbot 网页界面默认,主人必须知道正确的 URL,它可以到达。

请注意,在我们的示例配置中,我们没有设置此电子邮件服务。 如果你对这个配置感兴趣,请参阅 Buildbot 关于记者的文档以获得更多信息:

也就是说,要解决警告和发送包含正确内容的电子邮件,请编辑 Buildbot 主配置以指向您的域。

  • sudo ee /usr/jails/buildbot-master/var/buildbot-master/master.cfg

找到以 c [‘ buildbotURL’]开头的行,并用您的域名替换缺省选项,后跟 / buildbot / :

/var/buildbot-master/master.cfg
####### PROJECT IDENTITY
# ...
c['buildbotURL'] = 'https://example.com/buildbot/'
# ...

保存并关闭文件,然后,要应用新的配置,重新加载 buildbot 服务:

  • sudo jexec buildbot-master service buildbot reload

刷新浏览器中的 Buildbot web 界面,警告将消失。

持续集成服务器通常除了用于 CI 之外还用于其他目的。 例如,CI 服务器可能通过 HTTPS 为 FreeBSD 包或日志提供构建输出。 因此,建议您为 web 界面保留 URL 路径 / buildbot / 。 这允许您在不同的路径下托管更多的应用程序。 目前,我们将创建一个简单的主页,重定向到 web 界面。 一旦你为网络服务器实现了更多的用例,你可以添加更多的链接。

运行以下命令在你的网站上打开一个索引文件-用你自己的域名替换 example. com-创建一个自动重定向到 Buildbot 网站界面:

  • sudo ee /usr/local/www/example.com/html/index.html

注意: 如果您没有遵循先决条件 Nginx 教程并为您的 Nginx 配置创建一个新的 web 根,那么您将需要通过运行 sudo ee / usr / local / www / Nginx / index. html 在缺省 Nginx web 根下创建一个索引文件。

用以下行代替任何现有的文件内容:

/usr/local/www/nginx/index.html
<html>
<body>
<a href="/buildbot/">buildbot</a>
<script>
    // Auto-redirect while only the web interface should be served
    window.location.href = "/buildbot/";
</script>
</body>
</html>

保存并关闭此文件,然后在浏览器的 URL 栏中输入您的域名或 IP 地址。 它会自动将你重定向到 Buildbot 界面。

您已经完成了所有 Buildbot 组件的安装,包括其基于 web 的控件和查看界面。 完成所有这些之后,让我们按照为主配置设置的示例配置中指定的方式运行一个实际的构建。

构建器有一个默认配置的“强制”调度程序,它允许您触发第一个构建。 在 web 界面中,单击 Builders runtests 强制 Start Build 并查看 Build 如何运行。 如果您看到任何错误,请检查服务器的 internet 连接,以及是否所有相关包都按照前面描述的那样安装了。

您可以通过查看构建目录的内容来找到这个构建(以及其他构建)中的工件:

  • ls /usr/jails/buildbot-worker0/var/buildbot-worker/runtests
Output
build

您已经成功地配置了一个永久运行的多功能 CI 系统,现在可以开始实现自己的构建了。

总结

通过完成本教程,您可以练习创建 FreeBSD 监狱,并学习 Buildbot 自动化框架的一些基本知识,从而得到一个即用的安装。 要了解更多关于 Buildbot 及其配置的信息,我们鼓励您阅读 Buildbot 官方文档。

从这里,您可以自由地实现自己的持续集成和自动化实践。 为了拥有一个安全、稳定和高性能的生产环境,你可以采取以下可选配置步骤:

  • 仅使用 HTTPS (如本教程中所解释的)
  • 在本教程中,您为您的监狱使用了一个单独的、主机内部的网络 lo1。 在本指南中,我们出于 NAT 目的使用 ipfw,但是其他防火墙也有这个特性。 查看有关可用防火墙的 FreeBSD 文档。 除非您的用例另有要求,否则建议通过使用 NAT 或其他机制来保持监狱网络从外部无法访问。
  • 默认情况下,Buildbot 的 web 界面不需要登录或检查用户权限。 要实现这些,您必须启用用户身份验证。