Jenkinsを用いた継続的RPMビルド
RHEL系を使っていて、yumで取得できないバージョンのパッケージを使いたい場合、一般に以下の選択肢があります:
- 他ディストリビューションのSRPMをビルドしてRPMを生成する。
- 配布元のtar ballをビルドしてRPMを生成する。
- 配布元のtar ballを /usr/local 等にインストールする。
- Gentooに乗り換える。
このようなケースでは、パッケージのライフサイクルに合わせて誰がどのように運用していくか、担当者の頭を悩ませることになります。構築手順が後で分からなくなると悲惨です。そのための対策として、構築手順書を用意したり、バージョンアップ用のスクリプトを書いたりすると思います。
本稿では、対策の一つとしてJenkinsによる自動化を考えてみます。ワンクリックのRPMビルドが可能になることで、yumのようなきめ細かいバージョンアップも現実的になります。また、運用担当者の負担が減るだけでなく、手順を明文化して残す動機付けにもなります。
ビルドジョブの設定
Jenkinsで新しいジョブを作成しましょう。
ジョブパラメータでビルドしたいtar ballやSRPMを指定します。選択肢にしておくとよいでしょう。
タイプ | 名前 | 値 |
---|---|---|
選択 | TARGET | http://www.example.com/something-1.2.3.src.rpm |
以下のシェルスクリプトを実行するように設定します。
topdir="${WORKSPACE}/rpmbuild" rpmdir="${topdir}/RPMS/$(uname -m)" echo "%_topdir ${topdir}" > "${HOME}/.rpmmacros" case "${TARGET}" in *.src.rpm) curl -O "${TARGET}" && rpmbuild --rebuild "${TARGET##*/}";; *.tar.bz2) curl -O "${TARGET}" && rpmbuild -tb "${TARGET##*/}";; *) echo 'environment variable TARGET must be set.'; exit 1;; esac
ジョブを実行すると、実行ノードの ${WORKSPACE}/rpmbuild/RPMS にRPMが出力されます。Jenkinsのワークスペース画面からも確認できます。
設定例
例として Apache httpd 2.4 をビルドしてみます。配布されているtar ballにspecファイルが同梱されているため、rpmbuildコマンドでそのままビルドできます。依存関係を含めると以下のパッケージが必要です。
- distcache
- apr
- apr-util
- httpd
下記のジョブパラメータを設定します。ミラーは適当に選んでください。
シェルスクリプトを書きます。基本的には前掲のスクリプトでいいのですが、httpd-2.4.3に限ってはパッチ*1を当てています。おそらく次のリリースでは修正されているはずです。
(7/25追記) httpd-2.4.6のパッチを追記しました。
topdir="${WORKSPACE}/rpmbuild" rpmdir="${topdir}/RPMS/$(uname -m)" echo "%_topdir ${topdir}" > "${HOME}/.rpmmacros" case "${TARGET}" in */httpd-2.4.3.tar.bz2) # patch for httpd-2.4.3 tarball="${TARGET##*/}" module="${tarball%.tar.*}" curl -O "${TARGET}" tar jxf "${tarball}" sed -e 's,%{epoch}:,,g' -i "${module}/httpd.spec" tar jcf "${tarball}" "${module}" rpmbuild -tb "${tarball}" ;; */httpd-2.4.6.tar.bz2) tarball="${TARGET##*/}" module="${tarball%.tar.*}" curl -O "${TARGET}" tar jxf "${tarball}" patch "${module}/httpd.spec" <<\EOF 384a385 > %{_libdir}/httpd/modules/mod_proxy_wstunnel.so EOF tar jcf "${tarball}" "${module}" rpmbuild -tb "${tarball}" ;; *.src.rpm) curl -O "${TARGET}" && rpmbuild --rebuild "${TARGET##*/}";; *.tar.bz2) curl -O "${TARGET}" && rpmbuild -tb "${TARGET##*/}";; *) echo 'environment variable TARGET must be set.'; exit 1;; esac
参考までにJenkinsの設定画面はこんな感じです。
ポイント
RPMのビルドは多くの依存関係を必要とします。ジョブの実行結果を見ながらyum installで追加していくとよいでしょう。最初のうちはJenkinsが真っ赤になると思いますが、めげずに頑張ってください。
パイプラインを組んで、ビルドだけでなくインストールまで実行してもよいでしょう。運用プロセスに合わせて設計してみてください。
*1:SVN r1418720を参照。