第6章 ソフトウェアのパッケージ化
RPM パッケージマネージャーを使ったパッケージングプロセスの基本を学びましょう。
6.1. spec ファイルについて リンクのコピーリンクがクリップボードにコピーされました!
spec ファイルは、rpmbuild ユーティリティーが RPM パッケージをビルドするために使用する指示が記述されたファイルです。
仕様 ファイルは、一連のセクションで手順を定義することにより、ビルドシステムに必要な情報を提供する。これらのセクションは、spec ファイルの Preamble 部分と Body 部分で定義されます。
- Preamble セクションには、Body セクションで使用される一連のメタデータ項目が含まれています。
- Body セクションは、指示の主要部分を表します。
6.1.1. spec ファイルの Preamble の項目 リンクのコピーリンクがクリップボードにコピーされました!
RPM 仕様 ファイルの Preamble セクションで、以下の指示を使用してください。
| ディレクティブ | 定義 |
|---|---|
|
|
パッケージのベース名。 |
|
| ソフトウェアのアップストリームのバージョン番号。 |
|
| パッケージのバージョンがリリースされた回数。
初期値を |
|
| パッケージの簡単な一行の概要。 |
|
| パッケージ化するソフトウェアのライセンス。
|
|
| ソフトウェアの詳細情報の完全な URL (パッケージ化するソフトウェアのアップストリームプロジェクトの Web サイトなど)。 |
|
| パッチが適用されていないアップストリームソースコードの圧縮アーカイブへのパスまたは URL。このリンクの参照先は、パッケージャーのローカルストレージではなく、アクセスしやすく信頼性の高いアーカイブ保存場所 (アップストリームのページなど) である必要があります。
|
|
| 必要に応じて、ソースコードに適用する最初のパッチの名前。
|
|
| ソフトウェアのビルド対象アーキテクチャー。
ソフトウェアがアーキテクチャーに依存しない場合、たとえば、ソフトウェア全体をインタープリター型プログラミング言語で記述した場合は、値を |
|
|
コンパイル言語で記述されたプログラムをビルドするために必要なパッケージのコンマまたは空白区切りのリスト。複数の |
|
|
インストール後のソフトウェアの実行に必要なパッケージのコンマ区切りまたは空白区切りのリスト。複数の |
|
|
ソフトウェアが特定のプロセッサーアーキテクチャーで動作しない場合は、 |
|
|
ソフトウェアをインストールしたときに正常に機能させるために、システムにインストールしてはならないパッケージのコンマまたは空白区切りのリスト。複数の |
|
|
|
|
|
パッケージに |
6.1.2. spec ファイルの Body の項目 リンクのコピーリンクがクリップボードにコピーされました!
RPM 仕様 ファイルの 本文 セクションで、以下の指示を使用してください。
| ディレクティブ | 定義 |
|---|---|
|
| RPM でパッケージ化されているソフトウェアの完全な説明。この説明は、複数の行や、複数の段落にまでわたることがあります。 |
|
|
ソフトウェアのビルドを準備するための 1 つまたは一連のコマンド。たとえば、 |
|
| ビルド用にソフトウェアを設定するための 1 つまたは一連のコマンド。 |
|
| ソフトウェアをマシンコード (コンパイル言語の場合) またはバイトコード (一部のインタープリター言語の場合) にビルドするための 1 つまたは一連のコマンド。 |
|
|
ソフトウェアのビルド後に、
|
|
| ソフトウェアをテストするための 1 つまたは一連のコマンド (ユニットテストなど)。 |
|
| RPM パッケージによって提供され、ユーザーのシステムにインストールされるファイルのリストと、システム上におけるファイル配置場所のフルパスのリスト。
ビルド中に、
|
|
|
異なる |
6.1.3. spec ファイルの高度な項目 リンクのコピーリンクがクリップボードにコピーされました!
仕様 ファイルには、スクリプトレット、ファイルトリガー、トリガーなどの高度な項目を含めることができます。これらのディレクティブは、spec ファイルに影響するだけでなく、RPM からの情報を使用してシステムを更新することにより、結果として生成される RPM がインストールされるターゲットオペレーティングシステムにも影響します。
スクリプトレット、ファイルトリガー、およびトリガーは、ビルドプロセスではなく、ターゲットシステムへのインストールプロセスのさまざまな段階で有効になります。
- スクリプトレットは、パッケージがインストールまたは削除される前または後に無条件に実行されます。
- トリガーは、指定されたトリガー条件が、インストール済みのシステム上またはトランザクション内の他のパッケージと一致した場合に、条件付きで実行されます。
- ファイルトリガーは、指定されたパス接頭辞が、インストール先のシステム上またはトランザクション内の他のファイルと一致した場合に、条件付きで実行されます。
6.1.3.1. スクリプトレットのディレクティブ リンクのコピーリンクがクリップボードにコピーされました!
スクリプトレットは、パッケージのライフサイクルに関連する、あらかじめ決められたタイミング (パッケージのインストールや削除の前後など) で実行される任意のプログラムです。スクリプトレットは、ビルド時または起動スクリプトでは実行できないタスクにのみ使用してください。
デフォルトでは、スクリプトレットは、spec ファイル内のさまざまな %pre または %post ディレクティブによって宣言される短いシェルスクリプトです。
一般的なスクリプトレットのディレクティブは、%build や %install などの spec ファイルのセクションヘッダーに似ています。複数行のコードのまとまりとして定義され、多くの場合、標準の POSIX シェルスクリプトとして記述されます。ただし、ターゲットマシンのディストリビューションの RPM が対応している他のプログラミング言語で記述することもできます。
6.1.3.2. スクリプトレットのディレクティブの実行順序 リンクのコピーリンクがクリップボードにコピーされました!
パッケージのアップグレード中にスクリプトレットが実行される順序を確認してください。
| ディレクティブ | 説明 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6.1.3.3. スクリプトレットの実行をオフにする リンクのコピーリンクがクリップボードにコピーされました!
スクリプトレット名に --no オプションを指定することで、任意のスクリプトレットの実行を無効にできます。
--noscripts オプションを使用することもできます。これは、次のすべてのスクリプトレットの実行をオフにするのと同じです。
-
--nopre -
--nopost -
--nopreun -
--nopostun -
--nopretrans -
--noposttrans -
--nopreuntrans -
--nopostuntrans
詳細は、システム上の rpm man ページを参照してください。
手順
スクリプトレットの実行をオフにします。
# rpm --no<scriptlet_name>たとえば、
%pretransスクリプトレットの実行をオフにするには、次のように入力します。# rpm --nopretrans
6.1.3.4. スクリプトレットのマクロの例 リンクのコピーリンクがクリップボードにコピーされました!
以下は、spec ファイル内のスクリプトレットに使用できるマクロの例です。これらのマクロは、systemd-rpm-macros パッケージによって提供される実際のマクロです。これらのマクロは、systemd 関連の処理をパッケージ化するために使用できます。同様の原則を他のパッケージに適用することもできます。
systemd ユニットファイルを含むパッケージは、systemd サービスを適切に処理するために、スクリプトレットを使用する必要があります。systemd パッケージは、systemd のスクリプトレット操作を処理するための一連のマクロを提供しています。以下に例を示します。
%post
%systemd_post httpd.service
%preun
%systemd_preun httpd.service
これらのマクロはパッケージ内で次のように展開されます。
$ rpm --eval "%systemd_preun httpd.service"
if [ $1 -eq 0 ] && [ -x "/usr/lib/systemd/systemd-update-helper" ]; then
# Package removal, not upgrade
/usr/lib/systemd/systemd-update-helper remove-system-units httpd.service || :
fi
マクロの動作は変更される可能性があります。たとえば、マクロの動作はパッケージの開発に応じて変更される可能性があります。
6.1.4. Epoch ディレクティブ リンクのコピーリンクがクリップボードにコピーされました!
Version spec ファイルディレクティブを設定するだけではパッケージのバージョンを比較できない場合は、Epoch ディレクティブを使用できます。たとえば、Epoch を 使用すると、上流でのバージョン番号付け方式の変更が互換性のない方法で行われたために発生したアップグレードパスの問題を解決できます。
Epoch は数値フィールドです。Epoch に値を割り当てると、パッケージのバージョンを比較するときに RPM が使用する修飾子が追加されます。spec ファイルに Epoch ディレクティブが記載されていないことは、Epoch が未設定であることを意味します。これは、Epoch を設定しないと Epoch は 0 になる、という一般的な認識とは異なります。ただし、処理上の理由から、RPM は Epoch が未設定であっても、Epoch が 0 に設定されている場合と同じように扱います。その逆も同様です。
通常、spec ファイル内での Epoch の使用は省略されます。これは、ほとんどの場合、Epoch 値を導入すると、パッケージのバージョンを比較するときに RPM の動作が予想と異なるものになるためです。したがって、Epoch の使用は最後の手段として検討してください。
たとえば、Epoch: 1 および Version: 1.0 で foobar パッケージをインストールしたとします。このとき、別のパッケージ作成者が、Epoch ディレクティブを指定せずに、foobar を Version: 2.0 でパッケージ化したとします。この場合、この新しいバージョンが更新版とみなされることは決してありません。RPM パッケージのバージョン管理を表す従来の Name-Version-Release マーカーよりも、Epoch のバージョンが優先されるためです。
6.1.5. パッケージのバージョン管理の基本 リンクのコピーリンクがクリップボードにコピーされました!
パッケージの説明の基本的な要素は、spec ファイルのディレクティブである Name、Version、および Release (NVR) で定義されている情報です。RPM はこの情報を使用してパッケージのバージョンを比較し、パッケージの依存関係を追跡します。
RPM を扱っていると、EVR (epoch-version-release)、NEVR (name-epoch-version-release)、NEVRA (name-epoch-version-release-architecture) という表記を目にすることもあるでしょう。EVR は、RPM が比較の際に常に使用するパッケージの完全なバージョン情報です。RPM は、最初のコンポーネントから 1 つずつコンポーネントを比較します。RPM は、コンポーネントの違いを検出すると比較を停止します。たとえば、Epoch が異なる場合、RPM は残りの EVR コンポーネントを比較しません。
RPM データベースを照会することで、特定のパッケージの NVR 情報を表示できます。次に例を示します。
# rpm -q bash
bash-4.4.19-7.el8.x86_64
ここでは、bash がパッケージ名で、4.4.19 がバージョン番号を示し、7.el8 がリリースを意味しています。x86_64 は、パッケージアーキテクチャーを示すマーカーです。アーキテクチャーマーカーは、NVR とは異なり、RPM パッケージャーが直接制御するものではなく、rpmbuild ビルド環境によって定義されます。アーキテクチャーに依存しない noarch パッケージは例外です。
rpm -q コマンドは、NEVRA 形式のパッケージ情報をデフォルトで表示します。