オフィシャルサイト:
Yum: Yellowdog Updater Modified

Yum

Yum は RPM 版の apt のようなもので、その実体は python で書かれたスクリプト群。 YellowDog Updater Modified の略だそうだが、「もぐもぐ美味ちぃ」の` yum yum' に無理矢理こじつけたとしか思えない名前が傑作だ。

Yum をインストールしたら、パッケージの検索先 (レポジトリと呼ぶ) を設定してやらなければならない。設定は、yum 2.0.x の場合は /etc/yum.conf で行う。それに対して yum 2.2 以降の場合、通常は yum.conf にはグローバルな設定 ( [main] 部分) だけ書き、各レポジトリ定義は /etc/yum.repos.d/ 下にあるファイル fedora.repo, fedora-updates.repo などに記述する。 extras レポジトリや updates-testing レポジトリのパッケージなども引いてこれるようにしたい場合は、上記レポディレクトリに例えば fedora-extras.repo などというファイルを新設して各々の定義を記述すればよい。

日本国内で、同期のタイムラグが少なく信頼できるミラーサイトを幾つか挙げておくと:

Fedora Core 4 までと RedHat (Enterpriseでない) Linux にアップデートパッケージを提供してきた Fedora Legacy Project は 2007年 1月、閉鎖となった。それら古いバージョンのディストリビューションを使っている人は早急に Fedora Core 5 以降へアップグレードした方がいい。当サイトの Fedora Upgrade HOWTO がお役に立てるかもしれない。

RedHat Enterprise Linux では永いこと up2date という使いにくいアップデーターが使われてきたが、 5 からはやっと Yum が標準となった。動作時のメッセージを見ていると、認証の問題には特別なプラグインで対処しているようだ。

Table of Contents

RHEL4へのインストール

Fedora Core や RHEL5 以降なら yum は標準でインストールされるが、Red Hat Enterprise Linux 4 では yum の純正パッケージが提供されていないので、あれこれとインストールする必要がある。RHEL4.5 (旧称 4 Update-5) で検証した結果をまとめておく。

必要なパッケージ

先にも述べたように Yumpython スクリプトを中核としている。 Yum 関連のパッケージバージョンは、インストールされている pythonrpm-libs のバージョンを軸にして選択しなくてはいけない。RHEL4 の python は 2.3系である。

パッケージファイル名 入手先
yum-2.4.*-*.src.rpm Linux@DUKE
sqlite-2.8.*-*.el4.rf.*.rpm DAG WIEERS
python-sqlite-0.5.*-*.el4.rf.*.rpm DAG WIEERS
python-elementtree-1.2.*-*.el4.rf.*.rpm DAG WIEERS
python-urlgrabber-2.9.*-*.el4.rf.noarch.rpm DAG WIEERS

※ 過去の遺物だが、yum-2.0.x のビルド済みパッケージをここに置いておく。2.0.x なら上記の sqlite 以下はインストールしなくて済むが、はなはだ時代遅れでいろいろと不都合の方が多い。

先に yum 以外をインストールしてから、下記のようにして yum の RPMパッケージを作成し、それをインストールする。 rpmbuild について不明な人はこちらを参照。

hoge$ rpmbuild --rebuild yum-2.4.X-X.src.rpm

設定ファイル

設定例

yum 設定ファイルの、一般的に言ってお勧めの設定は以下。わざわざ HTTP でつないでいるのは、経験上 HTTP のほうが接続が確実なため。

yum 2.2 以降の場合

yum は 2.2 や 3 以降では、/etc/yum.conf にはグローバル設定のみを書く。そして各レポジトリ定義は /etc/yum.repos.d/ 下のファイルに分割して書く。CentOS 5.4 での例を示す。

yum.conf

[main]
cachedir=/var/cache/yum
keepcache=0
debuglevel=2
logfile=/var/log/yum.log
distroverpkg=fedora-release
tolerant=1
exactarch=1
retries=5
obsoletes=1
gpgcheck=1
plugins=1

CentOS-Base.repo

[base]
name=CentOS-$releasever - Base
failovermethod=roundrobin
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&cc=jp
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
enabled=1
 
[updates]
name=CentOS-$releasever - Updates
failovermethod=priority
baseurl=http://ftp.riken.jp/Linux/centos/$releasever/updates/$basearch/
        http://www.ftp.ne.jp/Linux/packages/CentOS/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
enabled=1
 
[addons]
name=CentOS-$releasever - Addons
failovermethod=roundrobin
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=addons&cc=jp
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
enabled=1
 
[extras]
name=CentOS-$releasever - Extras
failovermethod=roundrobin
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras&cc=jp
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
enabled=1
 
[centosplus]
name=CentOS-$releasever - Plus
failovermethod=roundrobin
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=centosplus&cc=jp
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
enabled=0

上記の CentOS-Base.repo では、説明のために、[base][updates] でレポジトリ参照先指定方法を変えてみた。通例使われるのは [base] で書いた mirrorlist による指定方法。mirrorlist 右辺に指定されている URL は一種の CGI らしく、release, arch などのリクエスト引数に応じてレポジトリサイトの URLリストを返してくるようにできている。赤字で示した CGI 引数 `cc=jp' を加えてやると、日本にあるレポジトリのリストが確実に返ってくるのでダウンロードがスムーズになる。ただし、yum 付属プラグイン `fastestmirror (yum-fastestmirror パッケージ) の旧バージョンでは、cc による国コード指定が無視される現象が見受けられた。また、最近の fastestmirror プラグインでは、上記のように cc=jp を付ける代わりに、fastestmirror プラグインの設定ファイルである /etc/yum/pluginconf.d/fastestmirror.conf 内の include_only=.jp を指定する。あるいは最後の手段として、fastestmirror.conf 内の enabled=10 にする手も残されている。
一方、baseurl のリストを直接書くやり方は、ディストリビューション標準でない外部レポジトリや、独自に作成したローカルレポジトリを参照させる場合に向いている。

他にもうひとつ、CentOS 5 あたりからデフォルトで設定されているレポジトリ定義がある。ローカルの CDROM/DVD をレポジトリとして参照するためのものだ。これは、インターネット接続のできない環境で、RedHat Enterprise Linux (RHEL) などにインストールメディアそのものからパッケージを追加する時に、真似すると便利だ。

fedora-media.repo

[fedora-media]
name=Fedora Core $releasever - $basearch - Media
failovermethod=priority
baseurl=file:///media/cdrom/
gpgcheck=1
enabled=0

ただし、メディアレポジトリ定義には幾つか注意点がある。まず、enabled=0 にして、メディアが光学ドライブに挿入されていない時のエラーを避けること。ローカルレポを使いたい時には yum のコマンドラインオプションに明示的に --enablerepo=fedora-media という風にオプションを添えてコールするわけだ。もうひとつは、最近の Ferora Core, CentOS, RHEL 5以降のように、光学メディアが /media/ 下に動的なメディアラベル名でマウントされるディストリビューションの場合。挿入するメディアによって、例えば "/media/RHEL_5.2 i386 DVD" のようにディレクトリ名がラベル名によって変わるので、メディアレポ定義ではカバーしきれないのだ。その対処法は 2つある。

1. fstab に光学メディアのマウント定義を載せる

いつからかは忘れたが、少なくとも RHEL/CentOS 6 では、/etc/fstab に光学メディアのマウント定義が載っていると、ラベル名によるマウントは抑止されて固定マウントポイントによるマウントへと挙動が変わる。定義の内容は下記の要領。もちろん /media/cdrom ディレクトリは mkdir しておく必要がある。

/dev/cdrom   /media/cdrom   auto   ro,noauto,user,exec   0 0

2. 別名マウント

root# mount --bind /media/RHEL_5.2\ i386\ DVD /media/cdrom

のように別名マウントしてから yum をコールする。また、そういうディストリビューションでは元々 /media/cdrom/ ディレクトリが存在しないので、やはりあらかじめ作成しておく必要がある。

なお、RHEL/CentOS 5 のインストールメディアは、baseurlfile:///media/cdrom/Server/ と指定しなければならない造りになっている点に注意。

yum 設定ファイルができたら、汚染チェックのための GPG キーをインポートする (下記は Fedora Core 5の例)。インストールCD/DVD からインポートしてもいい:

root# rpm --import \
 http://ring.riken.jp/pub/linux/fedora/linux/core/5/i386/os/RPM-GPG-KEY-fedora

Extras も利用するなら専用の署名も必要。例えば下記の URL で取れる。例えば:

http://ftp.kddilabs.jp/Linux/packages/fedora/extras/RPM-GPG-KEY-Fedora-Extras

RHEL4 でサードパーティのレポジトリを使用する

信頼できる有名レポジトリとして DAG WIEERS と EPEL がある。 EPEL (Extra Packages for Enterprise Linux) は、Red Hat Enterprise Linux 4 以降にアドオンパッケージを提供しようという、Fedora Project が立ち上げたプロジェクトだ。これらふたつのレポジトリを使用するには下記のパッケージをダウンロードしてインストールするだけでいい。これらによって yum.repos.d/ 下に適切なレポジトリ定義ファイルがインストールされ、GPGキーもインポートされる。

EPEL epel-release-4-*.noarch.rpm
DAG WIEERS rpmforge-release-0.3.*-*.el4.rf.i386.rpm

[参考] 既にLegacy入りしたリリースの場合

Fedora Legacy Project は閉鎖となったため、この項目は過去の遺物。参考のため引き続き置いておく。ここでは yum 2.0.x を例とするので、 /etc/yum.conf で全ての設定を行う。

[main]
cachedir=/var/cache/yum
debuglevel=2
logfile=/var/log/yum.log
pkgpolicy=newest
distroverpkg=fedora-release
tolerant=1
exactarch=1
retries=5
 
[base]
name=Fedora Core $releasever base
failovermethod=priority
baseurl=http://ftp.kddilabs.jp/Linux/packages/fedora.legacy/fedora/$releasever/os/$basearch
gpgcheck=1
 
[updates]
name=Fedora Core $releasever updates
failovermethod=priority
baseurl=http://ftp.kddilabs.jp/Linux/packages/fedora.legacy/fedora/$releasever/updates/$basearch
gpgcheck=1
 
[legacy-utils]
name=Fedora Legacy utilities for Fedora Core $releasever
failovermethod=priority
baseurl=http://ftp.kddilabs.jp/Linux/packages/fedora.legacy/fedora/$releasever/legacy-utils/$basearch
gpgcheck=1

設定後、RPM の汚染チェックのための GPG キーを Fedora Legacy 本家からダウンロードし rpm にインポートする:

root# rpm --import http://www.fedoralegacy.org/FEDORA-LEGACY-GPG-KEY

設定ディレクティブの詳細

主なものだけ述べる。yum 2.0.x と 2.2 以降では若干仕様が異なるので、それについても触れておく。

[main] セクションで使用するディレクティブ
記述例 (推奨とは限らず) 解説
cachedir=/var/cache/yum yum がキャッシュを蓄えるディレクトリを指定。この下に、各レポ定義で指定したレポジトリID (例えば "updates-released") 名のサブディレクトリが作られ、ヘッダやデータベース、ダウンロードしたパッケージが保管される
keepcache=0 1 にしておくと、インストールに先立って /var/cache/yum/REPO_ID/packages/ にダウンロードされたRPMパッケージが、インストール後も削除されない
pkgpolicy=newest [2.0.x のみ] newest なら、或るパッケージが複数のレポジトリサーバに見つかった際に、最も新しいバージョンをインストールする。 last とすると、レポジトリIDでソートした結果、リストの最後に来たパッケージをインストールしようとする。デフォルト=newest
distroverpkg=fedora-release yum がディストリビューションのリリースバージョン (Fedora Core 3 なら "3" または "FC3") を判断するために参照するパッケージ名。Fedora では fedora-release という rpm パッケージ、RHEL では redhat-release、CentOS では centos-release パッケージが、まさにこのためにデフォルトでインストールされており、RHN up2date でもバージョン判断に利用されてきた。Fedora Core 3 では /etc/yum.repos.d/ 下にあるデフォルトのレポ定義ファイルもこの fedora-release パッケージによってインストールされていた。バージョンそのものは /etc/xxxx-release (xxxx はディストリビューション名) にテキストで書いてあるが、そのシンボリックリンクとして /etc/redhat-release も存在するので、 distroverpkg=redhat-release でも正解。デフォルト=redhat-release
tolerant=1 yum install pkg1 pkg2 ... という具合に複数のパッケージを指定した際に、例えば pkg2 というパッケージが既にインストール済みであった時、エラーを吐かずに続行する。デフォルト=0
exactarch=1 update の際、インストールされているパッケージのアーキテクチャとアップデート版のアーキテクチャが厳密に同じでないとアップデートしない。例えばインストールされているのが foo-x.x.x-i686.rpm で、見つかった最新版が foo-x.x.x-i386.rpm だったら不可となる。デフォルト=1
retries=5 ファイルのダウンロード時に、エラーを出すまでに何度リトライするか。 0 は「永遠」の意となるので御法度。yum-2.0 や 2.2 では デフォルト=6、RHEL/CentOS 5 の yum-3.2.x では 10
obsoletes=1 yum の obsoletes 処理を有効にする (1) かしない (0) か。時として、或るパッケージのアップデートによって関連パッケージの構成や依存関係が大幅に変わり、関連の別のパッケージがアンインストールされなければならない場合がある。それが obsoletes 処理だ。特に、DISTROVER が変わるようなディストリビューションレベルのアップグレード (FC2 から FC3 へなど) の時には有効にする必要がある。yum によるリリースアップグレードは筆者としてはお勧めしないが、玉砕覚悟で冒険を犯したい人は YumUpgradeFAQ (Fedora) も読むべし。デフォルト=0
installonlypkgs=kernel update 動作を指定したとしても決して上書きせず、常に install を行うパッケージ。デフォルトでこの動作を採るのは kernel, kernel-smp, kernel-bigmem, kernel-enterprise, kernel-debug, kernel-unsupported
gpgcheck=1 [2.2 以降] 汚染チェックのための GPG 署名検査を行うかどうか、各レポ定義で指定しない場合のデフォルト値を決める。 2.0.x ではグローバルセクションに書くとエラーになる。デフォルト=0 (チェックしない)
keepalive=1 baseurl が HTTP 指定で、且つレポジトリサーバが HTTP 1.1 のキープアライブオプションをサポートしていれば、ひとつの HTTP コネクションで複数のファイルを連続してダウンロードでき、効率が上がる可能性がある。各レポ定義内で個別に指定することもできる。デフォルト=1
debuglevel=2 標準出力の冗長レベル (0-10)。 0 では結論のみ、 2 ではレポジトリへの接続も出力、 3 だと様々な判断も出力、という具合に詳細度が上がっていく。デフォルト=2
errorlevel=2 エラー出力の冗長レベル (0-10)。 0 ではクリティカルなエラーのみ、 1 でほとんど全て出力。デフォルト=2
exclude=PkgStr [...] アップデートおよびインストール対象から除外するパッケージを指定できる。右辺はパッケージ名のリスト (スペース区切り) で、各 PkgStr にはシェルスタイルのワイルドカードが使える。よく使う用法として、カーネルだけ除外したいケースがある。その場合は kernel-* と指定すると kernel-x.x.x...kernel-devel-x.x.x... など一式の不用意なアップデートが避けられる (RHEL6 の場合は perf-* も一緒に除外すること!)
proxy=URL:Port レポジトリへ接続する際に使用するプロキシ。例えば、proxy=http://192.168.1.100:8080 のように指定する
plugins=1 yum のプラグインを有効(1) または無効 (0) にする。プラグインとして代表的なものに、システムが Red Hat Network に登録されているかどうかチェックしてオフィシャルレポジトリへの接続を行う rhnplugin や、接続しやすいミラーサイトを検索して優先的に使用する fastestmirror がある。インターネットに接続できない環境でローカルレポジトリだけを使いたい時には邪魔になることがあるので、その場合は plugins=0 にするといい。コマンドラインオプションで一時的に無効にすることもできる
レポジトリ定義内で使用するディレクティブ
[updates-released] レポジトリID。何らかのコマンドラインでレポをオプション指定する場合はここで指定した名前を使う。規則は、まず 1語であることつまりスペースやタブを含んではイケナイ、そしてもちろん、一意でなくてはイケナイ
failovermethod=priority baseurl に複数のサイトを指定していた場合に、 priority なら、記述順に従って接続を試行しダメなら次、という動作を行う。 roundrobin なら、記述の中からランダムに選んでゆく。かつては roundrobin がデフォルトだったが、RHEL/CentOS 5 に搭載されている yum-3.2.x ではデフォルトが priority に変わっている
gpgcheck=1 GPG 署名チェックを行うか。 2.2 以降ではグローバルセクションでも使え、レポ内指定はそれをオーバーライドする。デフォルト=0
enabled=1 [2.2 以降] そのレポ定義を標準で生かすか。例えば updates-testing レポや extras レポ定義は enabled=0 としておくと、通常のアップデートチェックではそれらがチェックから除外されるので時間が短縮できる。敢えて参照したい時だけ yum --enablerepo=update-testing ... とコマンドオプションで指定すれば update-testing レポからもパッケージが引いてこれる
exclude=PkgStr [...] [main] セクションの同名ディレクティブと同じだが、特定のレポ定義内に書けば、そのレポジトリにだけ適用することができる
proxy=URL:Port レポジトリ個別にプロキシサーバを使用しなければならない場合に指定する。また、グローバルセクションで proxy を指定している時に、特定のレポジトリに proxy=none と書いておくとそこだけダイレクトに接続することができる

キャッシュの整備

baseurl を書き換えただけなら必要ないが、レポジトリ定義を追加や削除した場合には yum のキャッシュをクリーンナップする:

root# yum clean all 

上記で「header.info が見つからない」というエラーが出るかも知れないが、気にする必要はない。次回レポジトリを照会させた時にそれらキャッシュデータは整備される。そのために、ここで一度、下記コマンドを発行しておこう:

root# yum list updates

yumの使い方

主なコマンド

list updates [PkgStr] [...] アップデートのチェック (レポ参照優先)。パッケージ名を与えて絞り込むこともできる
check-update アップデートのチェック。 list updates と異なる点は、まず先にキャッシュを読もうとすること (キャッシュがないとエラー)。それに、リターンコードで結果が拾えること (※1)
update [PkgStr] [...] 指定したパッケージをアップデート。パッケージを省略すると、更新版の出たすべてをアップデート。依存関係が解決されて、関連するパッケージも同時にアップデートされる
install PkgStr [...] 指定したパッケージの最新版をインストール。依存関係のあるパッケージが足りなければ一緒にインストールされる
remove PkgStr [...] 指定したパッケージをアンインストール。これも依存関係が解決されるのだが、その評価が少々過大な傾向にあり、思わぬパッケージが連んで削除される可能性があるので、確認画面でしっかり確認すること
groupinstall Grp [...] パッケージグループ単位での一括インストール。有効なグループ名は `yum grouplist' で調べることができるが、日本語名だとタイプしづらいので `LANG=C yum grouplist' とした方がよい
list [PkgStr] [...] ローカルにインストール済みのパッケージとレポから入手可能なパッケージを列挙する。パッケージ名で絞り込むこともできる
list available [PkgStr] [...] 2.0.x と 2.2以降で異なる。どちらもレポから入手可能なパッケージだけを列挙するが、2.0.x ではパッケージ名による絞り込みはできない
info PkgStr [...] 基本的には rpm -qi PkgName あるいは rpm -qpi RPMfile と同様に働く。ただし、もちろんローカルに未インストールだったり RPM ファイルがなくても情報が得られるのが強み
clean packages キャッシュディレクトリにダウンロード済みの RPM ファイルを削除する
clean headers 同、ヘッダファイルを削除する
clean all 上記 clean packagesclean headers を行う。では他にどんな clean があるかと言えば 2.0.x では oldheaders、2.2以降では metadata, cache などがある
shell [File] オプション引数の File を省略すると、yum-shell のプロンプトに入り、yum のトランザクションを或る程度任意に組み立てることができる。トランザクションコマンドをファイルに書いておき、File 引数で渡せば自動化も可能。例を※2に示す

PkgStr 部分のパッケージ文字列にはシェルスタイルのワイルドカード(グロブ)が使える。例えば mod_*mod_perl-x.x.x-x.xmod_python-x.x.x-x.x などにマッチする。それに対して perl と指定すると perl-suidperlperl-debuginfo などはヒットせず、 perl-x.x.x-x.x だけがヒットする。他に、1文字を置き換える "?" も使える。ただし 2.0.x ではこうしたグロブ動作に曖昧さがあり少々注意が必要だ。また、例えば x86_64システムに i686版のパッケージをインストールしたい時には、zlib-devel.i686 のようにバージョンを省略することもできる。x86_64ネイティブと i686版を同時に入れる時は "zlib-devel.i686 zlib-devel" のように指定すればよい。

ついでに、カーネルアップデート時のコツについて。仕事でRedHat Linuxサーバを構築していると、商業ソフトウェアのインストール環境要件的都合で、kernel を最新ではなく少し前のエラータリリースまでで留めなくてはならないケースが多い。ご存知のように、RHEL/CentOS 6以降は、kernel を上げようとすると、kernel, kernel-devel, kernel-headers, kernel-firmware, perf といったパッケージ一式を一度に update しなくてはならない。まだ技を知らなかった頃は、所定のバージョンリリースの kernel 関連RPMをあらかじめ、update するものと install するものでディレクトリを分けてダウンロードしておき、`rpm -ivh install/*.rpm', `rpm -Uvh uptate/*.rpm' とやっていた。が、これは yum でのオンライン update で一発でやれる。しかも yumdevelheaders は自動的に update でなく install にしてくれる。ただし、中間エラータバージョンリリースを指定して update するには各パッケージ名全てに "-x.x.x-x.x.el6" を付けないとうまくいかない。同じ文言を何度も何度もタイプするのは面倒くさく、タイプミスを犯しやすい。そこで、bash のグロブのひとつ {} を使うと便利だ。例えば、2.6.32-504.1.3.el6 へ更新するとしよう。これだけで済む。

yum update {perf,kernel{,-devel,-headers,-firmware,}}-2.6.32-504.3.1.el6

蛇足だが、無償である CentOS の場合、中間エラータリリースパッケージは短期間でレポジトリから削除されてしまうので、希望の版が適用できるとは限らないことにご注意を。

主なコマンドラインオプション

-C ヘッダのダウンロード/アップデートを抑止。ただし、与えられたコマンド上必要であればレポジトリも見に行く
-y installupdate コマンドでは通常、対象パッケージのリストアップ後にポーズして、インストールを行うかどうか訊かれるが、このオプションを添えるとポーズなしで続行される。スクリプトなどで処理を自動化したい場合に便利
-d level 標準出力の冗長レベル (0-10)。グローバル設定の debuglevel をオーバーライド
-e level エラー出力の冗長レベル (0-10)。グローバル設定の errorlevel をオーバーライド
--enablerepo=RepoID レポジトリ定義で enabled=0 (無効) にしてあるレポジトリも有効にする。設定ファイルが書き換わるわけでなく一時的な指定に過ぎない。複数のレポジトリを有効にしたい場合は `--enablerepo=hoge --enablerepo=hoge2' のように複数回唱える
--disablerepo=RepoID レポジトリ定義で enabled=1 (有効) 扱いになっているレポジトリを見に行かない。設定ファイルが書き換わるわけでなく一時的な指定に過ぎない。複数のレポジトリを無効にしたい場合は複数回唱える。また、`--disablerepo=* --enablerepo=hoge' とすれば「hoge以外無効」という指示ができる
--exclude=PkgStr [2.2以降] アップデートおよびインストール対象から除外するパッケージを指定。ただし設定ファイル内での指定とは異なり、ダブルクォートで囲もうが何をしようが PkgStr はひとつしか指定できない
--noplugins プラグインを読み込まない。RHEL では標準で RedHat Network に接続しようとするプラグインが働くため、インターネットに接続できない環境でDVDやローカルレポジトリからパッケージをインストールしたい時にこれが必要となる
※1 check-update のリターンコードの受け取り方

例えばこんな要領でシェルスクリプトを書けば、不要なメッセージなしに状態に応じた処理ができる:

#!/bin/bash
yum -d 0 -e 0 check-update 1>/dev/null 2>&1
RETVAL=$?

if [ $RETVAL = 100 ]; then
    echo There should be one or more available updates
fi

if [ $RETVAL = 0 ]; then
    echo No Available Updates for now
fi
※2 yum shell の活用法

例えば、RHEL/CentOS 6 で rsyslog を v5 から v7 にアップグレードしよう思うと、通常の yum でやろうとした場合、まず先に rsyslog (v5) を remove してから、rsyslog7 を install しなければならない。しかし、rsyslog を `yum remove' すると、crontabs, redhat-lsb 等といった他の重要なパッケージも一旦アンインストールされ、rsyslog7 のインストール時に依存解決によって同じものをあらためてインストールするという危険と無駄が伴う。そこで yum shell の出番だ。yum shell を使うと、rsyslog を remove し rsyslog7 を install するという 2つのことを 1回の yum トランザクションに統合することができるので、crontabs などの再インストールが発生しないのだ。具体的なコマンドの様子は下記のようになる。

root# yum shell
> install rsyslog7
> remove rsyslog
> run
> exit

実際の削除とインストールは、run を叩いた時に初めて実行される。yum shell の説明は `man yum-shell' で読める。

yumレポジトリの作り方

これをまとめたのは、インターネットから隔絶された閉鎖LAN内で、プリプロダクションの数台の RedHat Enterprise Linux 4 マシンと取り組んでいた時、パッケージのアップデートや追加/削除を行うのに苦心したからだ。困ったことに、アップデートパッケージディスクは (いつもの如く) CD-ROM 4枚に分割されており、今ほしいパッケージが何枚目の CD に入っているか探すだけでも手間がかかる。そこで考えたのが、マシンの 1台にローカルレポジトリを作成し、同マシン上の Apache で内輪に公開するという方策だ。こうすれば CD を出し入れする手間もないし、どのマシン (レポジトリマシン自身も含めて) も、 yum の短いコマンドだけでアップデートやパッケージの追加/削除、パッケージ情報の検索などが行える。まず知っておかなくてはならないのは、 yumレポジトリの構造が、 yum 2.0.x クライアントを使う場合と 2.2 以降とで大幅に異なるということだ。 yum-2.2 以降では、パッケージメタデータ (ファイルインデックスのようなもの) を XML で管理する。ここに用意したシェルスクリプトは 2.0 以前でも 2.2 以降でも利用できる。

RHEL5 以降ではこんな込み入った手間は要らない。必要なパッケージをひとつのディレクトリに集めてから、createrepo を実行するだけで事足りる。 その際には、-g オプションでグループファイル (comps.xml) も取り込んでやるとより完全。グループファイルは、インストール DVD の repodata ディレクトリにある。あとはそのディレクトリを Apache で解放するだけだ。ただし、RHEL6 からパッケージングの仕様が変わったため、RHEL6 で RHEL5 以前用の yum レポジトリをホスティングするのは難しい。

これをまとめるにあたっては Creating a Redhat Yum Repository (WebMO) が大変参考になった。構築に利用しているシェルスクリプトも、一部を除き、同サイトから頂戴して手を加えたものだ。

※ この記事を書いた少し後になって、ここでやっていることをもっと洗練された筋道で実現してくれる Cobbler という正式なパッケージが登場した。レポジトリを RedHat Enterprise Linux 4 (RHEL4) 以降か Fedora Core 6 以降のサーバ上に構築するなら Cobbler の活用も検討してみてはいかがだろうか。

ツール

バージョン共通のツール
make-redhat-mirror WebMOサイトから拝借して改造した。レポジトリに必要なディレクトリツリーを作成する。本来は、外部のFTPサイトから lftp でパッケージをダウンロードしてくる作業も担うが、アップデートCDから吸い上げる今回のやりかたのために、その部分はコメントアウトして殺し、下記の get-updates スクリプトに役割を分担した。
get-updates 前記 make-redhat-mirrorlftp による同期部分の代わりとして自作したスクリプト。 RedHat のインストールCD から、パッケージをレポジトリの然るべきディレクトリへコピーする。現状では i386, i686, noarch だけを吸い上げているので、他にも扱いたいアーキテクチャがある人は冒頭の ARCHS 変数のメンバを適宜書き換えていただきたい。
make-apt WebMOサイトから拝借して改造した。上記で作成した up2date式のディレクトリツリーから、 yum式のディレクトリツリーとパッケージメタデータを作る。 up2date式と yum式ではツリー構造が圧倒的に異なるため、 yum式の基底ディレクトリを新たに作成し、 up2date式ツリーの各所へシンボリックリンクを張るというウマい仕組みになっている。名前の通り、元来は apt ツリーを生成するスクリプトだが、何箇所かをコメントアウト/アンコメントすることによって yum に対応できるようになっており、これもそうした他、かなり激しく改造を加えた。 make-yum2 という名前でシンボリックリンクを作成しておき、そちらの名前でコールすると、 yum-2.2 以降用のレポジトリが作成できるようになっている (この使い方には createrepo パッケージのインストールが必要)。 yum-2.0 系で貫き通すなら make-apt を直接呼べばいい。
RHEL4 の場合 (yum-2.2以降を使用)

RHEL4 への yum のインストール で述べた以外に、下記のパッケージが必要。各々 `rpmbuild --rebuild xxx.src.rpm' して RPMパッケージを作成してから、それをインストールする。

パッケージ 入手先
createrepo-0.4.4-*.src.rpm Linux@DUKE
yum-utils-0.3.*-*.src.rpm Linux@DUKE

yumレポジトリ (サーバ) の構築

安全性を考慮して、レポジトリは yumadm という専任ユーザの足下に作成し、そこを Apache の alias 機能で公開することにする。以下手順の /home/yumadm が yumadm ユーザのホームディレクトリだ。当例では全てのマシンのディストリビューションは RHEL 4 ES と仮定する。 AS の場合は以降の `4ES' を `4AS' に読み替えればいい。また、 x86 32bit 環境でしか試していないので、もしかすると x86_64 環境で使うにはスクリプトに細工が必要な可能性もある。

  1. 何は兎も角 yumadm グループ/ユーザを作成する。べつに専用ユーザを作らなくても構わないし、違う名前でもいっこうに構わないが、その場合は以後の説明中の yumadm を読み替え、構築スクリプトの中に登場する yumadm も全て置き換える必要がある。
  2. Apache の実行ユーザ apache を yumadm グループにも属させる。つまり usermod -G yumadm apache
  3. /home/yumadm/ のパーミションを 0750 にする。 apache がアクセスできるようにするため。もっと厳格にしたければ 0710。ここまでの作業は root で行うが、以後の手順は全て yumadm ユーザ権限で行う。
  4. 構築ツールを置く ~yumadm/repotools/ ディレクトリと、公開ディレクトリの根本となる ~yumadm/pub/ ディレクトリを作成。
  5. repotools/cd して make-redhat-mirror, make-apt, get-updates シェルスクリプトを配置し、ともに実行ビットを立てる。また、yum-2.2以降で使う人は make-apt へのシンボリックリンク make-yum2 も作成しておく。
  6. ./make-redhat-mirror full 4ES を実行する -> ~yumadm/pub/package/ 下のディレクトリツリーが出来上がる。引数の意味は make-redhat-mirror を引数なしで実行してみれば分かる。
  7. アップデートCD からパッケージを吸い上げる行程に入る。まず RedHatアップデートCDをマウントする。マウントポイントが /media/cdrom 以外の場合は get-updates スクリプト冒頭の MOUNTP 変数の値を変えていただきたい。さらに、 CD-ROM などではなく、全く別のところ (例えば自身の yum クライアントのキャッシュ済みRPMパッケージ) から拾ってくることも可能で、そうしたい場合には、デフォルトでは "" になっている RPMSOURCE 変数にそのディレクトリを絶対指定すると、 MOUNTP を無視してそこがソースとして使用される。
  8. ./get-updates 4ES を実行する -> RPMがメディアから ~yumadm/pub/package/ 配下にアーキテクチャ別にコピーされる。これを CD枚数分繰り返す。アップデートでなく、システムのインストールに使用したフルセット (つまり yum の [base] 定義で参照するためのもの) をコピーしておきたい時には ./get-updates 4ES os とコマンド。ディストリビューション基本データ (comps.xml など、オリジナルインストールCD の /base/ディレクトリの内容) をコピーしたい場合には ./get-updates 4ES base とコマンドする (base についてはCD枚数分でなく1度だけでいい)。
  9. シンボリックリンクやメタデータを生成する。 yum-2.2以降用のレポジトリを整備する場合には、./make-yum2 full 4ES と行程 5 で作成したシンボリックリンクのほうをコールする。 2.0 系の場合は./make-apt full 4ES' を実行する (~yumadm/pub/up2date/ 以下の構造ができ、 ~yumadm/pub/package からのシンボリックリンクやら、必要なメタデータやらが作られる)。 なお、今回の用途では extra 区分はレポジトリにコピーしていないため 「extra ディレクトリにはパッケージがないので空のメタデータを作った」 という警告メッセージが出るが、実害はない。
  10. この ~yumadm/pub/up2date/Apachealias機能で /up2date/ として公開する。そのための Apache設定の肝は;
<Directory "/home/yumadm/pub/up2date">
 Options Indexes SymlinksIfOwnerMatch
 AllowOverride None
 Order allow,deny
 Allow from 127.0.0.1 192.168.0
</Directory>
 
alias /up2date/ "/home/yumadm/pub/up2date/"

Apache がシンボリックリンクを辿れることが必須だが、 FollowSymlinks よりは、多少なりとも安全性の高い SymlinksIfOwnerMatch のほうがいいだろう。また、Apache のその他の設定要件として以下の設定が必要だということが分かった;

クライアント側の設定

RedHat Enterprise Linux 4 ES + yum-2.2 以降の場合
  1. yum をインストール
  2. yum.repos.d/redhat.repo を作成。下記の /4ES/ の部分は /$releasever/ でも行ける。
    [updates]
    name=Red Hat Updates - $basearch
    baseurl=http://local_repo_uri/up2date/redhat/4ES/en/$basearch/updates/
    また、サーバ構築の行程 8 でベース(os) パッケージを取り込んだ場合は、下記のように [base] 定義を書けば、それも参照することができる。取り込まなかったのに書いてしまうと、エラーが出る。
    [base]
    name=Red Hat Base - $basearch
    baseurl=http://local_repo_uri/up2date/redhat/4ES/en/$basearch/os/
  3. yumレポジトリサーバ自身の yum.conf だけは、レポジトリ参照先が自分自身なので、上記の local_repo_uri 部分を localhost にしたほうがいいかもしれない。ただし、DNS や hosts ファイルでリゾルブできるのならば (普通はできるだろう)、敢えて localhost にしなければならない理由はない。
Fedora Core + yum-2.2以降の場合
  1. yum-2.2 以降をインストール。おそらく既にインストールされているだろう。
  2. yum.repos.d/fedora-updates.repo を編集。[updates-released]baseurl は下のような塩梅。これはレポジトリサーバ構築の時に yum公開ディレクトリを make-yum2 full FC4 などとして整備した場合だ。
    baseurl=http://local_repo_uri/up2date/redhat/FC$releasever/en/$basearch/updates/
    サーバ構築の行程 8 でベースパッケージを取り込まなかった場合は yum.repos.d/fedora.repofedora.repo.old などへリネームする。取り込んだ場合は、前記 RHEL 4 ES と同様に baseurl の最後を /os/ にすげ替えた [base] 定義を書く。
  3. yumレポジトリサーバ自身の yum.conf だけは、レポジトリ参照先が自分自身なので、上記の local_repo_uri 部分を localhost にしたほうがいいかもしれない。ただし、DNS や hosts ファイルでリゾルブできるのならば (普通はできるだろう)、敢えて localhost にする必要はない。