BuildbotとPoudriereを使用してFreeBSDサーバー用のパッケージをビルドおよびデプロイする方法

提供:Dev Guides
移動先:案内検索

著者は、 Write for DOnations プログラムの一環として、 Free and Open SourceFundを選択して寄付を受け取りました。

序章

FreeBSDポートおよびパッケージコレクション(以下ポートツリーと呼びます)は、FreeBSDの外部ソフトウェア用ビルドシステムです。 Makefileベースの一貫したパッケージ構築方法を提供します。 port は、ビルドレシピ、つまりMakefileと関連ファイルを指します。 一方、 package は、1つのポートをパッケージファイルとそのメタ情報のバイナリ(圧縮)アーカイブに構築した結果です。

make installを使用すると、30,000を超えるポートのサブセットまたはすべてを手動で構築およびインストールできます。 ただし、ビルドは、クリーンな環境ではなく、サーバーの1つで実行されます。 実稼働のユースケースの場合、手動ビルドは、各ホストがポートツリーの同じリビジョンを必要とし、それ自体のためにすべてのパッケージをコンパイルする必要があることも意味します。 これは、人間とサーバーによる繰り返しのエラーが発生しやすい作業を意味します。 各ホストで同一のビルド済みバイナリパッケージを取得して使用し、中央の安全なパッケージリポジトリから提供することをお勧めします。

これを実現するために、 Poudriere は、パッケージをビルド、テスト、監査し、パッケージリポジトリを維持するためのFreeBSDの標準ツールです。 各ビルドは、新しい jail で分離して実行され、目的のバージョンのFreeBSDを実行し、パッケージがインストールされていない状態で開始されます。 クリーンビルドで使用できるのは、基本システムと明示的に指定された依存関係のみです。 Poudriereは、必要に応じてパッケージを再構築し、ビルドの完了後にパッケージリポジトリを更新します。 poudriereコマンドラインツールは、さまざまなポートツリー、FreeBSDバージョン、ポートビルドオプションの管理、そして最後にビルドの実行の中心です。

このチュートリアルでは、Poudriereを構成し、必要なパッケージのセットをビルドし、HTTPベースのパッケージホスティングをセットアップし、継続的インテグレーションプラットフォームとしてBuildbotを使用してビルドを自動化します。 最後に、クライアントマシンからパッケージに安全にアクセスします。

注:本番環境のようなユースケースをカバーするために、チュートリアルの例では、ポートツリーの四半期ごとに安定したブランチを使用しています。 そのようなブランチの1つにとどまると、変更を壊さないように保護され、必要に応じてセキュリティとビルドの修正が提供されます。アップストリーム(SubversionまたはそのGitHubミラー)からツリーを定期的に更新する場合です。 開発者/インフラストラクチャチームがシステムの更新を処理できるペースに応じて、1つのブランチに長期間滞在することを選択できます。 ポートコレクションは、保守終了(EOL)になるまでFreeBSDリリースをサポートします(サポートされているFreeBSDリリースを参照)。これにより、OSとパッケージの更新を個別に処理できます。 または、アップストリームツリーから複製されたローカルバージョン管理リポジトリを検討することもできます。 これにより、パッチを管理し、必要なときにのみアップストリームの変更をマージできます。


前提条件

このガイドを開始する前に、次のものが必要です。

  • FreeBSD11.2を実行しているサーバー。 FreeBSDを初めて使用する場合は、 FreeBSDの使用を開始する方法のガイドに従って、このサーバーをカスタマイズすると役立つ場合があります。 注: FreeBSD 12.0には現在ネストされたjailsの問題があり、このチュートリアルで12.xを使用する前に最初に修正する必要があります。
  • パッケージとログを保存するのに十分な容量を持つための10GB以上の空きディスク容量。
  • FreeBSDでBuildbotをセットアップする方法チュートリアルを完了することによる、基本的なBuildbotのセットアップ。
  • 同じバージョンのFreeBSDを実行している別のサーバー。これは、HTTP /HTTPSベースのパッケージリポジトリで自動的にビルドおよびホストするパッケージをフェッチしてインストールするためのクライアントとして使用します。

ステップ1—BuildbotWorkerで使用するためのPoudriereのインストール

前提条件のチュートリアルを完了すると、Buildbotマスターとワーカーのjailに加えて、Nginxのセットアップが機能します。 次の手順で、この既存の設定に基づいて構築します。 この最初のステップでは、ビルドツールPoudriereをワーカーjail内にインストールします。これは、Buildbotワーカープロセスが後でビルドをトリガーする場所だからです。

Buildbotをホストしているサーバーに接続し、次のコマンドを使用してワーカーjailでrootシェルを開きます。

sudo jexec buildbot-worker0 csh

Poudriereをパッケージとしてインストールします。

pkg install poudriere

次に、yENTERの順に押してインストールを確認します。

注: Buildbot、Poudriereなどのインストールには、公式のFreeBSDパッケージリポジトリを使用することをお勧めします。 これらのツールパッケージを自分でビルドする場合は、鶏が先か卵が先かという状況から始めます。外部ソフトウェアをインストールしたいが、クリーンにビルドされたパッケージを取得するにはPoudriereをインストールする必要があります。 Poudriereは非常に安定しており、下位互換性のあるツールであるため、製品パッケージから定期的かつ独立して更新することに反対するものはありません。

前提条件のチュートリアルに従った場合、これはすでに当てはまり、このメモに従わなくても続行できます。


これで、最新のPoudriereツールと依存関係が正常にインストールされました。 次のいくつかのステップでは、Poudriereを構成するための準備を行います。

ステップ2—パッケージ署名キーの作成(オプション)

セキュリティを強化するために、ビルドされたパッケージにデジタル署名を設定することをお勧めします。 後で、または別の方法でインストールを保護する場合は、この手順をスキップしてください。 それ以外の場合は、先に進んで、パッケージの署名(秘密鍵を使用)とパッケージの検証(公開部分を使用)に使用する鍵ペアを作成しましょう。

デフォルトでは、パッケージは.txzファイルとしてビルドされます。これは、パッケージの内容を強力に圧縮したtarballです。 圧縮されたファイルのチェックサムは、HTTP / HTTPS(TCPチェックサム)を介してファイルを提供するとともに、破損したデータに対するある程度の保護をすでに提供しています。 パッケージの内容は通常、ファイルとディレクトリに加えて、パッケージ名、バージョン、その他のオプションなどのメタ情報で構成されます。 ファイルにはsetuid-ableプログラムが含まれている場合もあり(sudoパッケージに見られるように-sudo はFreeBSDに組み込まれていませんが)、インストール時のスクリプトは次のように実行されます。 rootユーザー。 したがって、未確認のソースからインストールすると、セキュリティ上のリスクが発生します。

HTTPS経由でパッケージを提供することにより、誰かがディスク上のパッケージを改ざんしたかどうかを検出できません。 パッケージの整合性と信頼性は、RSA秘密鍵を使用してパッケージリポジトリに署名するようにPoudriereを構成することで追加できます。 これにより、署名されたダイジェストと対応する公開鍵がパッケージリポジトリのdigests.txzファイルに保存されます。 必要な鍵のペア(RSA秘密鍵と公開鍵)は、秘密鍵を紛失したり侵害したりしない限り、長期間変更しないでおくことができます。

このステップでは、ビルドが実行されるキーペア(ワーカーjail)を作成し、後でパッケージクライアントで使用するためにパブリックパーツをダウンロードします(後のステップで説明します)。

まだワーカージェイルrootシェルにいることを確認してください。

新しいRSA秘密鍵を作成します。

openssl genrsa -out /usr/local/etc/poudriere.key 4096

秘密鍵ファイルには、Poudriereを実行するユーザーであるrootのみがアクセスできる必要があります。 アクセス許可を保護します。

chmod 0600 /usr/local/etc/poudriere.key

後で、パッケージの署名を検証するために、クライアントで利用可能な公開鍵部分が必要になります。 ここで公開鍵を抽出しましょう:

openssl rsa -in /usr/local/etc/poudriere.key -pubout -out /tmp/poudriere.pub

最後に、自分のコンピューターから公開鍵ファイルをダウンロードします。

scp your-server:/usr/jails/buildbot-worker0/tmp/poudriere.pub /tmp/poudriere.pub

これで、パッケージ署名用のキーペアのオプションの作成は完了です。 後でPoudriereを使用して実際の署名を構成し、クライアントでダウンロードした公開鍵ファイルを使用して検証します。

別のオプションの手順は次のとおりです。ZFSファイルシステムを使用する場合、Poudriereはそれを利用してビルドを高速化できます。 それ以外の場合は、ステップ4 にスキップして、Poudriereを構成し、最初のビルドを実行する準備をすることができます。

ステップ3— ZFSのセットアップ(オプション)

このステップは、ZFSファイルシステム上でFreeBSDシステムを実行している場合にのみ適用されます。 たとえば、DigitalOcean Dropletを使用している場合、イメージには 11.2 x64 zfs (FreeBSD 11.2 の場合)というラベルが付けられます。 このステップでは、Poudriereがjailの作成と管理を高速化するために使用できるファイルシステムを作成し、ビルドを高速化する可能性があります。

プールを一覧表示することで、ZFSを使用しているかどうかを確認できます。 刑務所の中ではなく、サーバーのシェル上にいることを確認してください。

exit

次のコマンドを実行して、zpoolを一覧表示します。

sudo zpool list

利用可能なプールがある場合は、それに関する情報が出力されます。

OutputNAME    SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
zroot   148G  94.4G  54.1G        -         -    66%    63%  1.00x  ONLINE  -

それ以外の場合、ZFSサポートが利用できない場合、ツールはno pools availableまたはfailed to initialize ZFS libraryを出力します。 これは、どのシステムもZFSを使用していないことを意味します。 この場合、次のステップにスキップしてください。 UFSファイルシステムなど、別のディスクまたはストレージタイプを使用することにした場合は、次の手順に進むこともできます。

ZFSを使用する場合は、ビルド関連のデータを格納する印刷されたプール名を覚えておいてください。 数ギガバイトのストレージを計画する必要があります。

ZFSは、ビルドジェイル、ポートツリー、ログ、パッケージ、その他のデータなど、Poudriereのさまざまなデータセットを分離するのに役立ちます。 これらは個別に保存されるため、空き領域やトレースを残さないようにして、すばやく削除できます。

PoudriereがZFSを利用するには、次の3つのことを行う必要があります。親ZFSデータセットの作成、ZFSデータセットの作成と削除の許可(Buildbotワーカーの刑務所またはその他の刑務所ではデフォルトでは実行できません)、および編集それに応じてPoudriereの構成。

前提条件のチュートリアルでは、/etc/jail.buildbot-worker0.confでBuildbotワーカーjailを構成しました。 好みのテキストエディタでこのファイルを開き、次の強調表示された行を追加して親データセットを委任し、jailが親の下のZFSデータセットを管理できるようにします。 zrootを目的のプール名に置き換えることを忘れないでください。

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;

    exec.poststart = "/sbin/zfs jail buildbot-worker0 zroot/pdr/w0";
}

この記事では、ビルド関連のデータをZFSプールzrootに格納します。別の名前のプールを選択した場合は、このZFS関連の構成をここと記事の残りの部分全体に適合させてください。

このコンテンツを追加したら、保存してエディターを終了します。 eeを使用している場合は、CTRL+Cを押し、exitと入力して、ENTERを押します。

構成ファイルに記載されている親ZFSデータセットを作成します。

sudo zfs create zroot/pdr
sudo zfs create zroot/pdr/w0

これは、将来さらにワーカーを追加する可能性があることを意図的に想定しているため、最初のワーカーのサブデータセットを作成します。 古いバージョンのFreeBSD(12.0より前)には88文字のマウント名制限があったため、データセット名は意図的に短くなっています。

刑務所が親データセットを制御し、子を管理するには、データセットに次のフラグを付ける必要があります。

sudo zfs set jailed=on zroot/pdr/w0

前提条件が満たされると、jailは新しい構成で正しく開始されます。

sudo service jail restart buildbot-worker0

これらの手順により、必要なファイルシステム(ZFSデータセット)が正常に作成され、jailが親データセットを管理できるようになりました。 次のステップでは、Poudriereを構成します。これには、ビルド関連のデータを格納するために使用する、選択したzpoolとデータセットを指定することが含まれます。

ステップ4— Poudriere、Build Jail、およびPortsTreeの構成

この時点までに、Poudriereをインストールし、オプションでパッケージ署名とZFSの要件をカバーしました。 Poudriereを「jailed」方式で実行できるようにするには、つまり、Buildbotワーカーjail内から正しく機能させるには、jailに特定の権限を付与する必要があります。 たとえば、ZFSを使用している場合、jailによる使用と管理のために親データセットをすでに委任しています。

最初にループバックIPとすべてのアクセス許可を構成し、次に変更に続いてそれぞれの意味をステップスルーしてみましょう。

Poudriereは、ビルドごとに2つのビルドジェイルを開始したいと考えています。1つはループバックのみのネットワークを使用し、もう1つはインターネットアクセスを使用します。 インターネットに到達することになっているビルドステージのみが後者を使用します。 たとえば、fetchはソースtarballをダウンロードできますが、buildフェーズではインターネットアクセスが許可されていません。 ワーカー刑務所の既存の構成には、インターネットアクセスを許可するip4.addr = "lo1|10.0.0.3/24"があります。 Poudriereが新しく開始されたビルドジェイルにループバックアドレスを割り当てることができるようにするには、IPをその親(ワーカージェイル)にも渡す必要があります。 これを機能させるには、前提条件のチュートリアルから最新バージョンのファイアウォール構成ファイル/usr/local/etc/ipfw.rulesを適用していることを確認してください。これにより、ループバックインターフェイスlo0がNATを介して発信接続を開くことがブロックされます。

強調表示された行をワーカーjail構成に追加します。

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";
    ip4.addr += "lo0|127.0.0.3";
    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;

    # If you followed the ZFS setup step, you have this line
    # already (keep it). For non-ZFS setup, this line must be absent.
    exec.poststart = "/sbin/zfs jail buildbot-worker0 zroot/pdr/w0";

    allow.chflags;
    allow.mount;
    allow.mount.devfs;
    allow.mount.nullfs;
    allow.mount.procfs;
    allow.mount.tmpfs;
    allow.mount.zfs; # only needed if you use ZFS
    allow.raw_sockets; # optional
    allow.socket_af; # optional
    allow.sysvipc; # optional
    children.max=16;
    enforce_statfs=1;
}

ここに以下を追加しました( jail(8)のマンページも参照してください)。

  • ip4.addr += "lo0|127.0.0.3"は、別のIPv4アドレスをjailに追加します。 buildフェーズ中など、インターネットやネットワーク内の他のマシンと通信することを想定していないjailを構築するために、このループバックアドレスを割り当てるために、後でPoudriereのLOIP4変数を構成します。 ビルド中にインターネットアクセスを必要とするビルドがある場合、Poudriereは回避策として変数ALLOW_NETWORKING_PACKAGESをサポートしています。 ただし、Poudriereがインターネットアクセスを許可するfetchフェーズでは、ベストプラクティスに従い、ダウンロードやその他のインターネット向けタスクを早期に実行することをお勧めします。
  • allow.chflagsを使用すると、Poudriereはビルドジェイルで/bin/shなどの特定のシステムファイルを不変にすることができます。
  • allow.mountおよびその他のallow.mount.*オプションを使用すると、Poudriereは特定の必要なファイルシステムをビルドジェイルにマウントできます。
  • rawソケットの使用を許可するallow.raw_socketsと、任意のソケットアドレスファミリの使用を許可するallow.socket_afは、どちらもインターネット対応のビルドジェイルに適用されます。 これは、問題をデバッグするためにビルドjailに入るときのように、pingなどのツールをインタラクティブモードで実行できるようにするために役立ちます。
  • allow.sysvipcは非推奨になり、3つの個別の設定sysvmsg / sysvsem / sysvshmが使用されなくなり、刑務所は自分の共有メモリオブジェクトのみを表示するように制限されます(「SYSV ” IPCプリミティブ)。 ただし、Poudriereはallow.sysvipcのみを渡して刑務所を構築できます。これは、3つの別々のパラメーターに関連するsysctl情報を読み取ることができないためです(FreeBSD 11.2以降)。 この非推奨の構成では、jailはjailの外部のプロセスの共有メモリを読み取ることができます。 これは、PostgreSQLなどのIPC機能に依存する特定のソフトウェアにのみ関連するため、セキュリティに影響を与える可能性はほとんどありません。 ビルド中に必要なポートに依存しない限り、この構成を削除できます。
  • children.max=16は、ワーカー刑務所の下に16のサブ刑務所を許可します。 CPUが多く、Poudriereが許可されているよりも多くのビルドジェイルを作成しようとする場合は、後でこの数を増やすことができます。 各Poudriereビルドは、「ジョブ」ごとに参照jailと2つのビルドjailを作成しようとします。デフォルトでは、CPUの数(sysctl -n hw.ncpuによって出力される)をジョブ数として使用します。
  • 特定のファイルシステムをマウントするには、enforce_statfs=1allow.mountと一緒に必要です。

構成ファイルを保存して終了します。

構成をすぐに有効にするために、jailを再起動します。

sudo service jail restart buildbot-worker0

Poudriereがマウントを実行できるように、それぞれのカーネルモジュールをロードする必要があります。 次のコマンドを実行して、起動時および即時にモジュールをロードします。

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

サンプルファイル/usr/local/etc/poudriere.conf.sample/usr/local/etc/poudriere.confにコピーしたPoudriereパッケージを既にインストールしました。 次に、構成ファイルを編集します。 考えられるすべての構成変数はサンプルにすでに存在するため、ファイル内のそれぞれの行のコメントを解除または調整して、変数を特定の値に設定します。

次のコマンドについては、ワーカーjailのrootシェルにいることを確認してください。

sudo jexec buildbot-worker0 csh

次のコマンドでファイルを開きます。

ee /usr/local/etc/poudriere.conf

ZFSを使用することにした場合は、目的のzpoolと親データセットを入力してください。

/usr/local/etc/poudriere.conf(スニペット)

. . .
# Poudriere can optionally use ZFS for its ports/jail storage. For
# ZFS define ZPOOL, otherwise set NO_ZFS=yes
#
#### ZFS
# The pool where poudriere will create all the filesystems it needs
# poudriere will use ${ZPOOL}/${ZROOTFS} as its root
#
# You need at least 7GB of free space in this pool to have a working
# poudriere.
#
ZPOOL=zroot

### NO ZFS
# To not use ZFS, define NO_ZFS=yes
#NO_ZFS=yes

# root of the poudriere zfs filesystem, by default /poudriere
ZROOTFS=/pdr/w0
. . .

それ以外の場合、ZFSに反対することにした場合は、ZFSサポートを無効にしてください。

/usr/local/etc/poudriere.conf(スニペット)

. . .
# Poudriere can optionally use ZFS for its ports/jail storage. For
# ZFS define ZPOOL, otherwise set NO_ZFS=yes
#
#### ZFS
# The pool where poudriere will create all the filesystems it needs
# poudriere will use ${ZPOOL}/${ZROOTFS} as its root
#
# You need at least 7GB of free space in this pool to have a working
# poudriere.
#
#ZPOOL=zroot

### NO ZFS
# To not use ZFS, define NO_ZFS=yes
NO_ZFS=yes

# root of the poudriere zfs filesystem, by default /poudriere
# ZROOTFS=/poudriere
. . .

後で、PoudriereにFreeBSDベースシステムをダウンロードして、最初のビルドjailをブートストラップするように指示します。 これには、ダウンロードホストを指定する必要があり、次の強調表示された行を追加します。

/usr/local/etc/poudriere.conf(スニペット)

. . .
# the host where to download sets for the jails setup
# You can specify here a host or an IP
# replace _PROTO_ by http or ftp
# replace _CHANGE_THIS_ by the hostname of the mirrors where you want to fetch
# by default: ftp://ftp.freebsd.org
#
# Also note that every protocols supported by fetch(1) are supported here, even
# file:///
# Suggested: https://download.FreeBSD.org
FREEBSD_HOST=https://download.FreeBSD.org

Poudriereはjailで実行されるため、jail /usr/jails/buildbot-worker0のフルパスは各マウントパスの一部であるため、12.0より前のFreeBSDバージョンの88文字のマウント名制限は特に有害です。 制限を超えるとビルドが致命的に破壊されるため、パスの長さを短くするように注意してください。 通常のディレクトリ/usr/local/poudriereの代わりに、次のように/pdrを使用できます。

/usr/local/etc/poudriere.conf(スニペット)

. . .
# The directory where poudriere will store jails and ports
BASEFS=/pdr

次に、そのディレクトリを作成します。

mkdir /pdr

poudriere.confのエディターに再度切り替えます。

ee /usr/local/etc/poudriere.conf

Poudriereは、ビルドの実行中に distファイル(各ポートのソースコードtarball)の中央ディレクトリをマウントして、すべてのビルダーが同じキャッシュを共有するようにします。 デフォルトのディレクトリは次のとおりです。

/usr/local/etc/poudriere.conf(スニペット)

. . .
# If set the given directory will be used for the distfiles
# This allows to share the distfiles between jails and ports tree
# If this is "no", poudriere must be supplied a ports tree that already has
# the required distfiles.
DISTFILES_CACHE=/usr/ports/distfiles

次に、そのディレクトリを作成します。

mkdir -p /usr/ports/distfiles

手順2に従って、パッケージリポジトリの署名キーを作成した場合は、エディタをもう一度入力して指定してください。

ee /usr/local/etc/poudriere.conf

/usr/local/etc/poudriere.conf(スニペット)

. . .
# Path to the RSA key to sign the PKG repo with. See pkg-repo(8)
PKG_REPO_SIGNING_KEY=/usr/local/etc/poudriere.key

次回のためにC/C ++コンパイラとリンカの出力をキャッシュすると、ビルドははるかに高速に実行されます。 ポートツリーは、ツール ccache を利用して、これを直接サポートします。 少なくとも5GBのスペース(デフォルトのキャッシュサイズ)を確保できる場合は、それを有効にして、それぞれのキャッシュディレクトリを作成してください。

/usr/local/etc/poudriere.conf(スニペット)

. . .
# ccache support. Supply the path to your ccache cache directory.
# It will be mounted into the jail and be shared among all jails.
# It is recommended that extra ccache configuration be done with
# ccache -o rather than from the environment.
CCACHE_DIR=/var/cache/ccache
mkdir /var/cache/ccache

Linuxソフトウェアのビルドと実行は一般的ではないため、必要になるまで無効にします。

ee /usr/local/etc/poudriere.conf

/usr/local/etc/poudriere.conf(スニペット)

. . .
# Disable linux support
NOLINUX=yes

刑務所にはループバックアドレスが割り当てられる必要があります。そうしないと、Poudriereが警告を発します。 ジェイルのIPは、ループバックのみのネットワークインターフェイス(lo1)上にあるため、継承できます。 このために、構成ファイルの最後に次の行を追加してください。

/usr/local/etc/poudriere.conf(スニペット)

LOIP4=127.0.0.3

構成ファイルを保存して終了します。

ビルドを機能させるには、さらに2つのリソースが必要です。ビルドjailテンプレートとして使用するFreeBSDベースシステムと、最新のポートツリーです。 対象とするFreeBSDバージョンを選択してください。 このチュートリアルでは、Poudriereにamd64アーキテクチャ用のFreeBSD11.2をダウンロードするように指示します。 刑務所には好きな名前を付けることができますが、112amd64のような一貫した名前付けスキームをお勧めします。 また、四半期ごとに安定したポートツリーブランチ(ここでは2019Q2を使用)と、時々更新後にビルドが壊れる可能性のある最先端の「ヘッド」ブランチのどちらかを選択することにも注意してください。 サーバー上のバージョンよりも新しいFreeBSDバージョンは、ビルドjailでは使用できません。

ビルドジェイルをダウンロードして作成します。

poudriere jail -c -j 112amd64 -v 11.2-RELEASE -a amd64

最後に、portsツリーをダウンロードしましょう。 デフォルトのダウンロード方法はportsnapで、履歴情報なしでツリーの圧縮スナップショットを使用します。 アップストリームの変更をマージしたり、貢献したりするには、SubversionまたはGitのいずれかを使用することをお勧めします。 これは、バージョン管理システムでカスタムのセルフホストツリーを使用する場合にも重要です。 次のコマンドで、現在の年と四半期を入力してください。

アップストリームの公式ポートツリーから始めたい場合は、次のようにします。

poudriere ports -c -p 2019Q2 -m svn+https -B branches/2019Q2

メソッドsvn+httpsは、FreeBSD Subversionホストから同期します(ここでオンラインで表示可能)。 別のソースを使用する場合は、次の注をお読みください。それ以外の場合はスキップしてください。

注:別の方法として、メソッドgitは、デフォルトでGitHubのmirrorからツリーを複製します。

「head」ブランチを使用するには、最後のパラメーターを-B head(Subversionの場合)または-B master(Gitの場合)に置き換えます。

独自のGitリポジトリを使用する場合は、リポジトリのURLとブランチ名を明示的に指定する必要があります。 ツリーにcustomtreeという名前を付け、ブランチcustomを使用するとします。

poudriere ports -c -p customtree -m git -B custom -U https://github.com/AndiDog/freebsd-ports.git

サンプルURLは、GitHub上のfreebsd-portsのフォークを指していますが、CIサーバーがアクセスできる任意のGitまたはその他のサポートされているタイプのリポジトリである可能性があります。


使用可能なツリーは、poudriere ports -lでリストできます。これにより、次のようなリストが出力されます。

OutputPORTSTREE METHOD    TIMESTAMP           PATH
2019Q2    svn+https 2019-04-20 19:23:19 /pdr/ports/2019Q2

これで、Poudriereの構成とリソースの設定が完了しました。 最初のビルドをトリガーするために必要なデータを使用してPoudriereを構成し、jailがサブjailを作成できるようにしました。 次に、最初のビルドを手動で実行して、セットアップが機能していることを確認します。

ステップ5—手動テストビルドの実行

コマンドpoudriere bulkを使用して、1つ以上のパッケージとそのすべての依存関係を構築できます。 パッケージの最初のビルド後、Poudriereは、再構築が必要かどうかを自動的に検出するか、既存のパッケージファイルをそのままにします。 bulkサブコマンドはパッケージのみをビルドしますが、poudriere testportを使用してビルドを実行すると、ポートのMakefileで指定された「テスト」の定義を使用して指定されたポートもテストされます。 この記事の範囲では、クライアントにインストールするためのパッケージを提供することにのみ関心があるため、バルクビルドを使用しています。

Poudriereをインストールしたワーカー刑務所のルートシェルにいることを確認してください。 後で、これはBuildbotワーカープロセスがビルドを自動的に実行する場所でもあります。

ビルドを実行し、プレースホルダーに前に選択したビルドjail名とportsツリー名を入力します。

poudriere bulk -j 112amd64 -p 2019Q2 ports-mgmt/pkg

これにより、ポートports-mgmt/pkgが構築されます。 公式ツリーのポートは<category>/<name>階層に格納され、それらのパス(パッケージオリジンと呼ばれる)を使用して、どのパッケージをビルドする必要があるかをPoudriereに通知します。 最初に、パッケージマネージャー pkg のみをビルドすることを選択しました。これは、サードパーティの依存関係がないため、構成をすばやくすばやく確認できます。 すべてが正常に実行されると、次のような出力が表示されます。

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

この出力は、ビルド後にパッケージがどこに移動するか、および再構築が必要ない場合に既存のパッケージがどこから取得されるかを示します(ここでは/pdr/data/packages/112amd64-2019Q2)。 また、出力には、Poudriereの実行中に実行されているビルドの概要が表示されます(インタラクティブシェルでCTRL+Tを押すと、進行状況が印刷されます)。 最終的な要約では、1つのパッケージが作成されたことがわかります。 ログディレクトリ(/pdr/data/logs/bulk/112amd64-2019Q2/*)で詳細なビルド出力を表示できます。

この出力は、ビルドが成功したことを確認します。 Poudriereが少なくとも1つのパッケージを正常にビルドした場合、Poudriereはそれをパッケージリポジトリに自動的にコミットします。 つまり、他のパッケージのビルドに失敗した場合でも、パッケージはすべてのビルドが完了した後にのみ使用可能になります。 これで、Buildbotワーカージェイル内の/pdr/data/packages/112amd64-2019Q2に作業パッケージリポジトリができました。

動作中のPoudriereビルドを返すために必要なすべての構成を完了し、手動ビルドで正常に検証しました。 Buildbotでバルクビルドを自動化すると、チュートリアルの後半でこれと同じ出力が表示されます。 さらに、詳細なログを表示するためのリンクは、Webインターフェイスからアクセスできる必要があります。 これを実現し、パッケージリポジトリをクライアントに提供するために、次にWebサーバーをセットアップします。

ステップ6—PoudriereWebインターフェイスとパッケージリポジトリを提供するようにNginxを構成する

Poudriereは、Webサーバーを使用してホストするいくつかの出力アーティファクトを提供します。

  • パッケージリポジトリはクライアントが利用できるようになっているため、クライアントは、HTTPSまたはHTTPをトランスポートとして使用して、通常のpkg updateおよびpkg installコマンドでアクセスできます。
  • 詳細なビルドログは、開発者が問題のあるビルドをデバッグしたり、ビルド出力を調査したりするのに役立ちます。 これらはパッケージごとおよびビルドごとに保存されます。最後のステップのPoudriere出力では、ログがビルドごとに1つのディレクトリに保存され、日付と時刻のラベルが付けられていることがわかりました。
  • Poudriereの組み込みWebインターフェイスは、ビルドごとに小さな単一のHTMLページであり、WebSocketを使用してページに表示されるステータスを定期的に更新します。 これは、ビルドの距離、他のパッケージビルドが失敗する原因となった依存関係の概要を把握するのに役立ちます。最後に、コマンドライン出力の代わりに使用します。コマンドライン出力では、特に印刷しない限り、最後に要約のみが表示されます。現在のビルドの進行状況。

静的ファイルのみを提供する必要があるため、Nginxの構成変更は短時間です。 それらを外部に提供するので、次に、サーバー上の既存のNginxインスタンスを、刑務所の外で、ワーカー刑務所内のパスから上記のファイルを提供するように構成します。

サーバーで作業するので、jailシェルを終了してください。

exit

Nginx構成/usr/local/etc/nginx/nginx.confでエディターを開きます。

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

server {ブロック内に次の場所を追加します。

/usr/local/etc/nginx/nginx.conf

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

        # poudriere logs
        location ~ ^/logs(/(.*))?$ {
            include mime.types;
            types {
                text/plain log;
            }

            alias /usr/jails/buildbot-worker0/pdr/data/logs/bulk$1;
            index index.html index.htm;
            autoindex on;
        }

        # poudriere packages
        location ~ ^/packages(/(.*))?$ {
            alias /usr/jails/buildbot-worker0/pdr/data/packages$1;
            index no-index-file-but-required-directive-to-list-dir-contents;
            autoindex on;
        }

        location /buildbot/ {
            proxy_pass http://10.0.0.2:8010/;
        }

        . . .
    }
}
. . .

Nginx構成ファイルを保存して閉じます。 次に、Nginxサービスをリロードします。

sudo service nginx reload

最初の手動ビルドで作成されたアーティファクトを確認してみましょう。 ローカルマシンでお好みのWebブラウザを開いて、リソースにアクセスします。

パッケージリポジトリhttps://your-domain/packages/(またはhttp://your-server-ip/)の下にあります。 ルートディレクトリにメタ情報があります。例: 112amd64-2019Q2、およびサブディレクトリAll内のすべてのビルド済みパッケージ:

詳細なビルドログおよびPoudriereの組み込みWebインターフェイスhttps://your-domain/logs/の下にあります。 ディレクトリ階層をクリックして、以前の手動ビルドのデータにアクセスします。 この例では、https://your-domain/logs/112amd64-2019Q2/latest/build.htmlのようなURLにたどり着く可能性があります。

サーバーのドメイン名を設定しなかった場合は、これらの例でサーバーのパブリックIPアドレスを入力する必要があります。 http://your-server-ip/logs/

これで、ビルドを機能させ、出力(パッケージとログ)を可視化するためのすべての手動セットアップが完了します。 今後は、ビルドを自動化して継続的インテグレーションを実現します。

ステップ7—パッケージ用のBuildbotBuilderのセットアップ

このステップの目標は、既存のBuildbotサンプル構成に追加することにより、すでに手動で行っているのと同じ方法でPoudriereを実行することにより、バルクパッケージビルドを自動化することです。 このステップの終わりまでに、Buildbotは、portsツリーの選択されたブランチが変更されるたびにパッケージビルドをトリガーします。 このチュートリアルの例では、それは四半期ごとのブランチ2019Q2になります。

必要な変更はすべてBuildbotマスター構成で行われるため、マスターjailでrootシェルを開いてください。

sudo jexec buildbot-master csh

まず、ビルドを実行するために実行されるコマンドとアクションを記述するビルダーを定義する必要があります。 既存の構成/var/buildbot-master/master.cfgには、セクション####### BUILDERSがあります。エディターを開き、[X146X] で始まる次の見出しまで、セクション全体を置換します。次の構成で:

ee /var/buildbot-master/master.cfg

/var/buildbot-master/master.cfg(スニペット)

. . .
####### BUILDERS

c['builders'] = []

PORTS_TO_BUILD = {
    'security/sudo',
    'shells/bash',
    'sysutils/tmux',
}


# Custom classes
class PoudriereLogLineObserver(util.LogLineObserver):
    _logsRe = re.compile(r'Logs: /pdr/data/logs/bulk(/[-_/0-9A-Za-z]+)$')

    def __init__(self):
        super().__init__()
        self._hadUrls = False

    def outLineReceived(self, line):
        if not self._hadUrls:
            m = self._logsRe.search(line.strip())
            if m:
                poudriereUiUrl = f'''{re.sub('/buildbot/$', '', c['buildbotURL'])}/logs{m.group(1)}'''
                self.step.addURL('Poudriere build', poudriereUiUrl)
                self.step.addURL('Poudriere logs', poudriereUiUrl + '/logs/')
                self._hadUrls = True


class PoudriereCompileStep(steps.Compile):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.addLogObserver('stdio', PoudriereLogLineObserver())


# Poudriere bulk build
bulkBuildFactory = util.BuildFactory()
bulkBuildFactory.addSteps([
    steps.ShellCommand(
        name='update ports tree',
        command=['sudo', 'poudriere', 'ports', '-u', '-p', '2019Q2', '-v'],
        haltOnFailure=True,
    ),
    PoudriereCompileStep(
        name='make bulk',
        command=['sudo', 'poudriere', 'bulk', '-j', '112amd64', '-p', '2019Q2'] + list(sorted(PORTS_TO_BUILD)),
        haltOnFailure=True,
    ),
])
c['builders'].append(util.BuilderConfig(name='bulk-112amd64-2019Q2',
                                        workernames=['worker0'],
                                        factory=bulkBuildFactory))
. . .

これがBuildbotの拡張性をどのように利用しているかに注意してください。カスタムクラスは、Poudriereのログ出力からの情報を監視および解析するために使用されます。 つまり、PoudriereLogLineObserverが「ログオブザーバー」として追加されます。 ビルド中に新しいログ行が出力されるたびに呼び出されます。 クラスはログでログディレクトリを検索し、それをハイパーリンクに変換します。 これらのリンクはビルドステップと一緒に表示され、ユーザーはPoudriereのWebインターフェイスとログに直接移動します。

最初のビルドステップ「ポートツリーの更新」では、Poudriereの組み込みの更新コマンド(ports -u)を使用して、最新バージョンのポートツリーをプルします。 これにより、以前に構成されたメソッド(SVN / Gitなど)が自動的に使用されます。 このようにして、パッケージが常に最新のコミットされたツリーに対してビルドされていることを確認できます。これは、ソフトウェアのバージョンとパッチを維持する独自のバージョン管理されたリポジトリがある場合に特に役立ちます。

上部のリストPORTS_TO_BUILDは、構築するポートを指定します。 これは、ブロックの下部に指定されているビルドファクトリの手順で使用されます。 ビルドファクトリは、ビルドをインスタンス化するために使用されるテンプレートです。 Buildbotは、トリガーされるたびに一意のビルドを作成し、ビルドは、その時点でビルドファクトリに対して定義されたステップのコピーを使用します。 この場合、正確に2つのステップを構成しました。

  • ポートツリーを更新します。 この例では四半期ごとのブランチ2019Q2を使用しているため、変更を頻繁に受け取ることはありません(通常、セキュリティとビルドの修正のみ)。
  • 同じツリーを使用して一括ビルドを実行します。

追加したコードブロックを機能させるには、ファイルの先頭に必要なインポートを追加してください。

/var/buildbot-master/master.cfg(スニペット)

# -*- python -*-
# ex: set filetype=python:

import re

from buildbot.plugins import *

Pythonのreライブラリは、正規表現を実装しています。これは、文字列の一部を検索または置換する機能です。PoudriereLogLineObserverクラスは、これを使用して行[を検索します。 X175X]ログディレクトリについて言及しています。

ビルドコマンドは、sudoを使用して特定のコマンドを実行します。 これが必要なのは、ビルドを実行するときにPoudriereがスーパーユーザー権限を必要とし、ビルドjailを作成、管理、および破棄するためです。また、Poudriereが管理するポートツリーは、rootユーザーを所有者として作成されます。 前のチュートリアルでは、Buildbotワーカープロセスを実行するユーザーをsysrc buildbot_worker_uid=buildbot-workerで構成しました。 したがって、buildbot-workerユーザーがrootとして必要なコマンドを正確に実行できるようにしますが、他のコマンドは実行できません(セキュリティ上の理由から)。 sudoプログラムをインストールし、それに応じて構成してみましょう。

これは、マスターではなく、労働者の刑務所で行う必要があります。 マスター刑務所シェルを終了し、ワーカー刑務所に入ります。

exit
sudo jexec buildbot-worker0 csh

sudoパッケージをインストールします。

pkg install sudo

yおよびENTERでインストールを確認します。

FreeBSDでは、 sudo パッケージは、デフォルトで/usr/local/etc/sudoers.d/から設定ファイルを読み取ります。 エディターを開いて、新しい構成ファイルを作成します。

env EDITOR=ee visudo /usr/local/etc/sudoers.d/buildbot-worker

visudoの使用は意図的なものです。これは、構文エラーについて警告し、不適切な構成をコミットする代わりにそれらを修正できるようにするためです。

buildbot-workerユーザーがパスワードを必要とせずにrootとして実行できるコマンドを指定します。

/usr/local/etc/sudoers.d/buildbot-worker

buildbot-worker ALL=(ALL) NOPASSWD: /usr/local/bin/poudriere bulk *
buildbot-worker ALL=(ALL) NOPASSWD: /usr/local/bin/poudriere ports -u *

ファイルを保存し、マスターjailに戻って、Buildbotマスターのさらに必要な構成を行います。

exit
sudo jexec buildbot-master csh

バルクビルドを機能させるための要件を満たしました。 ただし、前述のように、実行するには、各ビルドをトリガーする必要があります。 Buildbotは、ビルドがトリガーされるタイミングと、どのブランチが変更されたかなどの追加情報を定義するオブジェクトにスケジューラーという用語を使用します。 構成ファイルから既存のセクションSCHEDULERS削除し、次のコンテンツ BUILDERSセクションの後に配置して、コードがすべてを使用できるようにしてください既存のビルダー名:

ee /var/buildbot-master/master.cfg

/var/buildbot-master/master.cfg(スニペット)

. . .
####### SCHEDULERS

c['schedulers'] = []

# Forceful scheduler allowed for all builders
c['schedulers'].append(schedulers.ForceScheduler(
    name='force',
    builderNames=[builder.name for builder in c['builders']]))

# Watch ports tree for changes on given branch
c['schedulers'].append(schedulers.SingleBranchScheduler(
    name='sched-bulk-112amd64-2019Q2',
    change_filter=util.ChangeFilter(project='freebsd-ports', branch='branches/2019Q2'),
    builderNames=['bulk-112amd64-2019Q2']))
. . .

これにより、サンプル構成が置き換えられ、すべてのビルダーにforceボタンが表示されます。 そして最も重要なことは、指定されたproject / branchに関連するすべての変更を監視し、変更ごとにビルドをトリガーするスケジューラーを作成することです。 ただし、そのような変更イベントは発生しません。最初に変更ソースを作成する必要があります。 通常、これらはSVNやGitなどのバージョン管理システムであり、ブランチの変更を検出できます。 Buildbotは最も人気のあるものをサポートしているため、その機能を使用して、選択したアップストリームポートツリーリポジトリをソースとして追加できます。 セクションCHANGESOURCESを次の構成に完全に置き換えます。

/var/buildbot-master/master.cfg(スニペット)

. . .
####### CHANGESOURCES

c['change_source'] = []

c['change_source'].append(changes.SVNPoller(
    'svn://svn.freebsd.org/ports/',
    project='freebsd-ports',
    split_file=util.svn.split_file_branches,
    svnbin='svnlite',
    pollInterval=4 * 3600))

# Example for Git:
# c['change_source'].append(changes.GitPoller(
#     repourl='https://github.com/AndiDog/freebsd-ports.git',
#     project='freebsd-ports',
#     branches=['custom'],
#     pollInterval=4 * 3600))
. . .

これにより、Buildbotマスターで4時間ごとにSVNリポジトリがポーリングされ、新しい(以前は表示されなかった)変更が一致するスケジューラーに転送され、ビルドがトリガーされて、最終的に単一のBuildbotワーカーで実行されるようにディスパッチされます。 ポートツリーは非常に大きく、最初に実行すると、これらのポーラーは完全な履歴(Gitの場合、指定されたブランチのみ)をダウンロードします。これには数分かかり、かなりのスペース(数ギガバイト)が必要になる場合があります。

Buildbotを再起動して、新しい構成ファイルを適用します。

service buildbot restart

この例では、svn://svn.freebsd.org/ports/のアップストリームポートコレクションを使用しており、ブランチ2019Q2が変更されるたびにビルドがスケジュールされます。 前に述べたように、四半期ごとのブランチはほとんど安定しており、更新を頻繁に受信しません。 ビルドが最初にトリガーされる前に、このような変更が行われるのを待ちたくない場合があるので、手動で1回実行してみましょう。

Buildbot Webインターフェイス(https://your-domain/buildbot/)を開き、ビルド>ビルダー>バルク-112amd64-2019Q2に移動します。 ビルドはまだ表示されません。

右上のforceボタンをクリックし、 StartBuildをクリックします。 これにより、デフォルト設定を使用してビルドがトリガーされます。 reason、branch、およびその他の値はオーバーライドされません。 「portsツリーの更新」ステップの実行には1分かかる場合があり、最終的にはPoudriereビルドも正常に実行されるはずです。 Webインターフェースは、ビルドが成功したことを示します。

リンクの1つ(PoudriereビルドおよびPoudriereログ)をクリックすると、それぞれこの特定のビルドのPoudriere Webインターフェイスとビルドログに移動します(手順6を参照)。 make Bulk の横にある矢印をクリックして展開し、 stdio>すべての…行を表示して、poudriere bulk ...コマンドの完全な出力を表示します。

最初のビルドが完了すると、ステップ6のNginxで構成されているように、パッケージが利用可能になります。 ブラウザでhttps://your-domain/packages/(またはhttp://your-server-ip/packages/)に移動し、Poudriereによって作成されたパッケージリポジトリをクリックします。 リポジトリの1つに入り、All/サブディレクトリに移動すると、実際のパッケージファイル(*.txz)を見つけることができます。

パッケージがHTTPS(または、必要に応じてHTTP)で利用可能になり、ポートツリーの変更に基づいて自動的に構築されるようになったため、これらのパッケージを使用するように1つ以上のホストを構成できます。

ステップ8—パッケージクライアントの構成

このステップでは、2番目のFreeBSDサーバーが必要であり、CIサーバー上に構築されたパッケージをフェッチしてインストールできるようにセットアップします。 この2番目のサーバーをパッケージクライアントと呼びます。

クライアントホストにSSHで接続します。 このセクションの残りのほとんどの手順は、クライアントで実行されます。

ssh package-client

カスタムパッケージリポジトリ構成用のディレクトリを作成します。

sudo mkdir -p /usr/local/etc/pkg/repos

root ユーザーとして、エディターを開いてファイル/usr/local/etc/pkg/repos/ci.confを作成し、パッケージを取得する方法と場所を指定します。

sudo ee /usr/local/etc/pkg/repos/ci.conf

パッケージ署名を選択した場合は、次のコンテンツを使用してください。

/usr/local/etc/pkg/repos/ci.conf

ci: {
    url: "https://your-domain/packages/112amd64-2019Q2",
    signature_type: "pubkey",
    pubkey: "/usr/local/etc/pkg/repos/ci.pub",
    enabled: yes
}

または、パッケージ署名を使用しないことにした場合は、次のように署名チェックを無効にします。

/usr/local/etc/pkg/repos/ci.conf

ci: {
    url: "https://your-domain/packages/112amd64-2019Q2",
    signature_type: "none",
    enabled: yes
}

注:この注は、ステップ2に従ってパッケージリポジトリ署名キーを作成した場合にのみ適用されます。 それ以外の場合はスキップしてください。

ローカルマシンから、公開鍵をパッケージクライアントにアップロードします。

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

クライアントシェルを再度使用して、キーを所定の位置に移動し、パッケージの信頼性を検証できるようにします。

sudo 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リポジトリーを無効にしてください。

sudo ee /usr/local/etc/pkg/repos/FreeBSD.conf

/usr/local/etc/pkg/repos/FreeBSD.conf

FreeBSD: {
    enabled: no
}

完全に元のパッケージクライアントホストを使用している場合、パッケージはまだインストールされていないため、すぐに独自のパッケージリポジトリの使用を開始できます。 ただし、別のソースから1つのパッケージしかインストールされていない場合は、それらのパッケージをアンインストールし、独自のソースを使用して最初から開始することをお勧めします。 パッケージマネージャーpkg自体はパッケージとしてインストールされます。鶏が先か卵が先かという問題を解決するために、FreeBSDのベースシステムには、パッケージマネージャーをブートストラップできる小さな実行可能ファイル/usr/sbin/pkgが付属しています。 つまり、pkgパッケージをダウンロードして、システムの最初のパッケージとしてインストールします。 その時点から、そのパッケージの実行可能ファイル/usr/local/sbin/pkgは、本格的なパッケージマネージャーとしてあなたをサポートします。

次のコマンドを実行して、pkgをブートストラップします。

sudo pkg bootstrap

pkg bootstrapの出力では、構成ファイルでciと呼ばれる独自のパッケージリポジトリからパッケージが取得されていることがわかります。 パッケージ署名キーを使用している場合、出力にはセキュリティ検証についてのヒントも表示されます。

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

この正常な出力が表示された場合は、次のノートブロックにスキップしてください。 ただし、パッケージマネージャーまたは他のパッケージがすでに別のソースからインストールされている場合は、次のエラーが発生します。

Outputpkg 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を正常に再インストールするまで、開いたままにします。

sudo sh

pkgを含むすべてのパッケージをアンインストールします。

pkg delete --all --force

パッケージマネージャーをブートストラップします。

pkg bootstrap

yENTERの順に押して、パッケージマネージャーをブートストラップすることを確認します。


HTTPS用のLet'sEncrypt証明書を使用してパッケージホストを設定する可能性が高い場合、パッケージホストが信頼されていないが、パッケージをインストールする必要がある鶏が先か卵が先かという問題が発生します [X229X ](信頼できるルート証明書機関を含む)Let's Encrypt CAを信頼し、それによってカスタムビルドパッケージをホストしているサーバーも信頼します。 内部CA(あなたまたはあなたの会社によって自己署名された)を使用した場合にも同じ問題が発生します。 証明書検証エラーは、パッケージマネージャーをブートストラップするときに次のようなエラー出力をもたらします。

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

このエラーが表示された場合は、以下の注の指示に従ってください。 それ以外の場合は、すべて設定されており、この部分をスキップしてメモの後に続行できます。

注– HTTPSの使用と証明書の検証が失敗した場合のみ:

直接的な回避策が1つあります。パッケージ署名キーのセキュリティを信頼するため、pkgをブートストラップし、暗号化されていないHTTPを介してca_root_nssパッケージをインストールします。 プライバシーの懸念、ブロックされたHTTPポートなどのため、これが常にオプションであるとは限らないため、より「ベストプラクティス」の方法を選択する必要があります。 公式のFreeBSDリポジトリもLet'sEncryptによって署名されているため、そこからca_root_nssパッケージを単純にインストールすることはできません。 どのCAであっても、信頼できるHTTPSCAの固定セットを使用してパッケージクライアントを設定することをお勧めします。 次のいくつかの手順でそれを正確に達成できます。 これはLet'sEncryptの場合であると想定しますが、手順は、独自の自己署名CAでも同じように機能します(証明書チェーンが手元にある必要があります)。

Webブラウザーで、https://letsencrypt.org/certificates/にあるLet'sEncryptの証明書リストにアクセスします。 Webサイトがブラウザによって信頼されていることを確認してください。 ルート証明書>アクティブ>ISRGルートX1(自己署名)および中間証明書>アクティブ> Let's Encrypt Authority X3(ISRGルートX1による署名)の下の証明書をPEM形式でダウンロードします。ローカルコンピュータの/tmp/root.pem/tmp/intermediate.pem

ダウンロードが成功したら、ファイルを証明書チェーンに連結します。

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

パッケージクライアントのシェルに戻り、TLS検証に使用されるように、パッケージマネージャー構成/usr/local/etc/pkg.confでこの信頼の鎖を指定する必要があります。 エディターを使用してこれらの行を追加し、ファイルがまだ存在しない場合はファイルを作成します。

sudo ee /usr/local/etc/pkg.conf

/usr/local/etc/pkg.conf(スニペット)

pkg_env: {
    SSL_CA_CERT_FILE: "/usr/local/etc/pkg/repos/letsencrypt-chain.pem",
}

CAチェーンを所定の位置に移動します。

sudo mv /tmp/letsencrypt-chain.pem /usr/local/etc/pkg/repos/.

sudoパッケージが削除されたためにこれまでルートシェルにとどまっていた場合、このコマンドはsudoなしで実行する必要があります。 このメモ内の次のコマンドにも同じことが当てはまります。

この設定を使用すると、ブートストラップをもう一度試すことができ、TLSエラーが発生することはありません。 小さなひねりが1つあります。完全なパッケージマネージャーをブートストラップするFreeBSD組み込み/usr/sbin/pkgは、構成されたpkg_env設定を尊重しないため、この環境変数のそれぞれの環境変数をオーバーライドする必要があります。時間のみ、構成されたものと同じ値を使用します。

sudo env SSL_CA_CERT_FILE=/usr/local/etc/pkg/repos/letsencrypt-chain.pem pkg bootstrap

以前に既存のパッケージを削除したことがある場合は、今すぐ重要なツールを再インストールすることをお勧めします(例: sudo)、およびその他の必要なパッケージ。

pkg install bash sudo

それでも問題が解決しない場合は、ルートシェルからドロップアウトします。

exit

すべてが機能するかどうかをテストするには、Buildbotマスター構成(変数PORTS_TO_BUILD)で指定されたリストからパッケージをインストールします。 たとえば、Bashシェルとsudo:

sudo pkg install bash sudo tmux

ここでも、yENTERの順に押して、インストールを確認します。 パッケージのインストールは問題なく実行されます。

pkg infoを使用して、現在インストールされているパッケージ(依存関係がある場合はそれを含む)を一覧表示できます。 他のソースからのパッケージがインストールされていないことを確認するために、クラッシュや非互換性を引き起こす可能性があります。pkg query "%n: autoinstalled=%a from repo=%R"を使用して、インストールされているパッケージとこれらの詳細を一覧表示できます。 pkgunknown-repositoryからブートストラップされたものとして表示されることに注意してください。これが、以前にブートストラップ出力を検証して、パッケージマネージャー自体も独自のパッケージリポジトリから取得されていることを確認した理由です。

この最後のステップでは、クライアント上のCIのパッケージリポジトリへのアクセスを構成し、オプションでセキュリティ目的でパッケージ署名の検証を有効にし、互換性の問題を回避するためにパッケージが単一のソースからのみ取得されるようにし、パッケージマネージャーをブートストラップしましたpkg 、CIによってビルドされた目的のパッケージをインストールします。

結論

このチュートリアルでは、Poudriereのインストールと構成、パッケージビルドの自動実行、クライアントホストからのパッケージリポジトリへの安全なアクセスの構成を行い、最終的に単一の中央ソースからインストールされた最新のビルドパッケージを作成しました。 このセットアップにより、サーバーの一貫性と最新性を維持し、外部ソフトウェアパッケージのバージョンアップグレードを管理できる優れた立場になります。

現在の設定をさらに強化するために、次のフォローアップ手順を選択することを検討できます。

  • プライベートアクセスのみ:デフォルトでは、ドロップレットはインターネット上でパブリックIPアドレスを持っています。 また、Buildbot は認証をサポートしていますが、デフォルトでは保護されていません。
  • ビルドの問題に関するアラート:開始するには、Buildbotレポーターのセットアップ方法を確認してください。
  • ポートツリーを最新の状態に保つ:チュートリアルの例では、四半期ブランチ 2019Q2が使用されましたが、最終的には新しいツリーに切り替えるか、独自のバージョン管理されたリポジトリを使用する必要があります必要なパッチを適用します。
  • 独自のプロジェクトのビルドの追加FreeBSD Porter's Handbook は、内部ソフトウェアをビルドしてインストールする場合のビルドレシピ( port )の書き方を説明しています。 FreeBSDパッケージ。
  • クライアントの古いパッケージの監視:バージョンが完全に一致しないすべてのパッケージを出力するsudo pkg update -q && sudo pkg version -q --not-like "="の出力を使用して、クライアントにインストールされているパッケージとCIで利用可能な最新のパッケージを比較できます。 詳細については、pkg-versionマンページを参照してください。
  • クリーンアップジョブの追加:時間の経過とともに、Buildbotワーカーjailは、古いビルドログファイル、ソースtarball、および場合によっては非推奨のパッケージでいっぱいになります。 コマンドpoudriere {logclean,distclean,pkgclean}を使用してクリーンアップします( poudriereのマンページを参照)。