今回はsystemd-nspawnとpbuilderを組み合わせ、パッケージをビルドする環境を整えます。
筆者流ビルド環境の整え方
FlatpakやSnapパッケージの普及により自分でパッケージをビルドして最新版のアプリケーションを使用するという機会は確実に減っています。どうしてもパッケージをビルドする必要ができた時も、DockerだLXCだmultipassだクラウドだと、環境の作り方はさまざまです。いずれにせよ共通するのは、手元の環境を汚さないということです。
ビルド環境は維持するのか逐次作成するのかも悩みどころですが、あまり頻繁にパッケージのビルドを行わない場合はどこかのクラウドサービスを借りるのがいいでしょう。ビルドに必要なハードウェアリソースは、たまにしか使用しないのであれば外部サービスを使用したほうが安上がりです。もちろんビルドするパッケージにもよるのですが。
ローカルでビルドする場合はいかようにもすればいいのですが、ハードウェアリソースは自前で確保しなければなりません。特にビルド時間に影響を及ぼすのはそれなりの性能のCPU、メモリー、ストレージです。ビルドはどうしてもトライ&エラーの繰り返しとなることが多く、かといって1日は等しく24時間しかないため、ハードウェアリソースが潤沢な場合はそれだけトライ&エラーの回数を増やすことができるというわけです。
ソースパッケージをビルドするだけであれば、ローカルに必要なパッケージをインストールしてビルドすればいいでしょうが、PPAにアップロードする場合は、クリーンなビルド環境を用意する必要があります。厳密にいえば依存するパッケージが100%把握できている場合は不要といえばそうなのですが、ちょっと現実的とは思えません[1]。ただし毎回クリーンなビルド環境を使用するとオーバーヘッドが大きくなるため、併用できると便利でしょう。
というわけで、筆者は可能な限りクリーンなビルドを行いつつ、場合によってはローカルでビルドしています。「ローカルでビルド」とは、具体的にはdpkg-buildpackageコマンドを実行してパッケージをビルドすることを指しています。クリーンなビルド環境はpbuilderを使用しています。これらを同居するため、第491回で紹介したsystemd-npawnを使用してコンテナを作成します。
pbuilderで事前にビルドしたパッケージを依存関係で使用している、なんてこともよくあるわけですが、pbuilderをセットアップしただけでは自身でビルドしたパッケージを使用してビルドすることはできず、この問題の解決も重要です。
長くなりましたが、今回はsystemd-nspawnでコンテナを作成し、pbuilderでビルド環境を構築する方法を紹介します。
例としてUbuntu 20.04 LTS上で開発版の21.04のビルド環境を構築してみますが、18.04 LTS以降であればおおむねどの組み合わせでも対応できると思います。
必要なパッケージ
必要なパッケージをインストールします。次のコマンドを実行してください。
コンテナを作成する
systemd-nspawnの使い方は第491回に準じるのですが、今は少し簡単になっているので改めて紹介します。
まずはコンテナーを作成するフォルダーを作成し、debootstrapコマンドを実行します。作成するのは/var/nspawn/hirsuteとします。“hirsute”はUbuntu 21.04開発版のコードネームです。次のコマンドを実行してください。
“Base system installed successfully.”と表示されると完了です。開発版のdebootstrapコマンドは実行に失敗するタイミングもあるため、必ずこのメッセージが表示されることを確認してください。リリース後であれば、おおむね問題となることはないでしょう。
作成したコンテナーにはユーザーがないため、作成します。
コンテナーにログインできたので、ユーザーを作成します。作成するユーザーは“ikuya”としますので、適宜読み替えてください。
同じパスワードを2回入力し、一致した場合はパスワードの設定ができて準備完了です。ここまでできたら、一度ログアウトしてください。
いよいよコンテナを起動します。次のコマンドを実行してください。
以後はログインしたコンテナ内での作業となります。
コンテナの設定
コンテナにログインしたら、まずはログインシェルを変更します。/bin/shは使いにくいでしょう。次のコマンドを実行してください。
一度ログアウトして再ログインすると、見慣れたbashが起動しているでしょう。
リポジトリの情報を変更します。/etc/apt/sources.listを次のように変更してください。
次のコマンドを実行し、リポジトリの情報をアップデートしてください。
エラーが出ていないことを確認してください。
最低限エディターを変更し、bash-completionをインストールすることも必須でしょう。エディターは今回はvimとしますが、お好きなものにしてください。次のコマンドを実行してください。
一度ログアウトして再ログインするとbash-completionが有効になります。
コンテナであることをわかりやすくするため、ホスト名も変更したほうがいいでしょう。今回では例として“nspawn-hirsute”に変更します。次のコマンドを実行してください。
/etc/hostnameの設定はしてくれますが、/etc/hostsの設定はしてくれないので、“127.0.0.1 (ホスト名)”を追加してください(IPアドレスとホスト名の間に入っているのはタブです)。
やはり一度ログアウトして再ログインするとホスト名が変わっています。
コンテナの設定はキリがないのでこのぐらいにしておきます。
pbuilder環境を構築する
pbuilderももちろんコンテナー内に作成します。まずは必要なパッケージをインストールします。次のコマンドを実行してください。
pbuilder内部で使用するコンテナ(chrootイメージをtarで固めたもの)を作成します。次のコマンドを実行してください。
debootstrapと同じく、作成までしばらく時間がかかります。
"pbuilder/(コードネーム)_result/D05deps“を次の内容で作成します。今回の例ではもちろん”pbuilder/hirsute_result/D05deps"です。ただしユーザー名は適宜変更してください。
パッケージが作成されたフォルダーをリポジトリとするために必要な情報を作成し、リポジトリ情報を更新しています。シェルスクリプトにもなっているため、次のコマンドを実行して実行権限を付与してください。
pbuilderの情報は~/.pbuilderに設定します。次の内容にしてください。ただしユーザー名は適宜変更してください。
リポジトリとして機能するようにしておきます。次のコマンドを実行してください。
pbuilderの情報を更新します。次のコマンドを実行してください。
奇妙な感じですが、必ずこの順番で実行する必要があります。これでひととおり完了です。
試しにMozcをビルドしてみましょう。次のコマンドを実行してください。
1行目のコマンドでUbuntu 21.04開発版のリポジトリからMozcのソースパッケージを取得しています。2行目のコマンドでMozcをビルドしています、“.dsc”が付くファイルを引数の最後につけます。
dpkg-buildpackageコマンドでもパッケージをビルドしてみましょう。次のコマンドを実行してください。
コンテナを終了する
コンテナを終了する場合は次のコマンドを実行してください。
ホストで実行しないように注意してください。ホスト名が変更されているため、誤った操作はしないはずではあります。