FreeBSDでBuildbotを設定する方法
著者は、 Open Internet / Free Speech Fund を選択して、 Write forDOnationsプログラムの一環として寄付を受け取りました。
序章
Buildbot は、継続的インテグレーション(CI)の目的で一般的に使用されるジョブスケジューリングシステムです。 CIはソフトウェア開発の実践であり、通常、定期的かつすべての変更に対してソフトウェアを自動的に構築およびテストすることで構成されます。 通常、CIプラットフォームとして使用されますが、Buildbotは、コンピューターで実行される自動化されたタスクにも使用できます。 Buildbotのタスク実行構成には、次の4つのコンポーネントが含まれています。
- 変更ソース:これらは、Gitリポジトリ内の変更などの変更を検出し、スケジューラーに通知します
- スケジューラー:スケジューラーは、着信する変更に応じてビルダーをトリガーします
- Builders :これらには、ソフトウェアプロジェクトのコンパイルなど、実際のビルド手順が含まれています
- レポーター:レポーターはビルド結果を使用して失敗メールやその他の通知を送信します
Buildbotは、少なくとも1つの Buildbot master を介して機能します。このマスターは、すべてのビルド構成とその他の設定を実行およびチェックし、実際のビルドをワーカーに配布します。 さらに、マスターはブラウザーベースのユーザーインターフェイスサブコンポーネントを提供します。これは、有効になっている場合、ビルドをトリガーまたは表示し、ステータスレポートやその他の設定を確認するために使用されます。 マスターに接続してコマンドを受信する、つまりビルドを実行する1つ以上のBuildbotワーカーもあります。
このガイドでは、FreeBSD jailを使用して、各Buildbotコンポーネントを個別の分離された環境にインストールして実行します。 次に、Nginx Webサーバーを使用してBuildbotにサービスを提供し、ローカルマシンのWebブラウザーを使用してそのWebインターフェイスにアクセスします。 このガイドを完了すると、サンプルプロジェクトビルドを使用した作業セットアップが完了し、独自のCIまたは他のユースケースに拡張できるようになります。
前提条件
このガイドを開始する前に、次のものが必要です。
- FreeBSD 11.2を実行しているサーバー。ただし、サポートされている新旧のバージョンのFreeBSDも同様に機能するはずです。 FreeBSDを初めて使用する場合は、 FreeBSDの使用を開始する方法のガイドに従って、このサーバーをカスタマイズすると役立つ場合があります。
- Nginxがサーバーにインストールされています。 FreeBSD11.2にNginxをインストールする方法に関するガイドに従ってこれを設定する方法を読んでください。
安全なHTTPSを使用してBuildbotWebインターフェイスをホストする場合は、次のものも必要です。
- あなたが所有および管理する登録済みドメイン名。 まだドメイン名を登録していない場合は、そこにある多くのドメイン名レジストラの1つに登録できます(例: Namecheap、GoDaddyなど)。
- ドメインがサーバーのパブリックIPアドレスを指すDNSARecord。 これが必要なのは、Let’s Encryptが、証明書を発行しているドメインを所有していることを検証する方法のためです。 たとえば、
example.com
の証明書を取得する場合、検証プロセスを機能させるには、そのドメインをサーバーに解決する必要があります。 これを追加する方法の詳細については、このDNSクイックスタートガイドに従うことができます。 このチュートリアルでは、ドメイン名の例としてexample.com
を使用します。 - ドメインのSSL/TLS証明書。 FreeBSDでLet’sEncryptを使用してNginxを保護する方法に従って、これを設定してください。
ステップ1-Buildbotマスターとワーカー用のJailを設定する
Buildbotを使用すると、外部の寄稿者がシステム上でコードを実行できるため、任意または悪意のあるコードがサーバーのリソースを占有しないように、さまざまなコンポーネントを分離することをお勧めします。 このチュートリアルでは、FreeBSDjailを使用してこれを行います。
LXC、Docker、およびその他のコンテナーメカニズムと同様に、FreeBSD jailは、ホストシステムからの軽量な分離を提供します。 刑務所内で実行されているプロセスは、刑務所がすでにアクセスを許可されているリソースにのみアクセスできます。 それ以外の点では、他のFreeBSD環境と同じように動作します。 Jailsは同じカーネルを共有しますが、通常、FreeBSDベースシステムのコピーを持つファイルシステムで実行されます。これは、ホストカーネルと互換性のあるFreeBSDの任意のバージョンである可能性があります。 ほとんどのワークロードでは、ホストでのタスクの実行とjailでのタスクの実行のパフォーマンスの違いは目立ちません。
FreeBSD jailの作成と管理を支援するために、いくつかの外部ソフトウェアパッケージが存在します。 これらはいずれもデファクトスタンダードではないため、オペレーティングシステムに組み込まれているjail構成メカニズムを使用します。
まず、システムの刑務所用に別のネットワークインターフェイスを作成します。 刑務所では、カーネルはネットワーク接続を刑務所に割り当てられた最初のIPv4/IPv6アドレスに書き換えます。 たとえば、最初に割り当てられたIPアドレスがパブリックであり、刑務所内のサービスが127.0.0.1:1234
でリッスンしている場合、ポート1234
はパブリックにアクセス可能になります。 推奨される方法は、刑務所用に別個のネットワークインターフェースを用意することです。 プライマリループバックインターフェイス(lo0
)を別のインターフェイス(lo1
)にクローニングするというこの推奨事項に従います。 ネットワーク10.0.0.0/24
を使用しますが、他の重複しないネットワークも同様に機能します。
起動時に作成されるクローンインターフェイスを構成することから始めます。 このsysrc
コマンドは、/etc/rc.conf
ファイルにルールを書き込みますが、インターフェイス自体は作成しません。
- sudo sysrc cloned_interfaces+=lo1
次に、次のコマンドを使用してネットワークインターフェイスを作成します。
- sudo service netif cloneup
インターフェイスの状態とIPは次の方法で確認できます。
- ifconfig lo1
Outputlo1: 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
は、このインターフェイスがローカルでのみ使用可能であり、実際のハードウェアデバイスを表していないことを意味します。
次に、お好みのエディターを使用して、マスターjailの新しい構成ファイルを開きます。 ここでは、ee
を使用します。
- sudo ee /etc/jail.buildbot-master.conf
次に、次のコンテンツをファイルに追加します。これにより、buildbot-master
という名前のマスター刑務所が構成されます。
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
の値は、jailのstart
およびstop
サービスがブートプロセスのように動作し、 /etc/
ディレクトリ。 persist
オプションを使用すると、すべてのプロセスが終了した場合でも、jailを実行し続けることができます。
可能なマスターjail設定の詳細については、 jail(8)のマンページを確認してください。
このコンテンツを追加したら、保存してエディターを終了します。 ee
を使用している場合は、CTRL+C
を押し、exit
と入力して、ENTER
を押します。
マスターjailの構成ファイルは、グローバルjail構成ファイル/etc/jail.conf
とは別のものです。 このため、既知の刑務所のリストにマスター刑務所の名前を追加する必要があります。
- sudo sysrc "jail_list+=buildbot-master"
次に、jail_list
にリストされているジェイルを有効にして、起動時に自動的に開始します。
- sudo sysrc jail_enable=YES
システムに/etc/jail.conf
グローバルファイルで構成されたjailが既にあり、以前にjail_list
を使用したことがない場合、この設定を有効にすると、jail_list
のjailのみが有効になります。自動起動すると、既存のjailをリストに追加できます。
注: ZFSファイルシステムを使用する場合は、後で簡単にバックアップ、複製、または破棄できるように、jailのファイル用に別のデータセットを作成することをお勧めします。 次のコマンドは、zpoolの標準名がzroot
であることを前提としています。 zpoolの名前がわからない場合は、次のコマンドで見つけることができます。
- zpool list
まず、すべての刑務所の親データセットを作成します。
- sudo zfs create zroot/usr/jails
次に、マスター刑務所のデータセットを作成します。
- sudo zfs create zroot/usr/jails/buildbot-master
次に、マスターjailのルートディレクトリを作成し、FreeBSDシステムを抽出します。
jailのルートファイルシステムディレクトリが存在することを確認します。 前のメモでZFSコマンドを実行した場合、これはすでに実行されているため、次のコマンドをスキップできます。
- sudo mkdir -p /usr/jails/buildbot-master
次に、FreeBSD11.2ベースシステムアーカイブをダウンロードします。 まず、ダウンロードサーバーを信頼するためにルート証明書をインストールします。
- sudo pkg install ca_root_nss
このコマンドは、ca_root_nss
パッケージのインストールを承認するように求めるプロンプトを表示します。 y
を押してから、ENTER
を押します。
次に、アーカイブをダウンロードします。
- fetch -o /tmp/base.txz "https://download.freebsd.org/ftp/releases/amd64/11.2-RELEASE/base.txz"
このファイルの内容をjailのルートファイルシステムとして抽出します。
- sudo tar -x -f /tmp/base.txz -C /usr/jails/buildbot-master
このガイドでは、1人のワーカー(これもjailに含まれています)をインストールするプロセスについて説明します。マスターと同じ方法で、ダウンロードしたベースシステムを再利用して構成します。 ee
コマンドを使用して、ワーカーjailの別の新しい構成ファイルを開きます。
- sudo ee /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;
}
これらの行を見ると、ワーカーjailのホスト名、IP、およびルートファイルシステムディレクトリがマスターとは異なることに注意してください。 このファイルを保存して閉じます。
ここでも、グローバル/etc/jail.conf
の代わりに別のjail構成ファイルを使用しているため、既知のjailのリストに名前を追加します。
- sudo sysrc "jail_list+=buildbot-worker0"
注:マスターjailと同様に、ZFSファイルシステムを使用する場合は、ワーカーjailのファイル用に別のデータセットを作成することをお勧めします。 この場合も、次のコマンドはワーカーjailのデータセットを作成し、zpoolの標準名がzroot
であると想定します。
- sudo zfs create zroot/usr/jails/buildbot-worker0
マスターの場合と同じように、ダウンロード済みのFreeBSD11.2ベースシステムを抽出します。
- sudo mkdir /usr/jails/buildbot-worker0
- sudo tar -x -f /tmp/base.txz -C /usr/jails/buildbot-worker0
この時点で、両方のjailが構成され、追加のパッケージがインストールされていないFreeBSDベースシステムが含まれています。 刑務所を始めましょう:
- sudo service jail start
次のコマンドを使用して、システムで実行中のすべてのjailを一覧表示して、起動が成功したかどうかを確認します。
- jls
これにより、サーバーで現在実行されているjailを示す次のような出力が返されます。
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パッケージをインストールすることはできません。 これを解決するために読み続けてください。
ステップ2–刑務所のインターネットアクセスを設定する
マスターとワーカーの刑務所は稼働していますが、どちらもインターネットから遮断されています。 パッケージをインストールしたり、相互に通信したりできる必要があるため、インターネットに公開する必要があります。
これを解決するには、ホストのDNSリゾルバー構成を両方のjailにコピーします。
- 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(ネットワークアドレス変換)ネットワークルールを設定します。 この手順を完了すると、jailネットワークから出て行くトラフィックがホストのパブリックIPアドレスに変換されます。
前提条件からLet’sEncryptチュートリアルに従った場合、Webサーバーへのアクセスを許可するようにファイアウォールが構成されています。 その場合、以下の手順のいくつかは冗長になりますが、それらを再度実行しても害はありません。
警告:ファイアウォール構成に誤った変更を加えると、SSH経由でリモートホストにアクセスできなくなる可能性があるため、マシンへのログインに使用できる別の方法があることを確認することが重要です。 たとえば、DigitalOceanから取得したサーバーを使用している場合は、「コンソールアクセス」機能を使用してサーバーにアクセスできます。
この機能を介したアクセスを有効にするには、次のコマンドでrootパスワードを設定します。
- sudo passwd
または、次のように入力して、現在のユーザーのパスワードを設定することもできます。
- passwd
次のコマンドを使用して、事前定義されたworkstation
ファイアウォールルールをrc.conf
ファイルに含めます。 workstation
ルールはサーバーを保護しますが、ホストへのpingや動的ホスト構成プロトコルなどの基本的なサービスを許可します。
- sudo sysrc firewall_type="workstation"
次に、外部からのWebサーバーポートへのアクセスを許可します。 次のコマンドは、SSHの場合、ポート22
を介したトラフィックを許可します。 ポート80
、BuildbotをHTTP経由で提供できるようにします。 ポート443
により、BuildbotをHTTPS経由で提供できます。 Let’s Encryptでサーバーを保護している場合は、これら3つのポートすべてが必要ですが、保護していない場合や計画していない場合は、ポート443
を除外できます。
- sudo sysrc firewall_myservices="22/tcp 80/tcp 443/tcp"
firewall_myservices
ディレクティブで指定されたポートへの任意のIPアドレスからのアクセスを許可します。
- 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
シェルのいずれかを使用している場合、このリダイレクトによりAmbiguous output redirect.
が出力に表示されます。 これらのシェルのいずれかを使用している場合は、代わりにsudo nohup service ipfw start >&/tmp/ipfw.log
を実行して、ipfw
を起動します。
この時点で、ファイアウォールサービスが開始され、セキュリティで保護されていないポートへの接続からホストを保護し始めます。
注:問題が発生した場合、または別のファイアウォールタイプを使用した場合、ファイアウォールがSSH接続の状態をまだ認識していないため、サーバーへの接続が停止している可能性があります。 シェルに何かを入力することで見つけることができます。 接続が停止している間、文字はリモート側に印刷されません。 この場合、SSHがタイムアウトに気付くまで待つか、ENTER
、~
、.
のキーを次々に押して、ハングしている端末からドロップアウトすることができます。 ]
SSH接続が閉じられたら、ローカルマシンからサーバーに再接続します。
- ssh freebsd@your_server_ip
SSH接続を再確立できない場合は、別の方法を使用してSSH接続に接続する必要があります。 たとえば、DigitalOcean Dropletを使用している場合は、その「コンソールアクセス」機能を使用して、以前に設定したパスワードでrootユーザーとしてログインできます。
アクセスを回復したら、ファイアウォールを非アクティブ化します。
- sudo service ipfw stop
ファイアウォールを停止すると、問題を自由にデバッグできます。
次に、インターネットに接続するホストのネットワークインターフェイスを決定する必要があります。 実行してこれを見つけます:
- ifconfig
このコマンドは、いくつかの異なるインターフェースを出力する場合があります。 ホストがインターネットに接続するために使用するものは、サーバーのパブリックIPアドレスを含むものです。 説明のために、次の出力例は、vtnet0
がホストによって使用されるネットワークインターフェイスであることを示しています。
Outputvtnet0: 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のファイアウォールルールを定義します。
#!/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.firewall
には、システムの事前定義されたIPFWルールスクリプトが含まれています。このスクリプトは、/etc/rc.conf
のfirewall_*
変数の構成に従って基本的なルールを追加します。- 次のブロックは、構成されているすべてのインターフェースが存在するかどうかを確認します。 これは安全のためであり、設定に誤りがある場合はスクリプトを早期に終了します。
ipfw
で始まるディレクティブは、実際のファイアウォール構成とルールを追加します。ipfw add
で始まる行に追加された各ルールには、番号が付いています。 ファイアウォールはこれらの番号を使用して、ルールを順番に評価します。ipfw nat 123 config if $ ext_ifは、IDが「123」のカーネル内NAT機能を作成し、パブリックに面したネットワークインターフェイスを使用してトラフィックを変換します。 ipfw add 1は、$jail_ifを介してanyからanyへのすべてを許可します。jail間のすべてのトラフィックを許可します。 許可ルールが一致すると、ルール処理が停止し、パケットの通過が許可されることに注意してください。 ipfw add 2 nat 123 ip4は、$ext_ifを介してanyからanyinに変換され、外部インターフェイス上のすべての着信IPv4パケットを変換します。 これは、ipfw add 20000 …の説明で説明されているように、発信パケットの変換に対応するものとして必要です。 ipfw add 501 skipto 20000 udp from any to any 53 out via $ ext_if keep-stateおよび次のskiptoルールは、ネットワークアドレス変換を許可および考慮するアウトバウンドトラフィックを定義します。 一致する場合は、NATを実行するルール20000にジャンプして処理を続行します。 ルール番号501は、ローカルのみのネットワーク(127.0.0.0/8および:: 1)からのトラフィックを拒否するデフォルトのループバックルール(00300 deny ip from 127.0.0.0/8 to anyなど)の後に意図的に付けられています。 sudo ipfw listを実行して、現在アクティブなファイアウォールルールを確認します(ただし、上記の変更はまだ適用されていないことに注意してください)。 skiptoルールを除いて、ルール2と19999の間には、/ etc/rc.firewallスクリプトが特定の基本ルールを挿入する意図的なギャップがあります。 上記のskiptoルールのいずれにも一致しない場合、基本ルールは、ループバック、着信ICMP pingメッセージ、firewall_myservicesで指定されたポートなどのさまざまなタイプのトラフィックの許可を処理します。 ipfw add 19999は、すべての基本ルールの後にすべてを拒否し、非NATルール処理を確実に終了させ、以前の許可ルールと一致しなかったすべてのトラフィックを本質的に禁止します。 ipfw add 20000 nat 123 ip4は、$ext_ifを介してanyからanyoutに変換され、外部インターフェイスに残されるすべてのアウトバウンドIPv4パケットのアドレスを変換します。 このチュートリアルでは、jailにIPv4アドレスが排他的に割り当てられるため、ここで必要なのはIPv4のみです。 ipfw add 20001 allow ip from any to anyは、NATルールのワンパスモードをオフにした場合にのみ必要です。この場合、処理はルール20000を通過した後も続行され、別のルールでこれらのパケットを明示的に許可する必要があります。 。 デフォルトのワンパスモードの場合、ファイアウォールはNATルールで処理を停止するため、ルール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
シェルまたはその派生物の1つ(tcsh
など)を使用している場合は、前のコマンドの代わりにsudo nohup service ipfw restart >&/tmp/ipfw.lo
を実行して、ファイアウォールを再起動します。
ファイアウォールルールが正しくロードされていることを確認します。
- cat /tmp/ipfw.log
これにより、ファイアウォールルールが一覧表示され、その後に成功メッセージが表示されます。
OutputFlushed all rules.
00100 allow ip from any to any via lo0
[...]
65500 deny ip from any to any
Firewall rules loaded.
また、以下を使用して、インストールされているファイアウォールルールをいつでも表示できます。
- sudo ipfw list
Output00001 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
すべてのファイアウォールルールが設定されているので、刑務所はインターネットにアクセスできるようになります。 刑務所内からWebページをダウンロードして確認できます。
- sudo jexec buildbot-master fetch -q -o- http://example.com/
Output<!doctype html>
<html>
<head>
<title>Example Domain</title>
[...]
これで、通常のオペレーティングシステムのように実行できるように両方の刑務所を準備し、各刑務所にインターネットアクセスを設定し、両方を開始しました。 このチュートリアルの次の2つの手順では、マスターコンポーネントとワーカーコンポーネントの両方をインストールしてから、それらをサービスとして実行する方法について説明します。
ステップ3–Buildbotマスターのインストールと実行
Buildbotのコンポーネントは、いくつかのパッケージに分割されています。 マスターコンポーネントを実行するには、py36-buildbot
パッケージをインストールするだけで済みますが、このガイドでは、Webインターフェイスパッケージpy36-buildbot-www
のインストール方法についても説明します。
さまざまなコンポーネントをセグメント化するためにjailを使用しているため、マスターjailでrootシェルを開くことから始めます。
- sudo jexec buildbot-master csh
このガイドでは、シェルコマンドブロックをjailシェル内で実行する必要がある場合は、異なる色でマークされていることに注意してください。 さらに、コマンドプロンプトには、コマンドを実行する必要があるjailのユーザープロファイル(rootまたは非特権buildbot-masterユーザー)が反映されます。
パッケージをインストールします。
- pkg install py36-buildbot py36-buildbot-www
このjailにpkg
パッケージマネージャーをまだインストールまたは使用していない場合は、それ自体のブートストラップを許可することを確認するように求められます。 これを行うには、y
を押してから、ENTER
を押します。 次に、もう一度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
を使用します。
- ee /var/buildbot-master/master.cfg
構成ファイルには、ワーカーがマスターに接続するために必要なパスワードが含まれています。 デフォルトのpass
を、選択した安全なパスワードに置き換えます。 また、ワーカーの名前はworker0
になるため、WORKERS
セクションとBUILDERS
セクションの両方でexample-worker
をworker0
に置き換えます。
完了すると、編集する必要のあるファイルの部分は次のようになります。
####### WORKERS
# ...
c['workers'] = [worker.Worker("worker0", "your_secure_password")]
# ...
####### BUILDERS
# ...
c['builders'] = []
c['builders'].append(
util.BuilderConfig(name="runtests",
workernames=["worker0"],
factory=factory))
# ...
このファイルを保存して閉じてから、exit
コマンドを実行して、jail内のrootユーザーに切り替えます。
- exit
サンプル構成はGitリポジトリgit://github.com/buildbot/hello-world.git
を変更ソースとして監視しているため、Gitもインストールする必要があります。
- pkg install git-lite
これで、マスターディレクトリの構造と構成を作成しましたが、サービスはまだ実行されていません。 Buildbotを手動で実行するには、マスターディレクトリ/var/buildbot-master
からコマンドbuildbot start
を実行できます。 ただし、これは起動時の起動やその他のシステム全体の構成には対応していません。 代わりに、サービスを実行するためのFreeBSDの標準的な方法であるrcスクリプトを使用します。 具体的には、service
ユーティリティを使用してこれを行います。
このチュートリアルでは、起動のたびにサービスを実行できるようにします。 刑務所の場合、これは刑務所の開始イベントを意味します。 次のコマンドを使用して、マスターディレクトリの場所を定義します。
- sysrc buildbot_basedir=/var/buildbot-master
次に、サービスをbuildbot-masterユーザーで実行するように指定します。
- sysrc buildbot_user=buildbot-master
次に、jailの起動時にサービスを実行できるようにします。
- sysrc buildbot_enable=YES
執筆時点で、py36-buildbot
パッケージには、サービスの開始を妨げるバグがあります(このバグレポートを参照)。 これが修正されるまで、buildbot-master
jailから次のコマンドを実行して、開始スクリプトに手動でパッチを適用する必要があります。
- 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
Output2018-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
ホストシェルに戻るには、jailシェルからexit
を実行します。
- exit
これで、Buildbotマスターサービスが正常に構成および開始されました。 2番目のコンポーネントであるワーカーは、実際にビルドを実行するために必要です。 2番目の刑務所内の次のセクションに1人のワーカーをインストールしてから、マスターサービスへの接続を構成します。
ステップ4–Buildbotワーカーのインストールと実行
Buildbotマスターは実行されていますが、少なくとも1人のワーカーを実行する必要があるため、ビルドは発生しません。 この手順は、最初に別の刑務所を設定してからサービスをインストールするという点で、前の手順と似ています。 ただし、今回は、Buildbotワーカーコンポーネントがマスターに接続してコマンドをリッスンし、結果を報告します。
この手順の手順は、ワーカーコンポーネントが別のパッケージの一部であり、マスターへの接続に関する詳細とワーカー自体に関する表示情報を追加することを含む唯一の構成変更を除いて、マスターセットアップとほぼ同じです。
刑務所の中ではなく、ホストシェルにいることを確認してください。 次に、ワーカー刑務所でrootシェルを開きます。
- sudo jexec buildbot-worker0 csh
このガイドでは、コマンドブロックをjailシェル内で実行する必要がある場合、コマンドブロックは異なる色でマークされ、コマンドプロンプトには、コマンドを実行する必要があるユーザープロファイルが反映されることに注意してください。
次のコマンドを使用して、Buildbotワーカーパッケージをインストールします。
- pkg install py36-buildbot-worker
このコマンドを実行すると、pkg
パッケージ管理ユーティリティをブートストラップするかどうかを確認するメッセージが表示されます。 y
と入力してください。 また、パッケージのインストールを承認するかどうかの確認を求められるので、プロンプトが表示されたら、もう一度y
と入力します。
次に、ワーカーサービスを実行するための通常の非特権ユーザーを作成します。
- 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
コマンドを実行して、jail内のrootユーザーに切り替えます。
- exit
サンプル構成ではGitリポジトリgit://github.com/buildbot/hello-world.git
のクローンを作成してサンプルプロジェクトをビルドするため、このjail内にGitをインストールする必要もあります。 変更ソースはマスターで実行されるため、BuildbotマスターにもGitが必要であることに注意してください。 さらに、ビルダーはpy27-twisted
パッケージの一部であるtrial
と呼ばれるテストランナーを使用するため、git-lite
と一緒にこれをインストールします。
- pkg install git-lite py27-twisted
ワーカーを実行するための組み込みメカニズムはbuildbot-worker start
であり、ワーカーディレクトリ/var/buildbot-worker
から実行する必要があります。 ただし、これは起動時の起動を処理せず、正しいユーザーで実行されることを保証しません。 マスターで行ったように、service
ユーティリティを使用して、パッケージ化されたrc
スクリプトを活用して、サービスを管理します。
次のコマンドを使用して、ワーカーディレクトリと、サービスを実行するユーザーとグループを定義します。
- sysrc buildbot_worker_basedir=/var/buildbot-worker
- sysrc buildbot_worker_uid=buildbot-worker
- sysrc buildbot_worker_gid=buildbot-worker
次に、jailの起動時にサービスを実行できるようにします。
- sysrc buildbot_worker_enable=YES
執筆時点で、py36-buildbot-worker
パッケージには、サービスの開始を妨げるバグがあります(このバグレポートを参照)。 これが修正されるまで、buildbot-worker0
jailから次のコマンドを実行して、開始スクリプトに手動でパッチを適用する必要があります。
- 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.tac
を編集してから、service buildbot-worker restart
を実行してこの問題を修正してください。
サービスが正しく開始されたら、jailシェルからexit
コマンドを実行して、ホストシェルにドロップアウトします。
- exit
これで、2番目の刑務所が構成され、Buildbotの操作に必要なすべての基本コンポーネントが揃いました。 ユーザーがすぐに使用できるように、Webベースのユーザーインターフェイスも設定することをお勧めします。 そうすることで、Buildbotを制御し、ビルド結果をより便利に確認できるようになります。
ステップ5–BuildbotWebインターフェースのセットアップ
Buildbotは、ビルドの概要と結果を表示するWebベースのユーザーインターフェイスを備えており、サンプル構成の場合のように、「強制」スケジューラーが構成されている場合は手動でビルドをトリガーできます。
マスター構成では、ポート8010
を介してHTTPを提供するようにwww
コンポーネントがすでに設定されています。 本番環境では、暗号化されていないHTTPを提供したり、非標準ポート8010
を外部に開放したりすることはありません。これにより、システムがセキュリティの脆弱性にさらされる可能性があります。 また、Webインターフェイスは任意のURLパスから提供できるため、ドメイン上の唯一のアプリケーションである必要はありません。 たとえば、ビルド出力またはログをユーザーに提供できます。 したがって、HTTPSをサポートし、内部ポートを保護し、Buildbot Webインターフェイスと一緒に他のコンテンツを提供できるようにするために、別のWebサーバー(Nginx)を使用してユーザーにUIを提供します。
Nginx構成ファイルを開いて編集します。
- sudo ee /usr/local/etc/nginx/nginx.conf
次の強調表示されたlocation
ブロックを、ファイルの既存のserver
ブロック内に追加します。
. . .
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サポートを有効にします。
Nginx構成ファイルを保存して閉じます。 次に、Nginxサービスをリロードします。
- sudo service nginx reload
ローカルマシンでお好みのWebブラウザーを開き、次のURLにアクセスしてBuildbotWebインターフェイスにアクセスします。
https://example.com/buildbot/
または、サーバーのドメイン名を設定していない場合は、代わりにサーバーのパブリックIPアドレスhttp://your_server_ip/buildbot/
を入力する必要があります。
インターフェイスに到達すると、次のような概要が表示されます。
メインページに、BuildbotURLが正しく構成されていないという警告が表示される場合があります。 これは、nginx.conf
ファイルで提供されているホスト名がマスターBuildbot構成にリストされているものと一致しない場合に発生します。 ビルド結果の電子メールにはデフォルトでBuildbotWebインターフェイスへのリンクが含まれているため、マスターはアクセスできる正しいURLを知っている必要があります。
この構成例では、この電子メールサービスを設定していないことに注意してください。 これを構成することに興味がある場合は、Buildbotのレポーターに関するドキュメントを参照してください。
そうは言っても、警告を解決し、正しいコンテンツを含む電子メールを送信するには、ドメインを指すようにBuildbotマスター構成を編集します。
- sudo ee /usr/jails/buildbot-master/var/buildbot-master/master.cfg
c['buildbotURL']
で始まる行を見つけて、デフォルトのオプションをドメイン名に置き換え、その後に/buildbot/
を続けます。
####### PROJECT IDENTITY
# ...
c['buildbotURL'] = 'https://example.com/buildbot/'
# ...
ファイルを保存して閉じます。 次に、新しい構成を適用するには、buildbot
サービスをリロードします。
- sudo jexec buildbot-master service buildbot reload
ブラウザのBuildbotWebインターフェイスを更新すると、警告が消えます。
継続的インテグレーションサーバーは、多くの場合、CI以外の目的にも役立ちます。 たとえば、CIサーバーは、HTTPSを介してFreeBSDパッケージまたはログのビルド出力を提供する場合があります。 したがって、WebインターフェイスのURLパス/buildbot/
を予約することをお勧めします。 これにより、さまざまなパスでより多くのアプリケーションをホストできます。 今のところ、Webインターフェイスにリダイレクトする簡単なホームページを作成します。 Webサーバーのユースケースをさらに実装したら、リンクを追加できます。
次のコマンドを実行して、Webルートでインデックスファイルを開き、example.com
を独自のドメインに置き換えて、BuildbotWebインターフェイスへの自動リダイレクトを作成します。
- sudo ee /usr/local/www/example.com/html/index.html
注:しなかった前提条件のNginxチュートリアルに従って、Nginx構成の新しいWebルートを作成する場合は、代わりに下にインデックスファイルを作成する必要があります。 sudo ee /usr/local/www/nginx/index.html
を実行することによるデフォルトのNginxWebルート。
既存のファイルの内容を次の行に置き換えます。
<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インターフェースに自動的にリダイレクトされます。
これで、Webベースの制御および表示インターフェイスを含むすべてのBuildbotコンポーネントのインストールが完了しました。 これらすべてが整ったら、マスター用に設定したサンプル構成で指定されている実際のビルドを実行してみましょう。
ビルダーには、デフォルトで構成された「強制」スケジューラーがあり、これにより、最初のビルドをトリガーできます。 Webインターフェイスで、ビルド>ビルダー>実行テスト>フォース>ビルドの開始をクリックして、ビルドが実行されます。 エラーが表示された場合は、サーバーのインターネット接続を確認し、前述のようにすべての依存パッケージがインストールされているかどうかを確認してください。
ビルドディレクトリの内容を確認することで、このビルド(およびその他)のアーティファクトを見つけることができます。
- ls /usr/jails/buildbot-worker0/var/buildbot-worker/runtests
Outputbuild
これで、永続的に実行され、用途の広いCIシステムが正常に構成され、独自のビルドの実装を開始できるようになりました。
結論
このチュートリアルを完了することで、FreeBSD jailの作成を練習し、Buildbot自動化フレームワークの基本のいくつかを学び、すぐに使用できるインストールを実現しました。 Buildbotとその構成の詳細については、公式のBuildbotドキュメントをお読みになることをお勧めします。
ここから、独自の継続的インテグレーションと自動化のプラクティスを自由に実装できます。 本番環境で使用するための安全で安定したパフォーマンスの高いセットアップを行うには、次のオプションの構成手順を実行することをお勧めします。
- HTTPSのみを使用してください(このチュートリアルで説明されているように)
- チュートリアルでは、刑務所に別のホスト内部ネットワーク
lo1
を使用しました。 このガイドでは、NATの目的でipfw
を使用しましたが、他のファイアウォールにもこの機能があります。 利用可能なファイアウォールに関するFreeBSDのドキュメントをチェックしてください。 ユースケースで特に必要とされない限り、NATまたはその他のメカニズムを使用して、外部から刑務所ネットワークにアクセスできないようにすることをお勧めします。 - BuildbotのWebインターフェースは、デフォルトでログインやユーザー権限の確認を必要としません。 これらを実装するには、ユーザー認証を有効にする必要があります。