[Python][PyAgile][Buildbot] The Buildbot 動かしてみた

http://buildbot.sourceforge.net/
試したのは、0.7.4 多分最新

BuildbotはCIツールで、継続結合を助けてくれるツールです。
リポジトリを監視して、最新版を取り出し、ビルド、テスト、結果レポートなどいろんなことをしてくれます。

インストール

http://buildbot.sourceforge.net/から辿って、ソースを入手。
以下、Pythonistaにはいつもの光景

$ tar xvzf buildbot-0.7.4.tar.gz 
$ cd buildbot-0.7.4/
$ python setup.py build
$ sudo python setup.py install
$ buildbot --version
Buildbot version: 0.7.4
Twisted version: 2.4.0

みてわかるとおり、Twistedが必要です。
http://twistedmatrix.com/trac/から入手してください。
先に同梱されているZopenInterfaceをインストールすれば問題ないでしょう。
(ってか、Twsitedのインストールスクリプトは、ZopeInterfaceインストールしてくれない)

マスタ側設定

マスタは、リポジトリを監視して、スレーブに色々(ソース取得とか、ビルドとか、テストとかとか)しろと命令します。
本当は別アカウントで作るべきらしいのだけど、今回は通常アカウントで両方やってしまう。

# buildbot用のディレクトリを作成。このディレクトリはスレーブでも使う。
$ mkdir buildbot
$ cd buildbot
# マスタ用ディレクトリを掘る
$ mkdir masters
$ cd masters/
# プロジェクトディレクトリを掘る
$ mkdir hello
# プロジェクトディレクトリ下にbuildbotマスタを作る
$ buildbot create-master hello/
updating existing installation
chdir /Users/aodag/buildbot/masters/hello
creating master.cfg.sample
creating Makefile.sample
buildmaster configured in /Users/aodag/buildbot/masters/hello
# 設定ファイルのサンプルがあるので、とりあえずコピー
$ cp master.cfg.sample master.cfg 

ここで、master.cfgの中身を確認しておく。
確認しておかなきゃいけない(スレーブ作成時に必要)のは、以下の点

# スレーブのアカウント 1個目がユーザー(ボット)ID、2個目がパスワード
c['bots'] = [("bot1name", "bot1passwd")]
# スレーブ待ち受けのポート(TCP)
c['slavePortnum'] = 9989

スレーブ側

実際の処理をしてくれるのが、スレーブ側です。

# マスタ側作成の時に作ったbuildbot用ディレクトリに移動
$ cd buildbot
# スレーブ用ディレクトリ作成
$ mkdir slaves
$ cd slaves
# サンプルプロジェクトディレクトリ作成
$ mkdir hello
# スレーブを作成
$ buildbot create-slave hello/ localhost:9989 bot1name bot1passwd
updating existing installation
chdir /Users/aodag/buildbot/slaves/hello
creating Makefile.sample
mkdir /Users/aodag/buildbot/slaves/hello/info
Creating info/admin, you need to edit it appropriately
Creating info/host, you need to edit it appropriately
Please edit the files in /Users/aodag/buildbot/slaves/hello/info appropriately.
buildslave configured in /Users/aodag/buildbot/slaves/hello

スレーブ作成のコマンドは以下のとおり、

buildbot create-slave ベースディレクトリ マスタ ボットID パスワード

マスタ、ボットID、パスワードはmaster.cfgの内容から。

ホスト情報も作っときましょう。
とりあえずOS情報とPythonのバージョンを入れとく。

$ (uname -a;python -V)  > hello/info/host 2>&1

中身はこんな感じ

Darwin odagiri-atsushi-nokonpyuta.local 8.8.1 Darwin Kernel Version 8.8.1: Mon Sep 25 19:42:00 PDT 2006; root:xnu-792.13.8.obj~1/RELEASE_I386 i386 i386
Python 2.4.3

サンプルプロジェクト

とりあえず適当にでっちあげました。
bankaccount.py

#!/usr/bin/env python
"""
>>> account = BankAccount()
>>> account.balance
0
>>> account = BankAccount(100)
>>> account.balance
100
>>> account.deposit(10)
>>> account.balance
110
>>> account.withdraw(20)
>>> account.balance
90
>>> try:
...   account.withdraw(-101)
... except:
...   pass
...
"""


class BankAccount:
    """
    BankAccount - emulating account of bank.:)
    """
    
    def __init__(self, balance=0):
        self.balance = balance

    def deposit(self, amount):
        """deposit amount from bank account.
        """
        self.changeBalance(self.balance + amount)

    def withdraw(self, amount):
        """withdraw amount from bank account.
        """
        self.changeBalance(self.balance - amount)

    def changeBalance(self, newBalance):
        if newBalance < 0:
            raise Exception()
        self.balance = newBalance

if __name__ == '__main__':
    import doctest
    doctest.testmod(raise_on_error=True)

doctest.testmodでraise_on_errorを指定するのは、
テストでパスしなかったときに、そのままエラーにして、buildbotに伝えるため。
でも、エラー内容が非常に見づらいので、他の方法を考えたい。

とりあえずテストが通ることを確認。

$ python bankaccount.py
$ echo $?
0

SVNリポジトリに入れる。

$ svn import file:///Users/aodag/SVNRepo/trunk/bankaccount
$ cd ..
$ mv bankaccount bankaccount.old
$ svn co file:///Users/aodag/SVNRepo/trunk/bankaccount

このSVNのURL(file:///Users/aodag/SVNRepo/trunk/bankaccount)はちゃんと覚えておくこと。

ソース設定

buildbotのソースはリポジトリとか、ソースがある場所ということで。
設定する箇所は、以下の場所(サンプルのbuildbotプロジェクトの設定があるので、ちょっと流用)
スケジューラ関連はとりあえずコメントアウト

c['schedulers'] = 
#c['schedulers'].append(Scheduler("all", branch=None, 
#                                 builderNames=["buildbot-full"],
#                                 treeStableTimer=2*60))

svnurl = "file:///Users/aodag/SVNRepo/trunk/bankaccount"
builders = 

from buildbot.process import step, factory
f1 = factory.BuildFactory()
f1.addStep(step.SVN,
           svnurl=svnurl)
f1.addStep(step.Test, command=["python", "bankaccount.py"],
           haltOnFailure=True)

b1 = {'name': "bankaccount",
      'slavename': "bot1name",
      'builddir': "full",
      'factory': f1,
      }
c['builders'] = [b1]

factoryは手順のファクトリ?
よく分かりませんが、factory に手順を追加していきます。
1つ目の手順は、SVNからのチェックアウト(またはアップデート)。
svnurlを指定しておけば、あとはよきにはからってくれます。
2つ目は、テスト実行。
haltOnFailureを指定して、テストが失敗したときは止まるようにしています。
また、デフォルトでは、make check が実行されるので、commandにて、実際のテストを指定します。
後は、追加情報とあわせてビルダーを作成して、設定辞書に追加。

デーモンを動かす

デーモンさんを動かして、監視してもらいましょう。

$ cd buildbot/masters
$ buildbot start hello
$ cd ../slaves
$ buildbot start hello

http://localhost:8010にアクセスすると、buildbotの稼働状態が分かります。
とりあえず1個だけスレーブがあるので、リンクを辿る(http://localhost:8010/bankaccount)と、
スレーブのホスト情報が見れます。
また、「Force Build」ボタンを押すと、設定した手順を実行します。
押した直後はまだ実行結果が出ていないかもしれません。
一息ついて、リロードしてみましょう。
ボタンを押した時刻に、ビルド番号と、実行した手順が表示されます。
スレーブの一番上は「build successfull」となっているはず。

これでとりあえず動くことが確認できました。

後はスケジューラを使ったリポジトリの監視です。

が、そろそろ眠いのでまた明日。