Mockで標準RPMをビルドする:「自分の環境では動く」エラーを根本から解決

Fedora tutorial - IT technology blog
Fedora tutorial - IT technology blog

「自分の環境では動くのに!」– すべてのパッケージ作成者を悩ませる問題

FedoraでRPMをパッケージングしたことがあるなら、こんなシナリオに心当たりがあるはずです。.specファイルを書き、rpmbuildを実行し、すべてが完璧に仕上がった。しかし、その.rpmファイルを新しいサーバーに持っていったり、顧客に送ったりすると、ライブラリ不足のエラーが続出する。最悪の場合、パッケージはインストールできても、バージョンの競合で実行時にクラッシュすることもあります。

Fedoraをメインマシンとして2年以上使っている開発者として、私はこの落とし穴をよく理解しています。個人のマシンは、さまざまな開発用ライブラリ(devel)、プラグイン、追加のビルドツールが混在する「戦場」になりがちです。ホストマシンで直接ビルドすると、rpmbuildはそれらの既存ライブラリを自動的に「勝手に」取り込んでしまいます。BuildRequiresにそれらを記述し忘れると、結果として他の環境に依存しきった不完全なパッケージが生まれてしまいます。

なぜローカル環境は常に「裏切り者」なのか?

問題は「環境汚染(Environment Pollution)」にあります。日常的に使用しているOSは、以下の3つの主な理由から、パッケージングの基準としては決して適切ではありません。

  • ライブラリの過剰: 他のアプリの依存関係が、意図せず現在のパッケージのビルド条件を満たしてしまうことがあります。例えば、古いプロジェクトのopenssl-develが残っていると、新しいアプリのビルド時にspecファイルへの記述を忘れていてもエラーが出ません。
  • ゴミ設定: 環境変数や/etc内の設定ファイルが、自分好みにカスタマイズされすぎています。
  • バージョンの混在: いつインストールしたかも覚えていないような、独自のglibcやカスタムライブラリを使用している可能性があります。

パッケージをどこでも動作させるには、絶対的に「クリーンな環境」が必要です。明示的に宣言したものだけが、その環境に存在することを許されるべきなのです。

環境隔離ソリューションের比較

最適なツールを選ぶ前に、私はさまざまな方法を試してきました:

  1. 仮想マシン (VM): ビルドのたびにVirtualBoxに新しいFedoraをインストールする方法です。非常にクリーンですが、非常に重いです。OSの起動と環境構築を待つのに、毎回少なくとも15〜20分はかかります。
  2. コンテナ (Podman/Docker): VMよりも大幅に高速です。しかし、ユーザー権限の管理、マウントポイント、異なるアーキテクチャのシミュレーション(Fedora上でRHEL向けにビルドするなど)は、依然として少し面倒です。
  3. Mockの使用: これはFedoraメンテナーの「黄金標準」です。Mockは最小限のchroot環境を作成し、依存関係を自動的にダウンロードし、作業終了後にすべてをきれいにクリーンアップします。

Mock – プロフェッショナルなパッケージ作成者の救世主

Mockを内部ツールのパッケージングに6ヶ月間使用してみて、これが最もプロフェッショナルなワークフローだと感じています。Mockはクリーンなビルドができるだけでなく、クロスバージョンビルドもサポートしています。Fedora 40を使用していても、コマンド1つでFedora 39やAlmaLinux 9向けにビルドすることが可能です。

1. クイックインストールと設定

Fedoraでは、Mockは公式リポジトリで提供されています。以下のコマンドを実行するだけです:

sudo dnf install mock

sudoを毎回使わずにMockを使用するには、自分のユーザーをmockグループに追加します:

sudo usermod -a -G mock $USER
newgrp mock

newgrpコマンドは権限を即座に適用します。もしうまくいかない場合は、一度ログアウトして再度ログインすれば完了です。

2. ソースRPM (SRPM) の作成

Mockは.specファイルから直接ビルドしません。入力として.src.rpmファイルが必要です。以下のコマンドで作成します:

rpmbuild -bs my-package.spec

このファイルは通常、~/rpmbuild/SRPMS/ディレクトリに生成されます。

3. Mockによるビルドの実行

いよいよMockの真価を発揮する時です。Fedora 40のx86_64アーキテクチャ向けにビルドすると仮定して、以下を実行します:

mock -r fedora-40-x86_64 --rebuild ~/rpmbuild/SRPMS/my-package-1.0-1.fc40.src.rpm

Mockの自動プロセスには以下が含まれます:

  • 新しいchrootディレクトリを作成し、コアパッケージ(bash, dnf, coreutils)をダウンロードします。
  • specファイルを解析して、BuildRequiresのリストを特定します。
  • それらの依存関係を隔離された環境に自動的にインストールします。
  • コンパイル、パッケージングを行い、完成したRPMファイルを出力します。

4. ログの確認とデバッグ

ビルド結果は/var/lib/mock/fedora-40-x86_64/result/に配置されます。以下の2つの重要なログファイルに注目してください:

  • build.log: コンパイルプロセスが記録されます。コードにエラーがある場合は、ここを確認してください。
  • root.log: 依存関係のインストールプロセスが記録されます。Mockが必要なライブラリを見つけられない場合、このファイルに理由が記載されています。

最適化のヒント:ビルド速度を3倍にする

Mockの弱点は、パッケージのダウンロードとchrootの展開に時間がかかることです。これを解決するために、私は常にハードディスクではなくRAM上のtmpfsを使用してビルドしています。これにより、平均的なパッケージのビルド時間を5分から2分未満に短縮できます。

tmpfsを有効にするには、以下のフラグを使用します:

mock -r fedora-40-x86_64 --plugin-option=tmpfs:max_size=4G --rebuild my-package.src.rpm

また、CentOS StreamやRHEL(EPEL経由)向けに頻繁にビルドする場合も、Mockは非常に強力にサポートします。-rフラグの後の値(例:epel-9-x86_64)を変更するだけで、Fedoraマシン上にRHEL標準の環境を構築できます。

Lời kết

Mockを使用することは、単に標準に従うだけでなく、自分自身を守ることでもあります。個人の環境に起因するくだらないエラーを完全に排除できます。アプリケーションをCOPRに公開したり、Fedoraのリポジトリに貢献したりする場合、Mockは不可欠なスキルです。ローカル環境に二度と騙されないようにしましょう!

Share: