Laminar CI service

はじめに

CI/CDツールのうち, オンプレミスで動作して, Dockerコンテナを起動するタイプではないものは限られています. 巨大なフレームワークやSDKを扱う場合や, Windows上のSDKしか提供されていない場合, Dockerコンテナ越しでCI/CDを行うことは大変です.

Jenkins

Jenkinsが有名ですが, 私が欠点と思っているのは次です.

  • ジョブをコードとして管理することが難しい
    • シェルスクリプトにするか, GroovyのDSLにすればできる
    • GroovyのDSLはローカル実行できないので, 開発・保守が非常に手間
  • 不安定
    • 多く要求される機能でもプラグインで対応する体制なので, 更新停止, 脆弱性・不具合の放置がよくある
    • うっかりJenkinsを更新しようものなら, プラグインが対応していなくて環境が崩壊する
    • “何もしていないのに動かなくなりました"が本当に起きる

OSSなんだから不満は自分から改善するように働きかければ?というのは, 私が自動化・CI/CDに興味がないのでモチベーションが湧かないのです.

Laminar

Laminar(GitHub)を試してみます. LaminarはLinux専用のCIツールです. Laminarの役割は待ち行列に積まれたジョブを実行し, ジョブの出力とステータスの集計・保存, それらをHTMLに整形することです.
ジョブ管理, VCSとの連携や定期実行などの機能はありません. ジョブの記述はシェルスクリプト, 定期実行はcronなどを使います.

インストール

sudo apt install git capnproto cmake g++ libboost-dev libcapnp-dev libsqlite3-dev make rapidjson-dev zlib1g-dev pkg-config
git clone https://github.com/ohwgiles/laminar.git
cd laminar
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
make -j "$(nproc)"
# Warning: the following will overwrite an existing /etc/laminar.conf
sudo make install
sudo mkdir -p /var/lib/laminar

WSLのsystemd

/etc/wsl.confにsystemdサポートを追加しておきます.

[boot]
systemd=true

Laminarサービス

/lib/systemd/system/laminar.serviceの実行ユーザを変更します. ローカルで動かすことにしているので, ユーザはrootとします.

[Service]
User=root
sudo systemctl start laminar
sudo systemctl enable laminar

設定

バインドアドレス等を設定する場合は, /etc/laminar.confを編集します.

ジョブ

ジョブは/var/lib/laminar/cfg/jobs以下に, 拡張子.runで作成します. 中身はシェルスクリプトです.

echoするだけの簡単なジョブhello.runを作成してみます.

sudo mkdir -p /var/lib/laminar/cfg/jobs
sudo touch /var/lib/laminar/cfg/jobs/hello.run
sudo chmod a+x /var/lib/laminar/cfg/jobs/hello.run

次のような, スリープするだけのジョブを作成します.

#!/usr/bin/bash -ex
echo 'start hello'
sleep 10
echo 'finish hello'

CLIツールlaminarcでキューにジョブを入れます.

laminarc queue hello

Web UI

デフォルトでは, http://localhost:8080でWeb UIを確認できます.

トップ画面では各種統計が表示されます.

Laminar Web Dash Board

ジョブのコンソールログも確認できます.

Laminar Web Job Result

CLIツール

laminarc <command>の形式で, 操作・情報表示ができます.

コマンド
queue [JOB [PARAMS…]]… ひとつ以上のジョブをキューに入れる. –nextをJOBの前に付けると, キューの先頭に入れる.
start [JOB [PARAMS…]]… ひとつ以上のジョブを開始する. ジョブが開始されるまで待つ.
run [JOB [PARAMS…]]… ひとつ以上のジョブを実行する. 全てのジョブが終了するまで待つ.
set [VARIABLE=VALUE]… ひとつ以上の環境変数を設定する. $JOBと$RUNが同一な以降のスクリプトにエクスポートされる
show-jobs ジョブ一覧を表示する ($LAMINAR_HOME/cfg/jobs/*.run).
show-running 実行中のジョブを表示する
show-queued キューで待機中のジョブを表示する
abort JOB NUMBER 実行中のジョブを強制終了する

ジョブの書き方

公式ドキュメントから, 必要そうなシナリオを実現する方法です.

定期実行

cronに登録します.

0 3 * * * LAMINAR_REASON="Nightly build" laminarc queue hello

ジョブチェイン

ジョブを連鎖させたい場合は, laminarc queueをスクリプト内に書けばよいです.

#!/usr/bin/bash -xe
if [ ... ]; then
  laminarc run example-downstream-special
else
  laminarc run example-downstream-regular
fi

ジョブのパラメータ

ジョブ名の後に, パラメータ名=値を付けるとスクリプトに渡される.

laminarc queue example foo=bar
#!/usr/bin/bash
if [ "$foo" == "bar" ]; then
   ...
else
   ...
fi

共通処理

/var/lib/laminar/cfg/scriptsがPATHに追加されるためヘルパースクリプトを置いておくと便利です.

まとめ