注: FedoraやCentOSのRPMパッケージャーが書いた文章ではありません。FedoraやCentOSのRPMパッケージメンテナになりたい方はFedoraやCentOSが公式に配布している文書の方をお勧めします。例えば、How to create an RPM package - FedoraProjectという文書があります。
Debianパッケージの作り方と公開方法: groongaを例にしてのRPM版のような内容です。
ここでは、迷惑メール対策ソフトウェアmilter managerを例にしてDebian GNU/Linux上でCentOS 5.4向けのRPMパッケージを作成し、それを提供するYumリポジトリを作成・公開する方法を紹介します。RPMパッケージの作成では、1つのspecファイルから複数のパッケージを作成します。この方法は、ライブラリを提供するソフトウェアの場合に多く用いられます。
また、Yumリポジトリを登録するRPMも作成します。そのため、ユーザには以下のようにYumリポジトリを登録してもらうことになります。
Yumリポジトリを登録:
% sudo rpm -Uvh http://milter-manager.sourceforge.net/centos/5/milter-manager-repository-1.0.0-0.noarch.rpm
インストール:
% sudo yum install -y milter-manager
ここで紹介する方法を自動化するスクリプト群はmilter managerのリポジトリで公開されています。ここで紹介する方法でRPMパッケージ・Yumリポジトリを作成・公開する場合は参考にしてください。
それでは、まずはパッケージの作り方です。
パッケージの作り方
RPMパッケージを作るためには.specを作ります。ここでは、複数のパッケージを生成する.specを作成するので、まず、どれをどのパッケージにいれるかを検討します。
構成
milter managerはmilterプロトコルを実装したライブラリ、それを利用したmilter管理アプリケーション、ユーティリティツールで構成されています。この場合、以下のように複数のパッケージに分解することが多いようです。
- libXXX: ライブラリを使用しているソフトウェアを実行するために必要なファイルを提供するパッケージ。/usr/lib/libXXX.soなどを提供する。
- libXXX-devel: ライブラリを使用しているソフトウェアをビルドするために必要なファイルを提供するパッケージ。/usr/include/XXX/*.hなどを提供することが多い。libXXXに依存する。
- XXX: (ライブラリではなく)コマンドを提供するパッケージ。libXXXに依存する。
milter managerの場合は以下のパッケージを作成することとします。
- libmilter-toolkit: /usr/lib/libmilter-client.soなどを提供する。
- libmilter-toolkit-devel: /usr/include/milter-manager/milter/client.hなどを提供。
- libmilter-compatible: libmilterとABI互換の/usr/lib/libmilter.soを提供する。
- libmilter-compatible-devel: libmilterとAPI互換の/usr/include/milter-manager/libmilter/*.hを提供する。
- milter-manager: milter-managerコマンドを提供する。
- milter-manager-munin-plugin: milter managerの統計情報を収集するmunin-nodeのプラグインを提供する。
雛形
複数のパッケージを作成する.specは以下のような内容になります。簡単ですね、とは言えないくらいの長さです1。
Summary: 簡単な説明
Name: (メイン)パッケージ名(「milter-manager」など)
Version: バージョン番号(「1.5.0」など)
Release: リリースバージョン(最初は「0{?dist}」にしておけばよい)
License: ライセンス(「GPLv3+」など)
URL: ソフトウェアのサイトのURL
(「http://milter-manager.sourceforge.net/」など)
Group: (メイン)パッケージが属するグループ
(「System Environment/Daemons」など。
「/usr/share/doc/rpm/GROUPS」に一覧がある。)
Source: ソースのアーカイブのURL
(「http://downloads.sourceforge.net/milter-manager/milter-manager-1.5.0.tar.gz」など)
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-%(%{__id_u} -n)
(常に↑でOK)
BuildRequires: ビルドに必要なパッケージ
BuildRequires: 必要な分だけ書く
Requires: 動作に必要なパッケージ
Requires: 必要な分だけ書く
%description
詳細なパッケージの説明。複数行になってもOK。
% package -n サブパッケージ名
(「-n」をつけないと「『パッケージ名』-『サブパッケージ名』」
というパッケージ名になるので、「libXXX」というパッケージ名を
つけるときは「-n」をつけないといけない)
Summary: サブパッケージの簡単な説明
Group: サブパッケージの属するグループ
% description -n サブパッケージ名
(「-n」の意味は「%package」と同じ)
詳細なサブパッケージの説明。複数行になってもOK。
%prep
%setup -q
%build
%configure オプション
(「--with-default-effective-user=milter-manager」など)
make %{?_smp_mflags}
% install
rm -rf %{buildroot}
make install DESTDIR=%{buildroot}
%clean
rm -rf %{buildroot}
%files
%defattr(-, root, root, -)
(メイン)パッケージに含めるファイルを指定。
%files -n サブパッケージ名
%defattr(-, root, root, -)
サブパッケージに含めるファイルを指定。
%changelog
* 日付 名前 <メールアドレス>
- (バージョン番号-リリース番号)
- new upstream release
1つの.specで1つのパッケージを作る場合は%package -n サブパッケージ名
、%description -n サブパッケージ名
、%files -n サブパッケージ名
がなくなるだけで、基本的な記述は変わりません。
milter managerの場合は以下のような.specになっています。%pre
やpost
などが増えていますが、これらは、それぞれインストール前・インストール後に実行するシェルスクリプトを指定しているだけです。
そこそこ長いので、詳細に興味がない場合は読み飛ばしてください。
Summary: A milter to use milters effectively
Name: milter-manager
Version: 1.5.0
Release: 11%{?dist}
License: GPLv3+, LGPL3+, AGPL3+, GFDL, Public Domain
URL: http://milter-manager.sourceforge.net/
Group: System Environment/Daemons
Source: http://downloads.sourceforge.net/milter-manager/milter-manager-1.5.0.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-%(%{__id_u} -n)
BuildRequires: intltool
BuildRequires: gettext
BuildRequires: gcc
BuildRequires: make
BuildRequires: glib2-devel
BuildRequires: ruby
BuildRequires: ruby-devel
Requires: glib2
Requires: ruby
Requires: libmilter-toolkit = %{version}-%{release}
Requires(pre): /usr/bin/getent, /usr/sbin/useradd
Requires(pre): /usr/bin/id, /usr/sbin/groupadd
Requires(post): /sbin/chkconfig
Requires(preun): /sbin/service, /sbin/chkconfig
Requires(postun): /sbin/service, /sbin/chkconfig, /usr/sbin/userdel
%description
milter manager administrates milters instead of MTA to reduce milter
administration cost and combine milters flexibly.
%package -n libmilter-toolkit
Summary: A milter protocol library
Group: System Environment/Libraries
%description -n libmilter-toolkit
Both of client-side and server-side milter protocol are implemented.
This package contains the library files required for running services
built using libmilter-toolkit.
%package -n libmilter-toolkit-devel
Summary: Development files for libmilter-toolkit
Group: Development/Libraries
Requires: libmilter-toolkit = %{version}-%{release}
%description -n libmilter-toolkit-devel
This package contains the headers, and other support files
required for developing applications against libmilter-toolkit.
%package -n libmilter-compatible
Summary: libmilter API and ABI compatible milter library
Group: System Environment/Libraries
Requires: libmilter-toolkit = %{version}-%{release}
%description -n libmilter-compatible
A libmilter API and ABI compatible library based on libmilter-toolkit.
This package contains the library files required for running services
built using Sendmail libmilter or libmilter-compatible.
%package -n libmilter-compatible-devel
Summary: Development files for libmilter-compatible
Group: Development/Libraries
Requires: libmilter-compatible = %{version}-%{release}
Requires: libmilter-toolkit-devel = %{version}-%{release}
%description -n libmilter-compatible-devel
This package contains the headers, and other support files
required for developing applications against libmilter-compatible.
%package -n milter-manager-munin-plugin
Summary: Munin plugin for milter manager
Group: System Environment/Libraries
Requires: milter-manager = %{version}-%{release}
Requires: munin-node
%description -n milter-manager-munin-plugin
This package contains the munin plugin for munin-node.
%prep
%setup -q
%build
%configure \
--with-default-effective-user=milter-manager \
--with-default-effective-group=milter-manager \
--with-default-socket-group=smmsp \
--with-default-pid-file=/var/run/milter-manager/milter-manager.pid \
--with-default-connection-spec=unix:/var/run/milter-manager/milter-manager.sock
make %{?_smp_mflags}
%install
rm -rf %{buildroot}
make install DESTDIR=%{buildroot}
mkdir -p %{buildroot}%{_initrddir}
install -m 755 data/init.d/redhat/milter-manager %{buildroot}%{_initrddir}/milter-manager
mkdir -p %{buildroot}%{_sysconfdir}/sysconfig
install -m 644 data/init.d/redhat/sysconfig/milter-manager %{buildroot}%{_sysconfdir}/sysconfig/milter-manager
mkdir -p %{buildroot}%{_sysconfdir}/cron.d
install -m 600 data/cron.d/redhat/milter-manager-log %{buildroot}%{_sysconfdir}/cron.d/milter-manager-log
mkdir -p %{buildroot}%{_localstatedir}/run/milter-manager/
mkdir -p %{buildroot}%{_sysconfdir}/httpd/conf.d/
cat <<EOC > %{buildroot}%{_sysconfdir}/httpd/conf.d/milter-manager-log.conf
Alias /milter-manager-log/ /var/lib/milter-manager/public_html/log/
EOC
mv %{buildroot}%{_datadir}/milter-manager/munin/ %{buildroot}%{_datadir}/
mkdir -p %{buildroot}%{_sysconfdir}/munin/plugin-conf.d/
cat <<EOC > %{buildroot}%{_sysconfdir}/munin/plugin-conf.d/milter-manager
[milter_manager_*]
user milter-manager
env.logdir /var/lib/milter-manager/public_html/log
EOC
%clean
rm -rf %{buildroot}
%pre
if ! /usr/bin/getent group milter-manager &>/dev/null; then
/usr/sbin/groupadd -r milter-manager || \
%logmsg "Unexpected error adding group \"milter-manager\". Aborting installation."
fi
if ! /usr/bin/id milter-manager &>/dev/null; then
/usr/sbin/useradd -r -s /sbin/nologin -c 'milter manager' \
-d %{_localstatedir}/lib/milter-manager --create-home \
-g milter-manager milter-manager || \
%logmsg "Unexpected error adding user \"milter-manager\". Aborting installation."
fi
%post
/sbin/chkconfig --add milter-manager
/bin/mkdir -p /var/run/milter-manager
/bin/chown -R milter-manager:milter-manager /var/run/milter-manager
%post -n milter-manager-munin-plugin
/usr/sbin/munin-node-configure --shell | \
grep -e '\(milter_manager_\|\(postfix\|sendmail\)_processes\)' | \
sh
[ -f /var/lock/subsys/munin-node ] && \
/sbin/service munin-node restart > /dev/null 2>&1
:
%preun
if [ $1 -eq 0 ] ; then
/sbin/service milter-manager stop > /dev/null 2>&1
/sbin/chkconfig --del milter-manager
fi
%postun
if [ $1 -ge 1 ] ; then
/sbin/service milter-manager condrestart > /dev/null 2>&1
fi
if [ $1 -eq 0 ]; then
/usr/sbin/userdel -r milter-manager || \
%logmsg "User \"milter-manager\" could not be deleted."
fi
%postun -n milter-manager-munin-plugin
if [ $1 -eq 0 ]; then
rm %{_sysconfdir}/munin/plugins/milter_manager_* > /dev/null 2>&1
rm %{_sysconfdir}/munin/plugins/postfix_processes > /dev/null 2>&1
rm %{_sysconfdir}/munin/plugins/sendmail_processes > /dev/null 2>&1
[ -f /var/lock/subsys/munin-node ] && \
/sbin/service munin-node restart > /dev/null 2>&1
:
fi
%files
%defattr(-, root, root, -)
%doc ChangeLog ChangeLog.toolkit README README.ja NEWS NEWS.ja TODO
%doc %{_datadir}/milter-manager/license/
%doc %{_datadir}/gtk-doc/html/milter-manager/
%{_bindir}/milter-manager-log-analyzer
%{_sbindir}/milter-manager
%{_includedir}/milter-manager/milter/manager.h
%{_includedir}/milter-manager/milter/manager/
%{_libdir}/libmilter-manager.*
%{_libdir}/milter-manager/binding/
%{_libdir}/milter-manager/module/
%{_libdir}/pkgconfig/milter-manager.pc
%{_mandir}/man1/milter-manager.*
%{_mandir}/man1/milter-manager-log-analyzer.*
%{_mandir}/ja/man1/milter-manager.*
%{_mandir}/ja/man1/milter-manager-log-analyzer.*
%{_initrddir}/milter-manager
%{_datadir}/milter-manager/admin/
%{_sysconfdir}/milter-manager/cron.d/
%{_sysconfdir}/milter-manager/init.d/
%{_sysconfdir}/milter-manager/rc.d/
%{_sysconfdir}/cron.d/
%config %{_sysconfdir}/sysconfig/milter-manager
%config %{_sysconfdir}/milter-manager/milter-manager.conf
%config %{_sysconfdir}/milter-manager/defaults/
%config %{_sysconfdir}/milter-manager/applicable-conditions/
%config %{_sysconfdir}/httpd/conf.d/milter-manager-log.conf
%defattr(-, milter-manager, milter-manager, 0755)
%dir %{_localstatedir}/run/milter-manager/
%files -n libmilter-toolkit
%defattr(-,root,root)
%doc ChangeLog ChangeLog.toolkit README README.ja NEWS NEWS.ja TODO
%doc %{_datadir}/milter-manager/license/
%{_bindir}/milter-test-client
%{_bindir}/milter-test-server
%{_bindir}/milter-performance-check
%{_libdir}/libmilter-core.so.*
%{_libdir}/libmilter-client.so.*
%{_libdir}/libmilter-server.so.*
%{_mandir}/man1/milter-test-client.*
%{_mandir}/man1/milter-test-server.*
%{_mandir}/man1/milter-performance-check.*
%{_mandir}/ja/man1/milter-test-client.*
%{_mandir}/ja/man1/milter-test-server.*
%{_mandir}/ja/man1/milter-performance-check.*
%files -n libmilter-toolkit-devel
%defattr(-,root,root)
%doc ChangeLog ChangeLog.toolkit README README.ja NEWS NEWS.ja TODO
%doc %{_datadir}/milter-manager/license/
%doc %{_datadir}/gtk-doc/html/milter-manager/
%{_includedir}/milter-manager/milter/core.h
%{_includedir}/milter-manager/milter/core/
%{_includedir}/milter-manager/milter/client.h
%{_includedir}/milter-manager/milter/client/
%{_includedir}/milter-manager/milter/server.h
%{_includedir}/milter-manager/milter/server/
%{_libdir}/libmilter-core.so
%{_libdir}/libmilter-core.la
%{_libdir}/libmilter-client.so
%{_libdir}/libmilter-client.la
%{_libdir}/libmilter-server.so
%{_libdir}/libmilter-server.la
%{_libdir}/pkgconfig/milter-core.pc
%{_libdir}/pkgconfig/milter-client.pc
%{_libdir}/pkgconfig/milter-server.pc
%files -n libmilter-compatible
%defattr(-,root,root)
%doc ChangeLog ChangeLog.toolkit README README.ja NEWS NEWS.ja TODO
%doc %{_datadir}/milter-manager/license/
%{_libdir}/milter-manager/libmilter.so.*
%files -n libmilter-compatible-devel
%defattr(-,root,root)
%doc ChangeLog ChangeLog.toolkit README README.ja NEWS NEWS.ja TODO
%doc %{_datadir}/milter-manager/license/
%doc %{_datadir}/gtk-doc/html/milter-manager/
%{_includedir}/milter-manager/libmilter/
%{_libdir}/milter-manager/libmilter.so
%{_libdir}/milter-manager/libmilter.la
%{_libdir}/pkgconfig/libmilter.pc
%files -n milter-manager-munin-plugin
%defattr(-,root,root)
%doc ChangeLog ChangeLog.toolkit README README.ja NEWS NEWS.ja TODO
%doc %{_datadir}/milter-manager/license/
%{_datadir}/munin/
%config %{_sysconfdir}/munin/plugin-conf.d/
%changelog
* Thu Feb 17 2010 Kouhei Sutou <kou@clear-code.com>
- (1.5.0-11)
- new upstream release
* Thu Oct 29 2009 Kouhei Sutou <kou@clear-code.com>
- (1.4.1-0)
- new upstream release
* Thu Oct 13 2009 Kouhei Sutou <kou@clear-code.com>
- (1.4.0-0)
- new upstream release
* Wed Sep 16 2009 Kouhei Sutou <kou@clear-code.com>
- (1.3.1-0)
- new upstream release
* Wed Aug 12 2009 Kouhei Sutou <kou@clear-code.com>
- (1.3.0-0)
- new upstream release
* Fri Jul 17 2009 Kouhei Sutou <kou@clear-code.com>
- (1.2.0-0)
- new upstream release
* Fri Jul 03 2009 Kouhei Sutou <kou@clear-code.com>
- (1.1.1-0)
- new upstream release
* Tue Jun 02 2009 Kouhei Sutou <kou@clear-code.com>
- (1.1.0-0)
- initial 1.1.x development seriese release
* Thu Apr 16 2009 Kouhei Sutou <kou@clear-code.com>
- (1.0.0-1)
- initial stable release
ビルド: rinse
Debian GNU/Linux上でCentOS用のRPMパッケージをビルドすることは茨の道です。そこで、CentOS用のchroot環境を作って、そこでビルドすることにします。こうすることで、CentOSの実機がなくてもビルドできる上に、きれいな環境でビルドすることもできます。
Debian GNU/LinuxやUbuntuのchroot環境を作るにはdebootstrapが便利です。CentOSやFedoraのchroot環境を作るにはrinseが便利です。
/var/lib/chroot/centos-i386/
以下にCentOS 5.4 i386用のchroot環境を構築するには以下のようにします。
% sudo aptitude install -y rinse
% sudo mkdir -p /var/lib/chroot/centos-i386/etc/rpm/
% sudo sh -c "echo i386-centos-linux > /var/lib/chroot/centos-i386/etc/rpm/platform"
% sudo rinse --arch i386 --distribution centos-5 --directory /var/lib/chroot/centos-i386/
/etc/fstabに以下を追記:
/dev /var/lib/chroot/centos-i386/dev none bind 0 0
devpts-chroot /var/lib/chroot/centos-i386/dev/pts devpts defaults 0 0
proc-chroot /var/lib/chroot/centos-i386/proc proc defaults 0 0
本質的な部分はsudo rinse ...
だけです。sudo rinse ...
の前にあるRPMパッケージで利用するプラットフォームを指定している箇所はrinseのバグを回避するためです2。これがないとamd64のDebian GNU/Linux環境でi386のCentOS環境を作成することができません。
/etc/fstabへの追記は、再起動する度にmountしなおすのが面倒だからです。
この作業はbuild-in-chroot.shの中で自動化されています。
ビルド: chroot
CentOSのchroot環境ができたら、その環境にビルド専用アカウントを作成し、そのユーザでビルドします。ここで紹介する作業はbuild-rpm.shの中で自動化されています。ここでは、その中の一部を説明します。
まず、ビルド用ユーザが存在しない場合はユーザを作成します。
USER_NAME=milter-manager-build
if ! id $USER_NAME >/dev/null 2>&1; then
useradd -m $USER_NAME
fi
次に、そのビルド用ユーザが実行するビルドスクリプトを作成します。.tar.gzや.specなどのビルドに必要なファイルはchroot環境の/tmp/以下(/var/lib/chroot/centos-i386/tmp/以下)に事前にコピーしておきます。それぞれの処理内容はコメントとして説明しています。
BUILD_SCRIPT=/tmp/build-milter-manager.sh
VERSION=`cat /tmp/milter-manager-version`
cat <<EOF > $BUILD_SCRIPT
#!/bin/sh
# RPMパッケージのビルドは~/rpm/以下で行う。
if [ ! -f ~/.rpmmacros ]; then
cat <<EOM > ~/.rpmmacros
%_topdir \$HOME/rpm
EOM
fi
# RPMパッケージ作成に必要なディレクトリを作成。
# rpmdevtoolsパッケージに含まれているrpmdev-setuptreeコマンド
# でも同様のことができるよう。
mkdir -p rpm/SOURCES
mkdir -p rpm/SPECS
mkdir -p rpm/BUILD
mkdir -p rpm/RPMS
mkdir -p rpm/SRPMS
# ソースと.specを配置。
cp /tmp/milter-manager-$VERSION.tar.gz rpm/SOURCES/
cp /tmp/milter-manager.spec rpm/SPECS/
# RPMパッケージ作成。
rpmbuild -ba rpm/SPECS/milter-manager.spec
EOF
このビルドスクリプトをビルド用ユーザで実行します。
chmod +x $BUILD_SCRIPT
su - $USER_NAME $BUILD_SCRIPT
ビルドが成功するとビルド用ユーザの~/rpm/RPMS/i386/以下にRPMパッケージができます3。
RPMパッケージができたら、それらに署名をします。
署名
RPMでは、パッケージに署名することによりパッケージ作成者のなりすましを防止することができます。署名の検証を無効にすることもできるので、署名なしのRPMパッケージでもYumリポジトリで公開・インストールすることはできますが、よほどの理由がない場合は署名をするべきでしょう。
パッケージへの署名はパッケージ作成時にも作成後にも行うことができます。パッケージ作成後に行う場合はrpm
コマンドの--resign
オプションを使います。署名する鍵は_gpg_name
で指定します。
% rpm -D "_gpg_name Kouhei Sutou <kou@clear-code.com>" --resign XXX.rpm
これをそれぞれの.rpmに対して行います。
RPMパッケージに署名したら、署名済みRPM使ってYumリポジトリを作ります。
Yumリポジトリの作成
milter managerは安定版と開発版の2つのリリースラインがあります。そのため、以下のようなディレクトリ構成でYumリポジトリも2つ作ります。下の図のdevelopmentとstableがそれぞれYumリポジトリになります。各YumリポジトリはSRPMS, i386, x86_64ディレクトリを持ち、その下にビルドしたRPMパッケージを配置します。
.
+--- centos/
+--- 5/
+--- development
| +--- SRPMS/
| | +--- milter-manager-1.5.0-0.src.rpm
| | +--- ...
| +--- i386/
| | +--- CentOS/
| | +--- milter-manager-1.5.0-0.i386.rpm
| | +--- ...
| +--- x86_64/
| +--- CentOS/
| +--- milter-manager-1.5.0-0.x86_64.rpm
| +--- ...
+--- stable
+--- SRPMS/
| +--- milter-manager-1.4.1-0.src.rpm
| +--- ...
+--- i386/
| +--- CentOS/
| +--- milter-manager-1.4.1-0.i386.rpm
| +--- ...
+--- x86_64/
+--- CentOS/
+--- milter-manager-1.4.1-0.x86_64.rpm
+--- ...
このように.rpmを配置したらSRPMS, i386, x86_64のそれぞれのディレクトリに対してcreaterepo
コマンドを実行します。この作業はupdate-repository.shで自動化されています。
for dir in centos/5/*/*; do
createrepo $dir
done
createrepo
コマンドを実行するとそれぞれのディレクトリの下にrepodataというディレクトリが作成され、パッケージの情報が格納されます。
これでYumリポジトリは完成です。HTTPでアクセスできるところにアップロードしてください。
http://milter-manager.sourceforge.net/centos/以下でアクセスできるところにアップロードしたとすると、Yumのリポジトリ指定は以下のようになります。
/etc/yum.repos.d/milter-manager.repo:
[milter-manager]
name=milter manager for CentOS-$releasever
baseurl=http://milter-manager.sourceforge.net/centos/$releasever/stable/$basearch/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-milter-manager
gpgkeyはRPMに署名した時に使ったキーの公開鍵が入ったファイルを指定します。公開鍵は以下のコマンドで出力できます。
% gpg --export --armor "Kouhei Sutou <kou@clear-code.com>"
これを/etc/pki/rpm-gpg/RPM-GPG-KEY-milter-managerに置くことになります。
つまり、Yumリポジトリを登録するためには以下の作業が必要になります。
-
/etc/yum.repos.d/milter-manager.repoの作成
-
公開鍵の配置
2段階にわかれているので面倒ですね。Yumリポジトリ登録の手間を軽減するために、「Yumリポジトリを登録するRPMパッケージ」を作りましょう。
Yumリポジトリ登録RPMの作成
ここで作成する「Yumリポジトリを登録するRPMパッケージ」はbuild-repository-rpm.shで自動化されています。
Yumリポジトリ登録に必要なものは「リポジトリを指定するファイル」と「RPMパッケージを署名している公開鍵」の2つです。それらをアーカイブした.tar.gzがソースのパッケージを作成します。
% tar cvzf milter-manager-repository.tar.gz milter-manager.repo RPM-GPG-KEY-milter-manager
.specはこのようになります。
Summary: milter manager RPM repository configuration
Name: milter-manager-repository
Version: 1.0.0
Release: 0
License: GPLv3+
URL: http://milter-manager.sourceforge.net/
Source: milter-manager-repository.tar.gz
Group: System Environment/Base
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-%(%{__id_u} -n)
BuildArchitectures: noarch
%description
milter manager RPM repository configuration.
%prep
%setup -c
%build
%install
%{__rm} -rf %{buildroot}
%{__install} -Dp -m0644 RPM-GPG-KEY-milter-manager %{buildroot}%{_sysconfdir}/pki/rpm-gpg/RPM-GPG-KEY-milter-manager
%{__install} -Dp -m0644 milter-manager.repo %{buildroot}%{_sysconfdir}/yum.repos.d/milter-manager.repo
%clean
%{__rm} -rf %{buildroot}
%post
rpm -q gpg-pubkey-1c837f31-4a2b9c3f &>/dev/null || \
rpm --import %{_sysconfdir}/pki/rpm-gpg/RPM-GPG-KEY-milter-manager
%files
%defattr(-, root, root, 0755)
%doc *
%pubkey RPM-GPG-KEY-milter-manager
%dir %{_sysconfdir}/yum.repos.d/
%config(noreplace) %{_sysconfdir}/yum.repos.d/milter-manager.repo
%dir %{_sysconfdir}/pki/rpm-gpg/
%{_sysconfdir}/pki/rpm-gpg/RPM-GPG-KEY-milter-manager
%changelog
* Sat Feb 06 2010 Kouhei Sutou <kou@clear-code.com>
- (1.0.0-0)
- Initial package.
大事な部分はBuildArchitectures
と%post
の部分です。
このYumリポジトリ登録RPMはプラットフォームに関係なく使えるのでnoarch
を指定しています。
%post
ではRPMにも公開鍵を登録しています。
%post
rpm -q gpg-pubkey-1c837f31-4a2b9c3f &>/dev/null || \
rpm --import %{_sysconfdir}/pki/rpm-gpg/RPM-GPG-KEY-milter-manager
このYumリポジトリ登録RPMはDebian GNU/Linux上でも作成できます。作成方法はCentOS上での方法と同じです。
% echo "%_topdir $HOME/rpm" > ~/.rpmmacros
% mkdir -p ~/rpm/{SOURCES,SPECS,BUILD,RPMS,SRPMS}
% cp milter-manager-repository.tar.gz ~/rpm/SOURCES/
% cp milter-manager-repository.spec ~/rpm/SPECS/
% rpmbuild -ba ~/rpm/SPECS/milter-manager-repository.spec
これで、/rpm/RPMS/noarch/以下に.rpmができ、/rpm/SRPMS/以下に.src.rpmができます。
ここで作成したRPMが冒頭で紹介したRPMです。このRPMを使うことで以下のようにパッケージをインストールできるのでしたね。
% sudo rpm -Uvh http://milter-manager.sourceforge.net/centos/5/milter-manager-repository-1.0.0-0.noarch.rpm
% sudo yum install -y milter-manager
Yumリポジトリの公開
ここまできたら、後はアクセスできる場所にアップロードするだけです。SourceForge.netではrsyncでアップロードできます。今回はhttp://milter-manager.sourceforge.net/centos/以下で公開したいので以下のようなコマンドになります。
% rsync -avz --exclude .gitignore centos/ \
ktou,milter-manager@web.sourceforge.net:/home/groups/m/mi/milter-manager/htdocs/centos
rsyncではパスの最後の「/」の有無に注意してください。
まとめ
以上がRPMパッケージの作成と作成したRPMパッケージをYumリポジトリで公開する手順です。これら一連の手順を自動化したものはmilter managerのリポジトリで公開しています。読んでみてわかる通り、手順が多く、バージョンが上がる毎に手動で作業するのは大変です。簡単にバージョンアップに対応できるよう、自動化しておきましょう。