mockコマンドでrpmをビルドする

2015-12-15 追記

nginxのカスタムrpmをmockでビルドできることを確認してからcoprでビルド・配布する環境を作りました · hnakamur’s blog at githubという記事を書きましたのでそちらもご参照ください。

以下元記事です

Travis CIとcopr.fedoraproject.orgを使ってrpmをビルド・配布するのを試してみた · hnakamur’s blog at githubでrpmを外部のサーバでビルドできるようになりましたが、試行錯誤中はこの手順だと時間がかかりますので、手元の環境でビルドしたいところです。

rpmbuild

私は最近までrpmbuildでrpmをビルドしていました。以下のコマンドでspecファイルの BuildRequires に書いたrpmをまとめてインストールすることが出来ることも最近知りました。

sudo yum-builddep -y specファイルのパス

これだけでも十分便利ですが、1つの環境でいろんなrpmをビルドするような使い方をしていると不満が出てきます。ビルドに必要なパッケージを BuildRequires に書き忘れていても、別のrpmのビルドの際にインストールされていてビルドが通ってしまい気づかない恐れがあるからです。

mock

Mock - FedoraProjectを使えば、chrootでクリーンな環境でrpmをビルドしてくれるので、上記のように BuildRequires に必要なパッケージを書き忘れた場合はビルドエラーになり間違いに気づくことができます。

また、実行環境と異なるCPUアーキテクチャやRHELのバージョン用のrpmもビルドできます。 mock(1): build SRPMs in chroot - Linux man pageによると -r オプションで /etc/mock/<chroot>.cfg<chroot> の部分を指定すればよいそうです。

CentOS 7で /etc/mock を見てみたところ、以下のような環境が用意されていました。

[vagrant@localhost ~]$ ls /etc/mock/
default.cfg            fedora-21-armhfp.cfg   fedora-22-i386.cfg     fedora-23-ppc64.cfg         fedora-rawhide-ppc64le.cfg
epel-5-i386.cfg        fedora-21-i386.cfg     fedora-22-ppc64.cfg    fedora-23-ppc64le.cfg       fedora-rawhide-s390.cfg
epel-5-ppc.cfg         fedora-21-ppc64.cfg    fedora-22-ppc64le.cfg  fedora-23-s390.cfg          fedora-rawhide-s390x.cfg
epel-5-x86_64.cfg      fedora-21-ppc64le.cfg  fedora-22-s390.cfg     fedora-23-s390x.cfg         fedora-rawhide-sparc.cfg
epel-6-i386.cfg        fedora-21-s390.cfg     fedora-22-s390x.cfg    fedora-23-x86_64.cfg        fedora-rawhide-x86_64.cfg
epel-6-ppc64.cfg       fedora-21-s390x.cfg    fedora-22-x86_64.cfg   fedora-rawhide-aarch64.cfg  logging.ini
epel-6-x86_64.cfg      fedora-21-x86_64.cfg   fedora-23-aarch64.cfg  fedora-rawhide-armhfp.cfg   site-defaults.cfg
epel-7-x86_64.cfg      fedora-22-aarch64.cfg  fedora-23-armhfp.cfg   fedora-rawhide-i386.cfg
fedora-21-aarch64.cfg  fedora-22-armhfp.cfg   fedora-23-i386.cfg     fedora-rawhide-ppc64.cfg

Caching in mock 0.8.x and laterを見るとmockの今のバージョンでは mock を実行してchroot環境を作ってyumでダウンロードしたrpmはホスト環境にキャッシュされるそうです。

ですので、複数のrpmをビルドしたり、同じrpmを試行錯誤で何度もビルドする場合に、キャッシュによる高速化が期待できます。

まとめると、mockの利点は以下の2つです。

coprもmockを使用しています

coprでビルドした結果のmockchaing.log.gzを見ると、以下の様な行がありました。

[2015-12-05 11:13:20,751][  INFO][PID:19554] executing: /usr/bin/mockchain -r epel-7-x86_64 -l /var/tmp/mockremote-ZTm5H/build/ -a https://copr-be.cloud.fedoraproject.org/results/hnakamur/nginx/epel-7-x86_64 -a https://copr-be.cloud.fedoraproject.org/results/hnakamur/nginx/epel-7-x86_64/devel -m '--define=copr_username hnakamur' -m '--define=copr_projectname nginx' -m '--define=vendor Fedora Project COPR (hnakamur/nginx)' /tmp/build_package_repo/nginx/nginx-1.9.7-1.el7.ngx.src.rpm

mockchain(1): chain package builder - Linux man pageによると複数のrpmを一括ビルドするためのコマンドだそうです。

mockを使うためのセットアップ

epelを入れればmockはyumでインストール可能です。他にもsrpmを作るためにrpm-buildなどもyumでインストールする必要があるので、Vagrant用とDocker用にそれぞれセットアップ手順をまとめたものを作りました。

Vagrant環境のほうは単に vagrant up で起動して vagrant ssh でログインし、 sudo su - mockbuildmockbuild ユーザになって作業します。

Docker環境でmockを利用する場合、mockがunshareシステムコールを呼ぶので SYS_ADMIN ケーパビリティが必要になります。そこで docker run の際に --cap-add=SYS_ADMIN オプションが必要です。

docker build -t mock .mock という名前でdockerイメージをビルドした場合、 docker run --cap-add=SYS_ADMIN -it mock でbashプロンプトが起動しますので、 su - mockbuildmockbuild ユーザになって作業します。

mockのyumキャッシュを有効活用するには、複数のビルド間に環境を破棄せずに維持したほうが良いです。dockerのほうはbashを抜けると環境が消えてしまうので、もう少しDockerfileを工夫したようが良さそうです。

とりあえず私はVagrantの環境の方を使っています。

mockでのビルド

まずsrpmファイルを作ります。 上記の環境ですと、mockbuild ユーザの /home/mockbuild/rpmbuild/ の下に SPECSSOURCES ディレクトリが作ってありますので、そこにspecファイルやソースを置いて以下のコマンドを実行して作成します。

rpmbuild -bs specファイルのパス

上記の環境では /home/mockbuild/rpmbuild/SRPMS/ にsrpmファイルが生成されます。 その後、以下のようにmockコマンドを実行してビルドします。

mock --rebuild srpmファイルのパス

ビルドで生成されたrpmとsrpmファイルは /var/lib/mock/<chroot>/result/ に置かれます。 また、ビルドの作業ディレクトリは /var/lib/mock/<chroot>/root/builddir/build/ 以下に BUILD, BUILDROOT, RPMS, SOURCES, SPECS, SRPMS ディレクトリが作成されていますので、ビルドが失敗した場合はこの中を見て調査できます。

おわりに

実はMock - FedoraProjectProject Listはしばらく前に存在を知っていたのですが、ググっても情報が少ないしよくわからないのでスルーしていました。今回ついに使ってみたのですが、非常に便利なツールとサービスだということがわかりました。もっと前から使っておけばよかったです。

みなさんもMock - FedoraProjectProject Listを活用して、快適なrpmビルド・配布環境を手に入れましょう!