Ubuntu16.04でBuildbotとの継続的インテグレーションを設定する方法
序章
Buildbot は、ソフトウェアのビルド、テスト、およびリリースプロセスを自動化するためのPythonベースの継続的インテグレーションシステムです。 以前のチュートリアルでは、 Buildbot をインストールし、 systemdユニットファイルを作成して、サーバーのinitシステムがプロセスを管理できるようにし、Nginxをリバースプロキシとして構成しました SSLで保護されたブラウザリクエストをBuildbotのウェブインターフェースに転送するため。
このガイドでは、リポジトリへの新しい変更を自動的にテストする継続的インテグレーションシステムをセットアップする方法を示します。 単純なNode.jsアプリケーションを使用して、テストプロセスと必要な構成を示します。 テスト環境をBuildbotホストから分離するために、Buildbotワーカーとして実行するDockerイメージを作成します。 次に、GitHubリポジトリで変更を監視するようにビルドボットマスターを構成し、新しい変更が検出されるたびに自動的にテストします。
前提条件
このチュートリアルに従うには、次のものが必要です。
- 少なくとも1GBのRAMを搭載した1台のUbuntu16.04サーバー、非ルートで構成
sudo
Ubuntu16.04初期サーバーセットアップガイドに従ってユーザーとファイアウォール
さらに、サーバーで次のチュートリアルを完了する必要があります。
- Ubuntu16.04にBuildbotをインストールする方法
- BuildbotのSystemdユニットファイルを作成する方法
- Ubuntu16.04にNginxをインストールする方法
- Ubuntu16.04でLet’sEncryptを使用してNginxを保護する方法。
- Nginxリバースプロキシを使用してSSLでBuildbotを構成する方法
- Ubuntu16.04にDockerをインストールして使用する方法:(ステップ1と2のみ)
これらの要件を完了すると、開始する準備が整います。
GitHubでサンプルリポジトリをフォークします
Buildbotの構成を開始する前に、このガイドで使用するリポジトリの例を見ていきます。
Webブラウザーで、デモに使用するGitHubのhellohapiアプリケーションにアクセスします。 このアプリケーションは、Node.jsWebフレームワークであるhapi で記述された、いくつかのユニットテストと統合テストを備えた単純な「HelloWorld」プログラムです。
この例はさまざまな継続的インテグレーションシステムを示すために使用されているため、他のシステムのパイプラインを定義するために使用されるファイルに気付く場合があります。 Buildbotの場合、リポジトリ内ではなくサーバー上でビルドステップを定義します。
後で、リポジトリ内にBuildbotのWebhookを設定して、変更によって新しいテストが自動的にトリガーされるようにします。 今のところ、リポジトリの独自のフォークを作成する必要があります。
画面右上のフォークボタンをクリックします。
GitHub組織のメンバーである場合、リポジトリをフォークする場所を尋ねられることがあります。
アカウントまたは組織を選択すると、リポジトリのコピーがアカウントに追加されます。
Buildbot構成内でフォークのURLを使用します。 リポジトリURLができたので、Buildbotの構成を開始できます。
Buildbot用にDockerをセットアップする
まず、BuildbotがDockerを使用してビルドを実行するようにDockerを設定します。 まず、DockerとBuildbot間のアクセスを構成する必要があります。 その後、コンテナに使用するDockerイメージを作成する必要があります。
BuildbotのDockerへのアクセスを構成する
BuildbotとDockerがいくつかの異なるレベルで通信できるようにする必要があります。
まず、BuildbotプロセスがDockerデーモンにアクセスできることを確認する必要があります。 これを行うには、buildbotユーザーをdockerグループに追加します。
- sudo usermod -aG docker buildbot
この新しいグループは、次にBuildbotマスターが再起動されたときに、Buildbotで使用できるようになります。これについては後で説明します。
また、BuildbotがDockerとの通信方法を知っていることを確認する必要があります。 BuildbotはPythonで記述されているため、Dockerコマンドを直接発行する代わりに、docker-pyPythonパッケージを利用します。
インストールできます docker-py
次のように入力します。
- sudo -H pip install docker-py
最後に、コンテナからホストシステムおよび外部へのネットワークアクセスを開く必要があります。 これを行うには、例外を許可します docker0
ファイアウォールのインターフェース。
からのトラフィックへのアクセスを許可する docker0
次のように入力してインターフェースします。
- sudo ufw allow in on docker0
これで、BuildbotとDockerは互いに効果的に通信できるようになります。
Buildbotワーカーとして使用するDockerイメージを作成する
次に、テストを実行するためのBuildbotワーカーとして使用するDockerコンテナーを作成します。 BuildbotはDockerコンテナーを動的に起動してワーカーとして使用できますが、コンテナーはまず、いくつかのBuildbotワーカーコンポーネントを含めてビルドする必要があります。
幸い、Buildbotプロジェクトは、Buildbot固有の要件がすべてすでに構成されている基本的なBuildbotワーカーイメージを提供します。 このイメージをベースとして使用し、プロジェクトに必要な追加の依存関係をインストールする必要があります。
この場合、使用するサンプルアプリケーションはNode.jsアプリケーションであるため、イメージでNode.jsが使用可能であることを確認する必要があります。
画像を定義するには、というファイルを作成して開きます。 Dockerfile
ホームディレクトリ:
- nano ~/Dockerfile
このファイルでは、Buildbotワーカーイメージに基づいてイメージを作成します。 FROM buildbot/buildbot-worker:master
. その後、に切り替えることができます root
ユーザーがNode.jsをインストールしてから、 buildbot
実際のコマンドを実行するユーザー:
FROM buildbot/buildbot-worker:master
USER root
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
RUN apt-get install -y nodejs
USER buildbot
終了したら、ファイルを保存して閉じます。
一度私たちが Dockerfile
、それからイメージを構築できます。 画像と呼びます npm-worker
インストールした追加の依存関係について明示するために:
- docker build -t npm-worker - < ~/Dockerfile
Dockerは、 Dockerfile
. ベースイメージとその依存関係レイヤーをプルダウンし、Node.jsをインストールして、結果の環境をというイメージに保存します。 npm-worker
.
Buildbotマスターを構成する
Dockerイメージができたので、それを使用するようにBuildbotマスターを構成できます。
まったく新しいビルドプロセスを定義しており、マスター構成へのカスタマイズはこれまで最小限であったため、構成を最初から開始します。 現在の情報が失われないように、元のファイルをバックアップファイルに移動します。
- sudo mv /home/buildbot/master/master.cfg /home/buildbot/master/master.cfg.bak
バックアップファイルの構成を表示して、新しい構成で使用するいくつかの重要な値をコピーできるようにします。
- sudo cat /home/buildbot/master/master.cfg.bak
新しい構成に転送する重要な部分は、ユーザーの資格情報と権限です。 で始まる構成セクションを探します c['www']['authz']
と c['www']['auth']
出力:
Output. . .
c['www']['authz'] = util.Authz(
allowRules = [
util.AnyEndpointMatcher(role="admins")
],
roleMatchers = [
util.RolesFromUsername(roles=['admins'], usernames=['Sammy'])
]
)
c['www']['auth'] = util.UserPasswordAuth({'Sammy': 'Password'})
. . .
これらの行をコピーしてどこかに保存し、後で参照できるようにします。 これらの詳細を新しいBuildbotマスター構成に追加して、ユーザーと認証の設定を保持します。
今、新しいを作成します master.cfg
Buildbotインスタンスの動作を再定義できるファイル:
- sudo nano /home/buildbot/master/master.cfg
このファイルで新しいBuildbotマスター構成を定義します。
基本的なプロジェクト構成をセットアップする
Buildbot構成ファイルは実際にはPythonモジュールであり、複雑さを犠牲にして大きな柔軟性を提供します。
まず、いくつかの基本的な構成から始めます。 次の行をファイルに貼り付けます。
# -*- python -*-
# ex: set filetype=python:
from buildbot.plugins import *
c = BuildmasterConfig = {}
# Basic config
c['buildbotNetUsageData'] = None
c['title'] = "Hello Hapi"
c['titleURL'] = "https://github.com/your_github_name/hello_hapi"
c['buildbotURL'] = "https://buildmaster_domain_name/"
c['protocols'] = {'pb': {'port': 9989}}
ファイルの先頭には、構文の強調表示を正しく適用するために多くのテキストエディタが解釈できるコメントがいくつか含まれています。 その後、からすべてをインポートします buildbot.plugins
パッケージを作成して、構成を構築するためのツールを利用できるようにします。
Buildbotの構成はすべて、という名前の辞書によって定義されます BuildmasterConfig
、したがって、この変数を空の辞書に設定して開始します。 名前の付いた省略変数を作成します c
この同じ辞書に設定して、ファイル全体で必要な入力の量を減らします。
次の構成で注意すべき点がいくつかあります。
buildbotNetUsageData
に設定されていますNone
. これを文字列に変更します"basic"
使用状況データを開発者に報告する場合。- The
title
とtitleURL
プロジェクトの名前とGitHubリポジトリを反映します。 自分のフォークへのリンクを使用してください。 buildbotURL
BuildbotマスターのSSLで保護されたドメイン名に設定されます。 から始めることを忘れないでくださいhttps://
末尾にスラッシュを付けて終了します/
.- 前回の構成とは異なり、
protocol
定義はローカルホストにバインドされません。 Dockerブリッジネットワークを介したDockerコンテナからの接続を許可する必要がありますdocker0
.
Dockerワーカーを構成する
次に、Dockerワーカーを定義する必要があります。 Buildbotは、必要に応じてDockerを使用してワーカーをプロビジョニングします。 そのためには、Dockerへの接続方法と使用するイメージを知る必要があります。
ファイルの下部に以下を貼り付けます。
. . .
# Workers
c['workers'] = []
c['workers'].append(worker.DockerLatentWorker("npm-docker-worker", None,
docker_host='unix://var/run/docker.sock',
image='npm-worker',
masterFQDN='buildmaster_domain_name'))
The c['workers'] = []
行は、構成を行うときに使用する基本的な規則を示しています。 構成ディクショナリのキーを空のリストに設定します。 次に、リストに要素を追加して、実際の構成を実装します。 これにより、後で要素を追加する柔軟性が得られます。
ワーカーを定義するために、 worker.DockerLatentWorker
インスタンスへのインスタンス worker
リスト。 この労働者に名前を付けます npm-docker-worker
後で構成で参照できるようにします。 次に、 docker_host
Dockerのソケットの場所に移動し、作成したDockerイメージの名前を指定します(npm-worker
私たちの場合には)。 設定しました masterFQDN
サーバーの内部ホスト名設定に関係なく、コンテナーがマスターに到達できることを確認するために、Buildbotマスターのドメイン名に追加します。
スケジューラを構成する
次に、スケジューラーを定義します。 Buildbotはスケジューラーを使用して、変更ソースまたは変更フックから受け取った変更に基づいて、ビルドを実行するタイミングと方法を決定します(変更フックは後で構成します)。
次の構成をファイルの下部に貼り付けます。
. . .
# Schedulers
c['schedulers'] = []
c['schedulers'].append(schedulers.SingleBranchScheduler(
name="hello_hapi",
change_filter=util.ChangeFilter(project='your_github_name/hello_hapi', branch='master'),
treeStableTimer=3,
builderNames=["npm"]))
ここでは、空のリストに構成を追加するのと同じ方法を使用します。 この場合、追加します schedulers.SingleBranchScheduler
実例。 これにより、リポジトリ上の単一のブランチを監視できるようになり、構成が簡素化されます。
スケジューラーを適切に識別するために、スケジューラーに「hello_hapi」という名前を付けます。 次に、変更フィルターを定義します。 さまざまなソースからのさまざまな変更セットがスケジューラーに渡される場合があります。 変更フィルターは、問題の変更をこの特定のスケジューラーで処理する必要があるかどうかを決定する一連の基準を定義します。 この例では、GitHub Webhookによって報告されるプロジェクトの名前と、監視するブランチに基づいてフィルタリングします。
次に、 treeStableTimer
、追加の変更を待機する時間を3秒に決定します。 これにより、Buildbotが密接に関連する変更のために多くの小さなビルドをキューに入れるのを防ぐことができます。 最後に、変更が基準に一致するときに使用するビルダーの名前を定義します(このビルダーはすぐに定義します)。
Node.jsプロジェクトのビルドファクトリを構成する
次に、Node.jsプロジェクトを処理するためのビルドファクトリを構成します。 ビルドファクトリは、プロジェクトをビルドするために、またはこの場合はテストするために実行する必要がある手順を定義する責任があります。 これは、 util.BuildFactory
インスタンスを作成してから、実行する必要のある一連のステップを追加します。
ファイルの下部に以下を貼り付けます。
. . .
# Build Factories
npm_f = util.BuildFactory()
npm_f.addStep(steps.GitHub(repourl='git://github.com/your_github_name/hello_hapi.git', mode='full', method='clobber'))
npm_f.addStep(steps.ShellCommand(command=["npm", "install"]))
npm_f.addStep(steps.ShellCommand(command=["npm", "test"]))
まず、ビルドファクトリを定義します npm_f
. 追加する最初のステップは steps.GitHub
実例。 ここでは、ビルダーにプルダウンする必要があるリポジトリを設定します。 設定しました mode
「満杯」に method
新しいコードをプルするたびにリポジトリを完全にクリーンアップするために「clobber」します。
追加する2番目と3番目のステップは steps.ShellCommand
オブジェクト。ビルド中にリポジトリ内で実行するシェルコマンドを定義します。 私たちの場合、実行する必要があります npm install
プロジェクトの依存関係を収集します。 その後、実行する必要があります npm test
テストスイートを実行します。 コマンドをリストとして定義する(["npm", "install"]
)ほとんどの場合、シェルがコマンド内の要素に不要な拡張を適用しないようにすることをお勧めします。
Builderを構成する
ステップが追加されたビルドファクトリができたら、ビルダーをセットアップできます。 ビルダーは、ビルドの実行方法を決定するために、すでに定義した要素の多くを結び付けます。
次の構成をファイルの下部に貼り付けます。
. . .
# Builders
c['builders'] = []
c['builders'].append(
util.BuilderConfig(name="npm",
workernames=["npm-docker-worker"],
factory=npm_f))
追加します util.BuilderConfig
に反対する builders
リスト。 私たちのビルドファクトリは npm_f
、Dockerワーカーが呼び出されること npm-docker-worker
、そして私たちが定義したスケジューラーは、という名前のワーカーにタスクを渡します npm
. ビルダーは、これらの要素間の関係を定義して、スケジューラーからの変更により、ビルドファクトリステップがDockerワーカーで実行されるようにします。
データベースとWebインターフェイスを構成する
最後に、データベースとWebインターフェイスの設定を構成できます。 前の項目の多くとは異なり、これら2つの設定は、リストではなく辞書として定義されています。 The db
辞書はただ指している state.sqlite
すでに私たちのファイルに /home/buildbot/master
ディレクトリ。 The www
辞書には、かなりの量の追加構成が含まれています。
ファイルの下部に以下を貼り付けます。 以下の認証ブロックを、元のBuildbotマスター構成からコピーした認証情報に置き換えます。
. . .
# Database
c['db'] = { 'db_url': "sqlite:///state.sqlite",}
# Web Interface
c['www'] = dict(port=8010, plugins=dict(waterfall_view={}, console_view={}))
# Auth info copied from the original configuration
c['www']['authz'] = util.Authz(
allowRules = [
util.AnyEndpointMatcher(role="admins")
],
roleMatchers = [
util.RolesFromUsername(roles=['admins'], usernames=['Sammy'])
]
)
c['www']['auth'] = util.UserPasswordAuth({'Sammy': 'Password'})
# End of auth info copied from the original configuration
# GitHub webhook receiver
c['www']['change_hook_dialects'] = {
'github': {
'secret': 'your_secret_value',
'strict': True,
}
}
データベース設定を定義した後、 www
リッスンするポートとWebUIに含めるビューの一部を定義することから始まる辞書。 次に、前のBuildbot構成ファイルから取得した認証要件を追加します。
最後に、という辞書を定義します change_hook_dialects
以内 www
辞書。 これを使用して、GitHubからのWebhookメッセージをリッスンするGitHub変更フックを定義します。 安全なパスフレーズを選択してください secret
、GitHubが送信するメッセージを認証するために使用されます。
終了したら、ファイルを保存して閉じます。
Buildbotマスターを再起動して、新しい構成を適用します
この時点で、Buildbotマスタープロセスを完全に再構成しました。 変更を実装するには、Buildbotマスタープロセスを再起動する必要があります。
その前に、ファイルに構文エラーがないかどうかを確認することが重要です。 構成を最初から再構築したため、いくつかの間違いが発生した可能性があります。
次のように入力して、ファイルの構文を確認します。
- sudo buildbot checkconfig /home/buildbot/master
コマンドは、検出した問題を報告します。 エラーが見つからなかった場合は、次のようなメッセージが表示されます。
OutputConfig file is good!
エラーが報告された場合は、エラーメッセージを注意深く読んで、何が問題なのかをよりよく理解するようにしてください。 構成ファイルを再度開いて、問題の修正を試みてください。
エラーがなくなったら、次のように入力してBuildbotマスターサービスを再起動します。
- sudo systemctl restart buildbot-master
次のように入力して、操作が成功したかどうかを確認します。
- sudo systemctl status buildbot-master
Output● buildbot-master.service - BuildBot master service
Loaded: loaded (/etc/systemd/system/buildbot-master.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2017-06-27 19:24:07 UTC; 2s ago
Main PID: 8298 (buildbot)
Tasks: 2
Memory: 51.7M
CPU: 1.782s
CGroup: /system.slice/buildbot-master.service
└─8298 /usr/bin/python /usr/local/bin/buildbot start --nodaemon
Jun 27 19:24:07 bb5 systemd[1]: Started BuildBot master service
サービスが正常に再起動できた場合、アクティブとしてマークされます。
サンプルリポジトリにGitHubWebhookを作成します
BuildbotがGitHubWebhook投稿を受け入れるようにWebエンドポイントで構成されたので、フォークのWebhookを構成できます。
Webブラウザーで、サンプルプロジェクトリポジトリのフォークに移動します。
https://github.com/your_github_user/hello_hapi
設定タブをクリックして、プロジェクトの設定を表示します。 設定ページの左側のメニューで、 Webhooks をクリックします(GitHubは、このプロセス中にIDを確認するためにパスワードの再入力を求めるメッセージを表示する場合があります)。
右側にあるWebhookの追加ボタンをクリックして、新しいWebhookを追加します。
次のページには、Webhookを定義するためのフォームが含まれています。 Payload URL フィールドに、プロジェクトのGitHub変更フックエンドポイントのURLを追加します。 これは、 https://
プロトコル、Buildbotマスターのドメイン名、 /change_hook/github
.
コンテンツタイプをに設定したままにします application/x-www-form-urlencoded
. Secret フィールドに、Buildbotマスター構成ファイルで選択したシークレットパスフレーズを入力します。 「プッシュイベントのみ」トリガーを選択したままにして、「アクティブ」チェックボックスをオンのままにすることができます。
終了したら、Webhookの追加ボタンをクリックします。
プロジェクトのwebhookインデックスに戻り、新しいWebhookが表示されます。 数回更新すると、メッセージが正常に送信されたことを示す緑色のチェックマークアイコンがWebhookの横に表示されます。
代わりに赤いXが表示された場合は、Webhookをもう一度クリックして、最近の配信セクションまで下にスクロールします。 失敗した配信をクリックすると、何がうまくいかなかったかについての詳細が表示されます。
Webhookのテスト
Webhookが配置されたので、リポジトリに変更を加えると、Buildbotにアラートが送信され、Dockerでビルドがトリガーされ、テストスイートを正常に実行できることを確認できます。
GitHubフォークのメインページで、緑色の[クローンまたはダウンロード]ボタンの左側にある新しいファイルの作成ボタンをクリックします。
次の画面で、 dummy_file
そして、いくつかのテキストを記入してください:
終了したら、ページの下部にある新しいファイルをコミットボタンをクリックします。
次に、Buildbot Webインターフェイスにアクセスし、まだ認証されていない場合はログインします。
コミットしてからの経過時間によって異なります dummy_file
リポジトリに、次のような進行中のビルドが表示される場合があります。
ビルドがすでに完了している場合は、代わりに「最近のビルド」セクションに表示されます。
定義したビルダーの名前「npm」は、ビルドにラベルを付けるために使用されます。 この例では、以前のマスター構成からのサンプルビルダーの古い実行も確認できます。
進行状況に関係なく、ビルダー名とビルド番号のリンクをクリックして、ビルドの詳細ページにアクセスします。 このビューには、実行されたビルドに関する情報が含まれています。 ビルドファクトリに追加した各ステップは、独自のセクションに表示されます。
ステップをクリックすると、コマンドの出力が表示されます。 これは、問題が発生した場合のデバッグに役立ちます。
上記の出力では、Buildbotがテストスイート内で3つのテストを正常に実行したことを確認できます。
ビルドが正常に完了しなかった場合は、ビルドの詳細ページの他のタブと、 /home/buildbot/master/twistd.log
ファイル。
Buildbotサービスの調整
終了する前に、Buildbotサービスにいくつかの調整を加える必要があります。
現在、 buildbot-worker
使用しなくなったワーカーに対して定義されたサービス(必要に応じてDockerワーカーが自動的に開始されます)。 古いワーカーを停止して無効にする必要があります。
実行中のサービスを停止し、起動時に開始しないようにするには、次のように入力します。
- sudo systemctl stop buildbot-worker
- sudo systemctl disable buildbot-worker
OutputRemoved symlink /etc/systemd/system/buildbot-master.service.wants/buildbot-worker.service.
上記の出力は、ワーカーが次回の起動で開始されないことを示しています。 サービスが実行されていないことを確認するには、次のように入力します。
- sudo systemctl status buildbot-worker
Output● buildbot-worker.service - BuildBot worker service
Loaded: loaded (/etc/systemd/system/buildbot-worker.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Jun 27 21:12:48 bb6 systemd[1]: Started BuildBot worker service.
Jun 27 21:55:51 bb6 systemd[1]: Stopping BuildBot worker service...
Jun 27 21:55:51 bb6 systemd[1]: Stopped BuildBot worker service.
最後にすべきことは、BuildbotマスターサービスとDockerデーモンの間にソフトな依存関係を確立することです。 BuildbotマスターサービスはDockerなしでは新しいワーカーをプロビジョニングできないため、この要件を定義する必要があります。
を開きます buildbot-master.service
内のファイル /etc/systemd/system
サービスファイルを調整するディレクトリ:
- sudo nano /etc/systemd/system/buildbot-master.service
の中に [Unit]
セクション、追加 docker.service
に After
後のディレクティブ network.target
アイテム。 追加する Wants
名前も付けるディレクティブ docker.service
. The Wants
ソフト依存関係を確立します。 After
ディレクティブは開始順序を確立します。
[Unit]
Description=BuildBot master service
After=network.target docker.service
Wants=docker.service
[Service]
User=buildbot
Group=buildbot
WorkingDirectory=/home/buildbot/master
ExecStart=/usr/local/bin/buildbot start --nodaemon
[Install]
WantedBy=multi-user.target
終了したら、ファイルを保存して閉じます。
systemdデーモンとサービスをリロードして、構成をすぐに適用します。
- sudo systemctl daemon-reload
- sudo systemctl restart buildbot-master
Dockerが使用可能になった後、Buildbotマスタープロセスを開始する必要があります。
結論
このチュートリアルでは、Webhookを使用してGitHubリポジトリへの変更をリッスンするようにBuildbotを構成しました。 変更を受け取ると、BuildbotはカスタムDockerイメージに基づいてコンテナーを起動し、新しいコミットをテストします。 Dockerイメージには、Buildbotワーカーインスタンスと、プロジェクトコードのテストに必要な依存関係が含まれています。 これにより、リポジトリに変更が加えられるたびに、Buildbotは必要に応じてBuildbotワーカーを動的に起動できます。