技術/Linux/RPMコマンドメモ(パッケージ作成など) で簡単ながらパッケージ作成時のTipsをまとめているが、今回はビルドを伴わないパッケージの作成方法について勉強してみた。
今回の「ビルドを伴わないパッケージ」というのは、リポジトリやtarボールから展開して適切な場所にファイル・ディレクトリを配置するだけで良いファイルセットをRPMパッケージにすることを指す。PHPスクリプトや、設定ファイルなどでこのようなケースが該当する。
サンプルを作成してみたので、ポイントとなる箇所を解説していく。
サンプル:
今回の練習環境:
CentOS 6.5 x86_64版 $ rpm --version RPM version 4.8.0 $ rpmbuild --version RPM version 4.8.0
ソース構成:
rpmbuild-demo-without-compilation/ ├── buildrpm.sh ... ビルド時の一時的なtarボールの生成とrpmbuildの実行スクリプト ├── helloworld/ ... 設定ファイルのセットで、これを"/etc"以下にインストールするRPMを作成する │ ├── auto_include_child/ │ │ ├── regular1.txt │ │ └── regular2.txt │ ├── dir_only │ │ └── ignored.txt │ ├── greet.conf │ ├── greet-noreplace.conf │ ├── greet.sh │ ├── p0600.txt │ ├── p0705.txt │ └── regular.txt ├── helloworld.spec ... SPECファイル ├── LICENSE └── README.md
ビルド方法
# yum install rpm-build $ cd /home/msakamoto/work $ git clone git@github.com:msakamoto-sf/rpmbuild-demo-without-compilation.git # 以下はJenkinsなどCI環境からのビルドを意識して、サブシェルによりcdしてから buildrpm.sh を起動する例 $ cd / $ (cd /home/msakamoto/work/rpmbuild-demo-without-compilation && ./buildrpm.sh)
#!/bin/sh WORK_DIR=`pwd` BUILD_NAME=helloworld BUILD_SPEC=${BUILD_NAME}.spec BUILD_TAR=${BUILD_NAME}.tar.gz BUILD_DIR=${WORK_DIR}/rpmbuild BUILD_TAR_PATH=${WORK_DIR}/rpmbuild/SOURCES/${BUILD_TAR} /bin/rm -rf ${BUILD_DIR} # rpmbuildが使用する各種ビルドディレクトリを作成 /bin/mkdir -p ${BUILD_DIR}/{BUILD,RPMS,SOURCES,SPECS,SRPMS} # rpmbuildのためだけの、一時的なtarボールを生成してSOURCESに配置 /bin/tar czf ${BUILD_TAR} ${BUILD_NAME}/ /bin/mv ${BUILD_TAR} ${BUILD_TAR_PATH} # "$HOME/.rpmmacros" に依存せずに rpmbuild を実行 /usr/bin/rpmbuild --define "_topdir ${BUILD_DIR}" -bb ${BUILD_SPEC}
今回のspecファイルとソースツリーについては、以下の記事を参考にさせて頂いております。helloworldのパッケージ名やディレクトリ構成など、丸パクリさせてもらいました。
"Name", "Version", "Release" については難しく無い。"Group"については、可能であれば既に存在するグループ名を指定する方が良いらしい。CentOSであれば、"yum grouplist" でCentOSで利用可能なグループ名の一覧を取得できる。
Name: helloworld Version: 1.0 Release: 1 Group: Security Tools
参考:
"Vendor"は、個人ではなく会社等でパッケージを開発する際は入れておいたほうが良いだろう。"URL", "License", "Summary"はそのまま。"BuildArch" については、今回は単なる設定ファイルのパッケージングなので "noarch" を指定した。
Vendor: Example Company Inc. URL: http://www.example.com/ License: Custom License Summary: Example RPM Plain File Packaging. BuildArch: noarch
ソースの指定で、ここでrpmbuild.shが一時的に生成したtarボール名を指定している。
# use build-time generated tar ball. Source0: %{name}.tar.gz
"BuildRoot"については、最近のRHEL系rpmbuildでは無視されるようだ。RHEL5系以前との互換性のために、一つのシステム上で複数人 or 複数ジョブが同時にビルドしても衝突しないよう、mktempでユニークな一時ファイル名を生成している。なお、今回実験した環境では "rpmbuild/BUILDROOT" というディレクトリが自動的に作成され、それが "%{buildroot}" として参照できていた。
# (only create temporary directory name, for RHEL5 compat environment) # see : http://fedoraproject.org/wiki/Packaging:Guidelines#BuildRoot_tag BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
BuildRootの解説と、最近のrpmbuildではdeprecatedになった話についての参考:
"%install" で指定する、ファイルツリーの展開先。"%{buildroot}" がインストール先のルートディレクトリに相当する。今回は helloworld を "/etc/helloworld" 以下に展開したいため、そのように調整している。
%define INSTALLDIR %{buildroot}/etc/helloworld
パッケージの説明以降は、準備とビルド(今回は何もしない)、仮のインストール、クリーニング処理になる。ファイルコピーについては、tarボール中のファイルパス名と、"%prep"でのファイル展開先との兼ね合いで微調整が必要になる。最後に"%{buildroot}"を削除している。
%description %{summary} %prep %setup -q -n %{name} %build %install rm -rf %{INSTALLDIR} mkdir -p %{INSTALLDIR} cp -Rp * %{INSTALLDIR} %clean #rm -rf %{buildroot} # Avoid Disastarous Damage : http://dev.tapweb.co.jp/2010/12/273 [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
"%files"では、属性の付け方や、"%config"の動きを練習してみた。また、正式にドキュメント化はされていないようだが、"%exclude"により、特定のファイルを除外する方式も試している。"%dir"と組み合わせており、「git向けに空ディレクトリとして、無視ファイル1つだけ入れたディレクトリをリポジトリに登録したが、パッケージインストール時はディレクトリだけを作成して終わりにしたい」というユースケースを想定している。
%files %defattr(-,root,root) /etc/helloworld/regular.txt # auto include child files under the directory /etc/helloworld/auto_include_child %config %attr(0600,root,root) /etc/helloworld/greet.conf %config(noreplace) /etc/helloworld/greet-noreplace.conf %attr(0700,root,root) /etc/helloworld/greet.sh %attr(0600,root,root) /etc/helloworld/p0600.txt %attr(0705,root,root) /etc/helloworld/p0705.txt # directory only %dir %attr(0770,-,-) /etc/helloworld/dir_only %exclude /etc/helloworld/dir_only/ignored.txt
"%files", "%attr"参考:
"%exclude"について:
最後に、pre/post, preun/postun についての練習を入れている。
%pre if [ "$1" = "1" ]; then echo "pre-install script : Initial installation." elif [ "$1" = "2" ]; then echo "pre-install script : Upgrade installation." fi %post if [ "$1" = "1" ]; then echo "post-install script : Initial installation." elif [ "$1" = "2" ]; then echo "post-install script : Upgrade installation." fi %preun if [ "$1" = "0" ] ; then echo "pre-uninstall script : Uninstall operation." elif [ "$1" = "1" ]; then echo "pre-uninstall script : Upgrade uninstallation process." fi %postun if [ "$1" = "0" ] ; then echo "post-uninstall script : Uninstall operation." elif [ "$1" = "1" ]; then echo "post-uninstall script : Upgrade uninstallation process." fi %changelog
RPMの基本
Fedoraからのドキュメント、パッケージングのガイドライン
今回、かなり参考になった記事
JenkinsなどCI環境と組み合わせる場合に参考になりそうな記事
Rubyなどのライブラリから、RPMパッケージをプログラマブルに生成するライブラリ
その他