概要
RPMパッケージを自作する手順です。
Go言語で、hello, world
と表示するだけのプログラムをインストールします。
環境
- CentOS 6 or 7
Installation
rpmパッケージを作成するための環境を作成します。
$ sudo yum install -y rpm-build
$ sudo yum groupinstall -y 'Development tools'
Goでソース作成
以下を参考に、Go言語の環境と、helloを表示するプログラムを作成してください。
rpmdev-setuptreeのインストール
rpmdev-setuptreeを使うと、コマンド1つでrpmの開発環境を作ることができます。
$ sudo yum install -y rpmdevtools yum-utils
rpmdev-setuptree実行
$ rpmdev-setuptree
すると、以下のディレクトリが自動生成されます。
$ ls -1 ~/rpmbuild/
BUILD
RPMS
SOURCES
SPECS
SRPMS
GOのパッケージを移動
GOのソースをtarで固めたら、生成されたディレクトリにtarファイルを移動します。
$ tar czvf hello-1.0.tar.gz hello
$ cp hello-1.0.tar.gz ~/rpmbuild/SOURCES
rpmdev-setuptreeのtopdirを変更する場合
デフォルトでは、~/rpmbuildが開発ディレクトリとなっています。
$ rpmbuild --showrc | grep _topdir
-14: _topdir %(echo $HOME)/rpmbuild
変更する場合は、~/.rpmmacrosの%_topdir %(echo $HOME)/rpmbuild
のパスを変更します。
以下は/usr/src/rpmbuild/
になるように変更する例です。
-%_topdir %(echo $HOME)/rpmbuild
+%_topdir %{_usrsrc}/rpmbuild
%_smp_mflags %( \
[ -z "$RPM_BUILD_NCPUS" ] \\\
&& RPM_BUILD_NCPUS="`/usr/bin/nproc 2>/dev/null || \\\
/usr/bin/getconf _NPROCESSORS_ONLN`"; \\\
if [ "$RPM_BUILD_NCPUS" -gt 16 ]; then \\\
echo "-j16"; \\\
elif [ "$RPM_BUILD_NCPUS" -gt 3 ]; then \\\
echo "-j$RPM_BUILD_NCPUS"; \\\
else \\\
echo "-j3"; \\\
fi )
%__arch_install_post \
[ "%{buildarch}" = "noarch" ] || QA_CHECK_RPATHS=1 ; \
case "${QA_CHECK_RPATHS:-}" in [1yY]*) /usr/lib/rpm/check-rpaths ;; esac \
/usr/lib/rpm/check-buildroot
変更されたことを確認
$ rpmbuild --showrc | grep _topdir
-14: _topdir %{_usrsrc}/rpmbuild
これでrpmdev-setuptreeを実行すると、/usr/src/rpmbuild/
が生成されます。
$ rpmdev-setuptree
$ ls -1 /usr/src/rpmbuild/
BUILD
RPMS
SOURCES
SPECS
SRPMS
SPEC
以降、/root/rpmbuild/をtopディレクトリとしている前提とします。
rpmの定義ファイルとなる、.spec
ファイルを作成します。
$ vi /root/rpmbuild/SPECS/hello.spec
%define name hello
%define version 1.0
%define unmangled_version 1.0
%define release 1
%define _binaries_in_noarch_packages_terminate_build 0
Summary: sample hello world program
Name: %{name}
Version: %{version}
Release: %{release}
License: MIT
Source0: %{name}-%{unmangled_version}.tar.gz
Group: Applications/File
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
Prefix: %{_prefix}
BuildArch: noarch
%define INSTALLDIR %{buildroot}/usr/local/bin
%description
This is a sample program to learn how to make a rpm package.
%prep
rm -rf ${RPM_BUILD_ROOT}
%build
%install
rm -rf %{INSTALLDIR}
mkdir -p %{INSTALLDIR}
tar -C %{INSTALLDIR} -xzf /root/rpmbuild/SOURCES/%{name}-%{unmangled_version}.tar.gz
%clean
rm -rf %{buildroot}
%files
/usr/local/bin
%defattr(-,root,root)
インストール除外したいファイル、ディレクトリの指定方法
/optにパッケージをインストールした場合の例。
%{buildroot}より下から指定する。
ファイルの場合
%files
/opt
%defattr(-,root,root)
%exclude /opt/appname/.gitignore
アスタリスクも可能
%exclude /opt/appname/.git/*
ディレクトリも同じ要領で指定可能
%exclude /opt/appname/.git
その他、設定値は詳しい内容は、以下を参照
- 参考:SPECファイルの記述
- それか、以下を参照
Build
作成した.spec
ファイルを使って、buildをします。
エラーが起きた場合は、適宜対処してください。
$ rpmbuild -bb /root/rpmbuild/SPECS/hello.spec
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.5EA7HS
+ umask 022
+ cd /root/rpmbuild/BUILD
+ rm -rf /root/rpmbuild/BUILDROOT/hello-1.0-1.x86_64
+ exit 0
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.j7oCjB
+ umask 022
+ cd /root/rpmbuild/BUILD
+ exit 0
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.lARvVj
+ umask 022
+ cd /root/rpmbuild/BUILD
+ '[' /root/rpmbuild/BUILDROOT/hello-1.0-1.x86_64 '!=' / ']'
+ rm -rf /root/rpmbuild/BUILDROOT/hello-1.0-1.x86_64
++ dirname /root/rpmbuild/BUILDROOT/hello-1.0-1.x86_64
+ mkdir -p /root/rpmbuild/BUILDROOT
+ mkdir /root/rpmbuild/BUILDROOT/hello-1.0-1.x86_64
+ rm -rf /root/rpmbuild/BUILDROOT/hello-1.0-1.x86_64/usr/local/bin
+ mkdir -p /root/rpmbuild/BUILDROOT/hello-1.0-1.x86_64/usr/local/bin
+ tar -C /root/rpmbuild/BUILDROOT/hello-1.0-1.x86_64/usr/local/bin -xzf /root/rpmbuild/SOURCES/hello-1.0.tar.gz
+ /usr/lib/rpm/check-buildroot
+ /usr/lib/rpm/redhat/brp-compress
+ /usr/lib/rpm/redhat/brp-strip /usr/bin/strip
+ /usr/lib/rpm/redhat/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump
+ /usr/lib/rpm/redhat/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/brp-python-bytecompile /usr/bin/python 1
+ /usr/lib/rpm/redhat/brp-python-hardlink
+ /usr/lib/rpm/redhat/brp-java-repack-jars
Processing files: hello-1.0-1.noarch
Provides: hello = 1.0-1
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
warning: Arch dependent binaries in noarch package
Checking for unpackaged file(s): /usr/lib/rpm/check-files /root/rpmbuild/BUILDROOT/hello-1.0-1.x86_64
Wrote: /root/rpmbuild/RPMS/noarch/hello-1.0-1.noarch.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.t4IR5L
+ umask 022
+ cd /root/rpmbuild/BUILD
+ rm -rf /root/rpmbuild/BUILDROOT/hello-1.0-1.x86_64
+ exit 0
buildをすると、/rootの下に以下のディレクトリが生成されます。
BUILD
BUILDROOT
RPMS
SRPMS
また、以下のファイルが生成されます。
$ ls -l /root/rpmbuild/RPMS/noarch/hello-1.0-1.noarch.rpm
-rw-r--r-- 1 root root 370740 Aug 13 08:15 RPMS/noarch/hello-1.0-1.noarch.rpm
Install
作成された.noarch.rpm
ファイルを使ってインストールをします。
$ rpm -ivh /root/rpmbuild/RPMS/noarch/hello-1.0-1.noarch.rpm
Preparing... ################################# [100%]
Updating / installing...
1:hello-1.0-1 ################################# [100%]
インストール確認
$ rpm -qa | grep hello
hello-1.0-1.noarch
$ rpm -qp /root/rpmbuild/RPMS/noarch/hello-1.0-1.noarch.rpm
hello-1.0-1.noarch
Run
hello
コマンドを実行して、hello, world
と表示されれば成功です。
$ hello
hello, world
Uninstall
アンイストールは以下の手順出来ます。
$ rpm -ev hello-1.0-1.noarch
Preparing packages...
hello-1.0-1.noarch
応用
ソースファイル以外に、設定ファイルや、binファイルを、それぞれソースとは別のディレクトリに設置する例です。
要件
このようなディレクトリ構造のアプリケーションを、
sample_app
├── bin
├── conf
├── src
└── systemd
以下の様なディレクトリ構造で展開したい。
元 | インストール先 |
---|---|
bin/* | /usr/local/bin |
conf/* | /etc/sample_app |
src/* | /opt/sample_app |
systemd/* | /etc/systemd/system |
1行目の説明をすると、bin配下のものは全て/usr/local/bin配下に設置という意味です。
tarファイルを作成
$ tar zcf /root/rpmbuild/SOURCES/sample_app.tar.gz sample_app/*
specファイルを作成
/root/rpmbuild/SPECS/sample_app.spec
%define name sample_app
%define version 1.0
# buildコマンドの引数で渡す。後述参照。version 1.0-1となる。
%define release 1%{?dist}
%define _binaries_in_noarch_packages_terminate_build 0
Summary: This is a sample python package.
Name: %{name}
Version: %{version}
Release: %{release}
License: MIT
Source0: %{name}.tar.gz
Group: Applications/File
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
Prefix: %{_prefix}
BuildArch: noarch
# BUILDディレクトリ
%define BUILD_DIR ${HOME}/rpmbuild/BUILD/sample_app
# ソースのインストールディレクトリ
%define INSTALL_DIR %{buildroot}/opt
# Pythonのsite-packagesのディレクトリ
%define PY_PKG_DIR %{INSTALL_DIR}/%{name}/site-packages
# binファイルを設置するディレクトリ
%define BIN_DIR %{buildroot}/usr/local/bin
# 設定ファイルを設置するディレクトリ
%define CONF_DIR %{buildroot}/etc/sample_app
# systemdを設置するディレクトリ
%define SYSD_DIR %{buildroot}/etc/systemd/system
%description
This is a sample python package.
# rpmをbuildする前の準備
%prep
rm -rf ${RPM_BUILD_ROOT}
# makeのための手順
%build
# installのための手順
%install
rm -rf %{INSTALL_DIR}
mkdir -p %{INSTALL_DIR}
mkdir -p %{PY_PKG_DIR}
mkdir -p %{BIN_DIR}
mkdir -p %{CONF_DIR}
mkdir -p %{SYSD_DIR}
# tarファイルを解凍
tar zxfv %{SOURCE0}
# 各ファイルを設置
mv %{BUILD_DIR}/src/* %{INSTALL_DIR}/sample_app
mv %{BUILD_DIR}/bin/* %{BIN_DIR}
mv %{BUILD_DIR}/conf/* %{CONF_DIR}
mv %{BUILD_DIR}/systemd/* %{SYSD_DIR}
# pipモジュールをインストール
cd %{INSTALL_DIR}/%{name}/pkg && PYTHONPATH='%{PY_PKG_DIR}' python setup.py install --install-lib %{PY_PKG_DIR}
pip install -r %{INSTALL_DIR}/%{name}/requirements.txt -t %{PY_PKG_DIR}
# rpmを作った後の処理
%clean
rm -rf %{buildroot}
# rpm展開後に行うコマンド
%post
systemctl enable service_name
systemctl start service_name
# rpmパッケージアンイストール後に実行するコマンド
# アンイストールのときだけ実行されるようにif文を追加
# 参考: https://qiita.com/ymko/items/80e78bfc8cbf4cee2186
%postun
if [ $1 -eq 0 ]; then
rm -f /usr/local/bin/sample01
rm -f /usr/local/bin/sample02
fi
# 設置するファイル。${RPM_BUILD_ROOT}より下から書く
%files
# ソースのインストールディレクトリ
/opt
# binファイルを設置するディレクトリ
/usr/local/bin
# 設定ファイルを設置するディレクトリ
/etc/sample_app
# systemdを設置するディレクトリ
/etc/systemd/system
# ディレクトリの権限
%defattr(-,root,root)
# 設置をしない、除外するディレクトリ
%exclude /opt/%{name}/wrapper/tests
%exclude /opt/%{name}/luigi/tests
# ${RPM_BUILD_ROOT}/usr/doc/sample_app-1.0-1にコピーされる
%doc README.md
Build
--define "dist .el7"
のオプションを付けることで、specファイル内の%{?dist}
に値が渡ります。
$ sudo rpmbuild -bb /root/rpmbuild/SPECS/sample_app.spec --define "dist .el7"
ファイルが作成されたことを確認
$ sudo ls /root/rpmbuild/RPMS/noarch/
sample_app-1.0-1.el7.noarch.rpm
Install
$ sudo rpm -ivh /root/rpmbuild/RPMS/noarch/sample_app-1.0-1.el7.noarch.rpm
これで、以下のそれぞれのディレクトリの下に、ファイルが展開されます。
- /usr/local/bin
- /etc/sample_app
- /opt/sample_app
- /etc/systemd/system
追記
python3でビルドする場合は、.specに以下を追記して、インタプリタをpython3にする必要あり。
%global __python %{__python3}
確認
%install
%{__python} -V
%{__python} -m pip -V
参考:https://fedoraproject.org/wiki/Archive:PackagingDrafts/Python3?rd=PackagingDrafts/Python3