みんな大好きCentOS。
最近はUbuntuのシェアも増えているみたいですが、無料で使えるRedHat系ディストリビューションとして、まだまだ他に移行する気がしない!って人も多いんじゃないでしょうか。
CentOSといえば、有名なリポジトリとしてepel、RepoForge、remi、iusなどなどありますが、
- CentOSを使い続けたい
- できるだけ最新のソフトウェアを利用したい
- ソースからビルドして/usr/local/binなどにインストールする運用は避けたい
・・・といったポリシーをお持ちの方なら、一度は利用したことはあるかと思います。
しかし、いろんなリポジトリを併用しすぎると パッケージの依存関係がなんかヘン になったり、 同じソフトウェアなのに微妙にパッケージ名が違う という事態に陥って、混乱しがちですよね(私だけ?)。
だったらいっそ 独自のリポジトリを持とう! ということで、そのために必要な知識を私の 独断と偏見で ザックリと説明しつつ、一連の作業の流れをまとめてみようと思います。
- 要するに、以下、自己責任でお願いします。
- 詳細な説明を省いている箇所もありますが御了承ください。
はじめに:3行まとめ
- SRPMやspecファイルからパッケージ(*.rpm)作成
- パッケージをWebにアップロード
- createrepoコマンドとyum設定ファイルでリポジトリとして認識させる
SRPMやspecファイルからパッケージ作成
RPMを作成するために、まずは必要なパッケージをインストールします。
$ sudo yum install -y rpm-build rpmdevtools
rpm-buildパッケージは、RPM作成には欠かせないrpmbuildコマンドを提供します。
rpmdevtoolsパッケージは、RPM作成のためのディレクトリツリーや.rpmmacrosファイルをセットアップしてくれるrpmdev-setuptreeコマンドを提供します。
これらがインストールできたところで、以下、 最新バージョンのRPMを作成する方法 を、例を挙げて説明します。
例:CentOS 6.7におけるGitパッケージ
2015/10/22現在、CentOS 6.7において、公式パッケージとして公開されているGitの最新バージョンは 1.7.1 です。
対して、実際のGitの最新バージョンは 2.6.2 ですので、できれば最新バージョンを利用したい!と思ったとします。
つまり、 CentOS 6.7用のgit-2.6.2パッケージを自作したい! ということですね。
RawhideのSRPMを拝借する
CentOSは、Red Hat Enterprise Linux(以下 RHEL)のクローンOSとして知られていますが、RHELと同様に、最新の(メジャーバージョンが上がった)パッケージは提供されない傾向にあります。
対して、同じRHEL系のFedoraは比較的新しいパッケージを随時取り入れているディストリビューションで、特にRawhideは最新のパッケージを提供し続けています。
SRPMも公開されているので、これを用いてCentOS向けにリビルドしていくことにします。
(かなり邪道ですが、ツッコミはナシの方向で。本来は、インストールしたいソフトウェアがどのようにビルドされるのかを良く研究・把握したうえで、独自にspecファイルを自作し、リビルドすべきです。)
Rawhideが提供するSRPMは下記から取得できます。
https://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/source/SRPMS
現時点のRawhideにおけるgitパッケージのSRPMは下記の通りです。
https://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/source/SRPMS/g/git-2.6.2-1.fc24.src.rpm
ちょうどいい具合に最新バージョンのようですね!
下準備
まず始めに、先ほどインストールしたrpmdev-setuptreeコマンドを実行します。
$ rpmdev-setuptree
~/rpmbuild以下に必要なディレクトリが作成され、~/.rpmmacros設定ファイルが配置されます。
$ ls -R rpmbuild
rpmbuild:
BUILD  RPMS  SOURCES  SPECS  SRPMS
rpmbuild/BUILD:
rpmbuild/RPMS:
rpmbuild/SOURCES:
rpmbuild/SPECS:
rpmbuild/SRPMS:
%_topdir      %(echo $HOME)/rpmbuild
%_smp_mflags  -j3
%__arch_install_post   /usr/lib/rpm/check-rpaths   /usr/lib/rpm/check-buildroot
説明は省きますが、不要なdebuginfoパッケージが作成されないよう、~/.rpmmacrosファイルに次の1行を追加します。
%debug_package %{nil}
これでrpmbuildコマンドを用いるための下準備が整いました。
SRPMファイルの展開
SRPMファイルは、RPMファイルのビルドに必要な specファイル と、ソフトウェアの ソース、パッチ類 などが含まれたファイルです。
これらを展開するために、curlコマンドを用いてSRPMファイルをダウンロードし、rpmコマンドを用いて~/rpmbuild以下に配置します。
$ curl -LO https://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/source/SRPMS/g/git-2.6.2-1.fc24.src.rpm
$ rpm -ivh git-2.6.2-1.fc24.src.rpm
これで~/rpmbuild/SOURCESにソースやパッチ類、~/rpmbuild/SPECSにspecファイルが配置されます。
ビルドに必要なパッケージのインストール
では、rpmbuildコマンドでビルド・・・と行きたいところですが、ビルドに必要なパッケージが足りないようです。
$ rpmbuild -ba ~/rpmbuild/SPECS/git.spec
エラー: ビルド依存性の失敗:
	asciidoc >= 8.4.1 は git-2.6.2-1.el6.x86_64 に必要とされています
	xmlto は git-2.6.2-1.el6.x86_64 に必要とされています
	desktop-file-utils は git-2.6.2-1.el6.x86_64 に必要とされています
	emacs は git-2.6.2-1.el6.x86_64 に必要とされています
	expat-devel は git-2.6.2-1.el6.x86_64 に必要とされています
	gettext は git-2.6.2-1.el6.x86_64 に必要とされています
	libcurl-devel は git-2.6.2-1.el6.x86_64 に必要とされています
	pcre-devel は git-2.6.2-1.el6.x86_64 に必要とされています
	openssl-devel は git-2.6.2-1.el6.x86_64 に必要とされています
	zlib-devel >= 1.2 は git-2.6.2-1.el6.x86_64 に必要とされています
	pkgconfig(bash-completion) は git-2.6.2-1.el6.x86_64 に必要とされています
	perl(Error) は git-2.6.2-1.el6.x86_64 に必要とされています
	perl(ExtUtils::MakeMaker) は git-2.6.2-1.el6.x86_64 に必要とされています
yum-builddepコマンドが便利!
こういうときに便利なコマンドがyum-builddepコマンドです。
yum-utilsパッケージにて提供されていますのでインストールします。
$ sudo yum install -y yum-utils
インストールできたら、yum-builddepコマンドを用いるために、specファイルからSRPMファイルを作成します。
$ rpmbuild -bs ~/rpmbuild/SPECS/git.spec
書き込み完了: /home/*****/rpmbuild/SRPMS/git-2.6.2-1.el6.src.rpm
では、yum-builddepコマンドを用いて、必要なパッケージを一括インストールします。
$ sudo yum-builddep -y ~/rpmbuild/SRPMS/git-2.6.2-1.el6.src.rpm
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
 * base: www.ftp.ne.jp
 * extras: www.ftp.ne.jp
 * updates: www.ftp.ne.jp
Getting requirements for git-2.6.2-1.el6.src
 --> asciidoc-8.4.5-4.1.el6.noarch
 --> xmlto-0.0.23-3.el6.x86_64
 --> desktop-file-utils-0.15-9.el6.x86_64
 --> 1:emacs-23.1-28.el6.x86_64
 --> expat-devel-2.0.1-11.el6_2.x86_64
 --> gettext-0.17-18.el6.x86_64
 --> libcurl-devel-7.19.7-46.el6.x86_64
 --> pcre-devel-7.8-7.el6.x86_64
 --> openssl-devel-1.0.1e-42.el6.x86_64
 --> zlib-devel-1.2.3-29.el6.x86_64
Error: pkgconfig(bash-completion) のパッケージが見つかりません
「Error: pkgconfig(bash-completion) のパッケージが見つかりません」
まだ足りないパッケージがあるようです。
bash-completionパッケージは、CentOS 6.7の公式リポジトリには存在しないので、同じ要領でこちらもビルドします。
同様にRawhideのSRPMを拝借してインストールすることにします。
$ curl -LO https://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/source/SRPMS/b/bash-completion-2.1-8.20150513git1950590.fc23.src.rpm
$ rpm -ivh bash-completion-2.1-8.20150513git1950590.fc23.src.rpm
$ rpmbuild -bs ~/rpmbuild/SPECS/bash-completion.spec
$ sudo yum-builddep -y ~/rpmbuild/SRPMS/bash-completion-2.1-8.20150513git1950590.el6.src.rpm
$ rpmbuild --rebuild ~/rpmbuild/SRPMS/bash-completion-2.1-8.20150513git1950590.el6.src.rpm
不足パッケージもなく、bash-completionのRPMパッケージがビルドできました!
忘れずにインストールしておきます。
$ sudo yum install -y ~/rpmbuild/RPMS/noarch/bash-completion-2.1-8.20150513git1950590.el6.noarch.rpm
さて、気を取り直して、これで先ほどのyum-builddepコマンドが正常に実行できるはずです。
$ sudo yum-builddep -y ~/rpmbuild/SRPMS/git-2.6.2-1.el6.src.rpm
上手く行ったら、ようやくgitパッケージのビルドです!
$ rpmbuild --rebuild ~/rpmbuild/SRPMS/git-2.6.2-1.el6.src.rpm
〜(略)〜
RPM ビルドエラー:
    インストール済み(ただし未伸張)ファイルが見つかりました:
   /usr/share/doc/git-2.6.2/git-subtree.html
「エラー: インストール済み(ただし未伸張)ファイルが見つかりました」
このように、他のディストリビューションからSRPMを借りてきた場合、そのままビルドできない場合が多いですが、経験上、Fedoraは同じRHEL系なので、まだ互換性は高い方だと思います。
例えば今回の「git-2.6.2-1.fc24.src.rpm」は、名前が示す通り「Fedora 24」に準拠したSRPMと推測されます。
- 要するに、状況に応じて最適なspecファイルを用意しましょう、ということです。
- ソフトウェアによっては、配布物にspecファイルが同梱されているものもあるので、ありがたく利用しましょう。
今回のケースでは「インストール済み(ただし未伸張)ファイルが見つかりました」というエラーが表示されます。
これは簡単に言うと、 ビルドしたファイル群のうち、パッケージされていないファイルがあるよ(取りこぼしがあるよ) という意味です。
こういった場合には、--define="__check_files %{nil}"というオプションを用いて、チェック処理を抑制する事ができます。
$ rpmbuild --rebuild --define="__check_files %{nil}" ~/rpmbuild/SRPMS/git-2.6.2-1.el6.src.rpm
ビルドは成功したものの・・・
これでようやくgit-2.6.2パッケージのビルドに成功しました!
~/rpmbuild/RPMS/x86_64と~/rpmbuild/RPMS/noarchディレクトリ配下にRPMファイルが生成されます。
これらをひとつずつインストールすると、依存関係のせいで上手く行かないので、下記のように一度にファイルを指定してインストールします。
$ find ~/rpmbuild/RPMS -name "*.rpm" -exec sudo yum install -y {} +
しかし・・・ここでまたエラー。
エラー: パッケージ: git-svn-2.6.2-1.el6.x86_64 (/git-svn-2.6.2-1.el6.x86_64)
             要求: perl-Digest-MD5
 問題を回避するために --skip-broken を用いることができません
 これらを試行できます: rpm -Va --nofiles --nodigest
ここで着目すべきは
             要求: perl-Digest-MD5
の部分です。気を取り直して、~/rpmbuild/SPECS/git.specの中身を注意深く追っていくことにしましょう。
$ grep -n 'perl-Digest-MD5' ~/rpmbuild/SPECS/git.spec
224:Requires:       perl-Digest-MD5
715:- git-svn - added requires for perl-Digest-MD5 (#1218176)
というわけで、224行目が怪しいのですが、「perl-Digest-MD5」は、「PerlのDigest::MD5モジュール」のパッケージ名を表しています。
また、「Requires:」とあるので、これはgitに必要なパッケージであることを示しています。
以上の手がかりを元にもう少し見ていきましょう。
$ grep -n 'Requires:' ~/rpmbuild/SPECS/git.spec | grep perl
97:Requires:       perl(Error)
99:Requires:       perl(Term::ReadKey)
101:Requires:       perl-Git = %{version}-%{release}
142:Requires:       perl-Git = %{version}-%{release}
144:Requires:       perl(Term::ReadKey)
224:Requires:       perl-Digest-MD5
226:Requires:       perl(Term::ReadKey)
239:Requires:	perl-DBD-SQLite
249:Requires:       git = %{version}-%{release}, perl-Git = %{version}-%{release}
250:Requires:       perl(Authen::SASL)
251:Requires:       perl(Net::SMTP::SSL)
283:BuildRequires:  perl(Error), perl(ExtUtils::MakeMaker)
284:Requires:       perl(Error)
285:Requires:       perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version))
297:Requires:       perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version))
同じPerlモジュールでも、2種類の指定方法があるようですね。
ハイフンで単語を繋げる形式と、カッコとコロンで区切られた形式の2種類に大別できるようです。
説明は省きますが、前者は RPMパッケージ名 、後者は Perlモジュール名 を示しています。
先ほどのエラーが示す通り、「perl-Digest-MD5なんてパッケージはCentOS 6.7には無いよ」ということなのですが、実は、 Rawhideでは「perl-Digest-MD5」という個別のパッケージが存在する のに対し、 CentOS 6.7では、「perl」パッケージに含まれます。
以上を踏まえると、224行目を
224:Requires:       perl(Digest::MD5)
このように修正すれば良いということになります。
同じRHEL系といえども、ディストリビューションやバージョンの違いで微妙な差異があるため、前提となる標準パッケージの違いや、それらの依存関係については十分留意する必要があります。
ようやくインストールまで成功!
~/rpmbuild/SPECS/git.specを修正したら、もう一度SRPMの作成からやり直しです。
$ rpmbuild -bs ~/rpmbuild/SPECS/git.spec
$ sudo yum-builddep -y ~/rpmbuild/SRPMS/git-2.6.2-1.el6.src.rpm
$ rpmbuild --rebuild --define="__check_files %{nil}" ~/rpmbuild/SRPMS/git-2.6.2-1.el6.src.rpm
$ find ~/rpmbuild/RPMS -name "*.rpm" -exec sudo yum install -y {} +
これでようやくインストールも成功です!
きちんとパッケージされているかどうか、インストール後の動作確認も忘れずに。
パッケージをWebにアップロード
期待通りのパッケージが作成できたら、Webから閲覧できる領域にRPMファイルをアップロードします。
64ビット版のCentOSなら、*.x86_64.rpmと*.noarch.rpmの2種類のRPMが作成されますので、これらを同一ディレクトリにアップロードします。
ちなみにx86_64は、「64ビット版IntelCPUアーキテクチャ」を意味し、noarchは「CPUアーキテクチャに依存しないパッケージ」を意味します。
32ビット版のCentOSなら、*.noarch.rpmの他に*.i686.rpmや*.i386.rpmなどが生成されます。
*.src.rpmはアップロードしなくて構いません。
createrepoコマンドとyum設定ファイルでリポジトリとして認識させる
RPMファイルが無事作成できたので、yumから利用できるようにするための準備に取りかかります。
サーバ側でcreaterepoコマンドを実行し、クライアント側で設定ファイルを用意します。
createrepoコマンド
$ man createrepo
NAME
       createrepo - Create repomd (xml-rpm-metadata) repository
SYNOPSIS
       createrepo [options] <directory>
DESCRIPTION
       createrepo  is a program that creates a repomd (xml-based rpm metadata)
       repository from a set of rpms.
〜(略)〜
createrepo = RPMファイルをもとにリポジトリのメタデータを作成するコマンド です。
例えばここ(理研のミラーサイト)もyumリポジトリですが、構造を良く見ると、repodataというディレクトリがあり、ここにメタデータが格納されています。
createrpoコマンドは、このrepodataディレクトリ(とその中身)を作成する事ができます。
yumコマンドは、このメタデータを読み取ることによって、リポジトリに登録されているRPMパッケージを認識しています。
createrepoは RPMファイル単体ではなく、RPMを配置したディレクトリ全体に作用するコマンド ですので、対象とするディレクトリの内容に変更があれば、その都度メタデータの更新が必要となります。
当然サーバ側での作業が必要となりますので、サーバ側でcreaterepoが実行できない場合は、ローカルに同様の環境を用意してrepodataごと上書きアップロードします。
createrepoのインストール
createrepoは同名のcreaterepoパッケージにて提供されます。
$ sudo yum install -y createrepo
使い方は上記のman createrepoの通りです。
yum設定ファイルの作成
さて、いよいよクライアント側でyumを利用するため、yumに上記のWeb領域を認識させます。
yumがWeb領域をリポジトリとして認識するために、/etc/yum.repos.d配下に*.repoファイルを配置します。
下記に*.repoファイルの内容例を示します。
$ cat /etc/yum.repos.d/example.repo
[example]
name=My packages
baseurl=http://example.com/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
$releaseverはCentOS 6.xなら「6」、CentOS 7.xなら「7」が適用されます。
$basearchは64ビット版なら「x86_64」、32ビット版なら「i386」が適用されます。
今回はGPG署名の説明は端折ったので、gpgcheck=0としていますが、署名されたパッケージの場合はgpgcheck=1とし、公開鍵のアップロードが必要です。
おわりに
以上のような手順で、実際にepelやremiと同じようなことが実現できます。
上記の*.repoのみをインストールするためだけのパッケージを用意すれば、導入も容易になり便利です。
また、リポジトリ用のページを生成したい場合はrepoviewというコマンドを利用することもできるようですので調べてみてください(誰かまとめてくださいw)。