Ukigumo入門 ― 2014年スタイル
とりあえずデモサイトを示しますので適当に見て下さい.
http://ukigumo.moznion.net/
さて今回はゆるふわCIシステムであるところのUkigumoのナウいスタイルについて説明しようと思います.
ここ最近ではUkigumo::AgentというAgentサーバが存在しており,これを使うとまあ便利なんですけれども,ドキュメントが少ない為か *1 あまり利用されている事例を見かけませんので,それらも踏まえて解説したい感じです.
まずUkigumoとは何か
CIシステム.Perl製.
Perl製だが,もちろん他言語のプロジェクトでも使える.
Travisのようにサービスとして提供されている感じではなく,自前でインストールして使う.
多分,感覚としてはJenkinsに近いと思うが,そこまで複雑ではなく,シンプル.
基本的に,「テストの実行及びその結果の取得」と「テスト結果の保存」が主な仕事.詳細は後述.
Ukigumoの登場人物
Ukigumo::Server
Clientから送られてくるテスト結果を保存する為のサーバ.
保存しているテスト結果をブラウザから閲覧するためのウェブアプリケーションもサポートしている.
端的にいうとCPAN Testers Reportsみたいな存在.
Ukigumo::Client
実際にテストを走らせて,Serverにその結果を送る存在.
例えば,Ukigumo::Clientのインスタンスを作って,$client->run()
などと実行してやると,テスト対象のリポジトリをclone or pullしてきて,実際にテストを走らせる.そしてその結果をServerに対してPOSTしてその儚いライフサイクルを終える.
Ukigumo::Agent
Agentサーバ.テストランナーサーバとも言える.
何らかのイベントが発火して,Agentにタスクをenqueueする (AgentサーバのAPIにPOSTする) とAgentが適宜Clientのインスタンスを作って,そのClientのインスタンスにタスクを振って処理を行わせる,という事が出来る.
中にジョブキュー的な機構を持っているので,「次から次へとClientに処理を実行させた結果、ハングして処理を詰まらせる」みたいな悲劇を防ぐことが可能.
実際の例を挙げると,GitHubのPushのWebHooksにAgentサーバのAPIのアドレス (GitHub WebHooksだと/api/github_hook
)を登録しておくと,リポジトリにpushされる度にイベントが発火してWebHooksでリポジトリの情報がAgentサーバのAPIにPOSTされる (つまりenqueueされる) ので,リポジトリにpushされる都度テストを走らせる,みたいなことが出来るようになる.
構成の今昔
かつての構成
かつてはAgentサーバを使わず,下図のようにServerとClientのみでまかなう構成が多かった.
Cron等で定期的に実行するという素朴な感じ.
ここ最近の構成
Agentサーバを使って,Agentが何らかのイベントを受け取ったらClientを立ち上げてジョブを走らせるようにする.
例えばリポジトリにpushされたらそのイベントをAgentに投げて,その都度テストを回してやるという感じ.
最近のインストールの方法
最近ではUkigumoシリーズはCPANにアップされているので,それを使うと楽.今回はこの方法を紹介する.
GitHubに上がっているもの *2 をcloneしてcarton等で実行するのでも良い.そういうことしたい人は説明しなくても出来ると思うので説明略!
なお今回の説明では,簡単化の為にUkigumo::ServerとUkigumo::Agentを同じマシン上で立ち上げるものとする.もちろんそれぞれが別のマシンに存在していて良い.
インストールは至って簡単,以下のコマンドを叩くだけで良い.
$ cpanm Ukigumo::Server Ukigumo::Client Ukigumo::Agent
最近の構成で実際に使ってみる
1. サーバ群を立ち上げる
なにはなくともServerとAgentを立ち上げる必要があるので立ち上げる.
Server
$ ukigumo-server --port=2828 --host=127.0.0.1 --max-workers=4 --config=/path/to/config.pl
--port
と--host
はそれぞれサーバを立ち上げるポートとホスト.
--max-workers
は動かすワーカーの最大数.--config
については後述.
詳細はukigumo-server --help
を参照のこと.
とりあえずこうすると,localhost:2828にUkigumo::Serverが立ち上がる.
Agent
$ ukigumo-agent --port=2829 --server_url=http://127.0.0.1:2828 --work_dir=/tmp/
--port
はAgentサーバを立ち上げるポート番号.
--server_url
はテスト結果をPostするサーバのアドレス (つまり上で立ち上げたUkigumo::Serverのアドレス) .
--work_dir
はClientがリポジトリから実際にコードをcloneしてきてテストを走らせる為に割り当ててあげるワークスペースのディレクトリ.
こういう塩梅で実行するとUkigumo::Agentも立ち上がる.
2. テストしたいリポジトリのルートに.ukigumo.yml
を置く
.ukigumo.yml
というのは,.travis.ymlのようなもので,Ukigumo::Clientはプロジェクトルートに置かれているこのファイルを見てよしなにもろもろ設定をしてくれる.
以下が例:
before_install: - "cpanm -L $HOME/.ukigumo/ukigumo-server/extlib --installdeps --with-develop -n ." install: "ln -s $HOME/.ukigumo/ukigumo-server/extlib ./extlib" script: prove -lrv -Iextlib/lib/perl5 t
before_install
と言うのはinstall
の前段階で走るコマンドで,install
はその名の通りインストール時に走るコマンド.script
では実際にテストを実行するコマンドを指定する.
あけすけに言うと,だいたい.travis.ymlでできることが出来る.現状セット出来るオプションは以下のとおり.実行される時系列順に示している.
- before_install
- install
- before_script
- script
- after_script
<追記>
すっかり忘れていた.
.ukigumo.yml
ではこれ以外にもnotifications
という項目が設定できて,これが便利.
テストの結果を任意のNotifierに渡して,通知を飛ばすということができる.
例えば,以下のように書いてやると,GitHubのStatuses API *3 を使ってテスト結果をGitHubのcommitに反映させる,みたいなことが可能.
notifications: guthub_statuses: - api_endpoint: https://api.github.com access_token: __ACCESS_TOKEN__
他にも色々な通知 (とは言え限定的なのだけれど……) に対応している.Ukigumo::Client::Notify::*
というモジュールがそうした通知に対応している *4.<追記ここまで>
ここらへん,現状公式のドキュメントが無いので書く必要を感じている.
とにかく,こういうものを置くと,Ukigumo::Clientは上手く処理してくれる.
3. (例えば) GitHubのWebHooksに登録してやる
リポジトリにpushされたらその都度テストが走る,みたいな事をさせたいのでGitHubのWebHooksを設定する.
リポジトリの設定のWebHooksのところに,Ukigumo::AgentのサーバのAPIに対するアドレスを突っ込んでやる.
例: http://your.ukigumo-agent.net/api/github_hook
push以外のPayloadが来てもしょうがないので,Push Onlyで問題ない.
(今回はGitHubを例に採っているが,別のものでも構わない.その場合,登録するアドレスは`http://your.ukigumo-agent.net//api/v0/enqueue`のようになると思う *5.しかしここ最近のUkigumoはGitHubに寄せていて,「GitHubを使っていると更に便利!」という風になっているという旨を記す)
Ukigumo関連の設定の勘所
Ukigumo::Server
サーバを立ち上げる時のオプションである--config=/path/to/config.pl
に食わせるコンフィグファイルの話.
コンフィグファイルは以下のような感じになる.
+{ 'DBI' => [ 'dbi:SQLite:dbname=deployment.db', '', '', +{ sqlite_unicode => 1, } ], max_num_of_reports => 5000, max_num_of_reports_by_branch => 1000, enable_compression => 1, };
DBI
はもちろんDBの設定で,Ukigumo::ServerはMySQLとSQLiteに対応している.たいていの場合はSQLiteで問題がない (と思う).
max_num_of_reports
とmax_num_of_reports_by_branch
はそれぞれ「保存するレポートの総個数の上限」と「ブランチごとの保存するレポートの個数の上限」を表している.これを超えると,古いものから順に自動的に消去される.
enable_compression
は,レポートの内容をgzipで圧縮するかどうかの設定で,たいていの場合はenable (つまり1) にすると良いと思う.
Ukigumo::Client
特になし..ukigumo.yml
を使えば良いという位.
Ukigumo::Agent
特になし.強いて言えばukigumo-agent
コマンドには--timeout
というコマンドがあって,テストの実行に指定した以上の時間がかかると強制的に処理を終了させる,ということが出来る (その場合はTIMEOUTという風になり,失敗扱いになる).
そんな感じです
かなり駆け足でしたが,こんなふうにすると使えますよ,という感じでした.
割と簡単に導入できることがお分かりいただけたと思います!!
「単純にテストを走らせて,その結果だけとれればいいワ」みたいな用途だとハマるのではないでしょうか.
ああ,次は公式のドキュメントだ……