GeekFactory

int128.hatenablog.com

Jenkinsを用いた継続的RPMビルド

RHEL系を使っていて、yumで取得できないバージョンのパッケージを使いたい場合、一般に以下の選択肢があります:

  1. ディストリビューションSRPMをビルドしてRPMを生成する。
  2. 配布元のtar ballをビルドしてRPMを生成する。
  3. 配布元のtar ballを /usr/local 等にインストールする。
  4. 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

下記のジョブパラメータを設定します。ミラーは適当に選んでください。

タイプ 名前
選択 TARGET http://ftp.jaist.ac.jp/pub/Linux/Fedora/releases/17/Fedora/source/SRPMS/d/distcache-1.4.5-23.src.rpm
http://ftp.jaist.ac.jp/pub/apache/apr/apr-1.4.6.tar.bz2
http://ftp.jaist.ac.jp/pub/apache/apr/apr-util-1.5.1.tar.bz2
http://ftp.jaist.ac.jp/pub/apache/httpd/httpd-2.4.3.tar.bz2

シェルスクリプトを書きます。基本的には前掲のスクリプトでいいのですが、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を参照。