Ubuntu16.04でBuildbotとの継続的インテグレーションを設定する方法

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

序章

Buildbot は、ソフトウェアのビルド、テスト、およびリリースプロセスを自動化するためのPythonベースの継続的インテグレーションシステムです。 以前のチュートリアルでは、 Buildbot をインストールし、 systemdユニットファイルを作成して、サーバーのinitシステムがプロセスを管理できるようにし、Nginxをリバースプロキシとして構成しました SSLで保護されたブラウザリクエストをBuildbotのウェブインターフェースに転送するため。

このガイドでは、リポジトリへの新しい変更を自動的にテストする継続的インテグレーションシステムをセットアップする方法を示します。 単純なNode.jsアプリケーションを使用して、テストプロセスと必要な構成を示します。 テスト環境をBuildbotホストから分離するために、Buildbotワーカーとして実行するDockerイメージを作成します。 次に、GitHubリポジトリで変更を監視するようにビルドボットマスターを構成し、新しい変更が検出されるたびに自動的にテストします。

前提条件

このチュートリアルに従うには、次のものが必要です。

さらに、サーバーで次のチュートリアルを完了する必要があります。

これらの要件を完了すると、開始する準備が整います。

GitHubでサンプルリポジトリをフォークします

Buildbotの構成を開始する前に、このガイドで使用するリポジトリの例を見ていきます。

Webブラウザーで、デモに使用するGitHubhellohapiアプリケーションにアクセスします。 このアプリケーションは、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

このファイルでは、FROM buildbot/buildbot-worker:masterを使用して、Buildbotワーカーイメージに基づいてイメージを作成します。 その後、rootユーザーに切り替えてNode.jsをインストールしてから、buildbotユーザーに切り替えて実際のコマンドを実行できます。

〜/ Dockerfile

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マスター構成に追加して、ユーザーと認証の設定を保持します。

次に、Buildbotインスタンスの動作を再定義できる新しいmaster.cfgファイルを作成します。

sudo nano /home/buildbot/master/master.cfg

このファイルで新しいBuildbotマスター構成を定義します。

基本的なプロジェクト構成をセットアップする

Buildbot構成ファイルは実際にはPythonモジュールであり、複雑さを犠牲にして大きな柔軟性を提供します。

まず、いくつかの基本的な構成から始めます。 次の行をファイルに貼り付けます。

/home/buildbot/master/master.cfg

# -*- 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という名前の省略変数を作成して、ファイル全体で必要な入力の量を減らします。

次の構成で注意すべき点がいくつかあります。

  • buildbotNetUsageDataNoneに設定されます。 開発者に使用状況データを報告する場合は、これを文字列"basic"に変更します。
  • titletitleURLは、プロジェクトの名前とGitHubリポジトリを反映しています。 自分のフォークへのリンクを使用してください。
  • buildbotURLは、BuildbotマスターのSSLで保護されたドメイン名に設定されます。 https://で始まり、末尾のスラッシュ/で終わることを忘れないでください。
  • 最後の構成とは異なり、protocol定義はローカルホストにバインドされません。 Dockerブリッジネットワークdocker0を介したDockerコンテナーからの接続を許可する必要があります。

Dockerワーカーを構成する

次に、Dockerワーカーを定義する必要があります。 Buildbotは、必要に応じてDockerを使用してワーカーをプロビジョニングします。 そのためには、Dockerへの接続方法と使用するイメージを知る必要があります。

ファイルの下部に以下を貼り付けます。

/home/buildbot/master/master.cfg

. . .

# 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'))

c['workers'] = []行は、構成を進めるときに使用する基本的な規則を示しています。 構成ディクショナリのキーを空のリストに設定します。 次に、リストに要素を追加して、実際の構成を実装します。 これにより、後で要素を追加する柔軟性が得られます。

ワーカーを定義するために、worker.DockerLatentWorkerインスタンスを作成してworkerリストに追加します。 このワーカーにはnpm-docker-workerという名前を付けて、後で構成で参照できるようにします。 次に、docker_hostをDockerのソケットの場所に設定し、作成したDockerイメージの名前(この場合はnpm-worker)を指定します。 masterFQDNをBuildbotマスターのドメイン名に設定して、サーバーの内部ホスト名設定に関係なく、コンテナーがマスターに到達できるようにします。

スケジューラを構成する

次に、スケジューラーを定義します。 Buildbotはスケジューラーを使用して、変更ソースまたは変更フックから受け取った変更に基づいて、ビルドを実行するタイミングと方法を決定します(変更フックは後で構成します)。

次の構成をファイルの下部に貼り付けます。

/home/buildbot/master/master.cfg

. . .

# 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インスタンスを定義してから、実行する必要のある一連のステップを追加します。

ファイルの下部に以下を貼り付けます。

/home/buildbot/master/master.cfg

. . .

# 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を「full」に設定し、methodを「clobber」に設定して、新しいコードをプルするたびにリポジトリを完全にクリーンアップします。

追加する2番目と3番目のステップは、steps.ShellCommandオブジェクトです。これは、ビルド中にリポジトリ内で実行するシェルコマンドを定義します。 この場合、プロジェクトの依存関係を収集するためにnpm installを実行する必要があります。 その後、テストスイートを実行するためにnpm testを実行する必要があります。 ほとんどの場合、コマンドをリスト(["npm", "install"])として定義して、シェルがコマンド内の要素に不要な拡張を適用しないようにすることをお勧めします。

Builderを構成する

ステップが追加されたビルドファクトリができたら、ビルダーをセットアップできます。 ビルダーは、ビルドの実行方法を決定するために、すでに定義した要素の多くを結び付けます。

次の構成をファイルの下部に貼り付けます。

/home/buildbot/master/master.cfg

. . .

# 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つの設定は、リストではなく辞書として定義されています。 dbディクショナリは、/home/buildbot/masterディレクトリにすでにあるstate.sqliteファイルを指しているだけです。 wwwディクショナリには、かなりの量の追加構成が含まれています。

ファイルの下部に以下を貼り付けます。 以下の認証ブロックを、元のBuildbotマスター構成からコピーした認証情報に置き換えます。

/home/buildbot/master/master.cfg

. . .

# 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構成ファイルから取得した認証要件を追加します。

最後に、wwwディクショナリ内にchange_hook_dialectsというディクショナリを定義します。 これを使用して、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なしでは新しいワーカーをプロビジョニングできないため、この要件を定義する必要があります。

/etc/systemd/systemディレクトリ内のbuildbot-master.serviceファイルを開いて、サービスファイルを調整します。

sudo nano /etc/systemd/system/buildbot-master.service

[Unit]セクションで、network.target項目の後のAfterディレクティブにdocker.serviceを追加します。 docker.serviceという名前のWantsディレクティブを追加します。 Wantsはソフト依存関係を確立し、Afterディレクティブは開始順序を確立します。

/etc/systemd/system/buildbot-master.service

[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ワーカーを動的に起動できます。