Ubuntu Weekly Recipe

第829回systemd-nspawn+pbuliderでパッケージのビルド環境を整え⁠別PCからビルドする

今回はsystemd-nspawnとpbuilderを組み合わせ、パッケージをビルドする環境を整えます。また、別のPCからマウントもしてみます。

ビルド環境を整える時期

Ubuntu 24.04.1 LTSがリリースされたということは、22.04 LTSから24.04 LTSへのアップグレードも有効になったということです。22.04 LTSユーザーも、そろそろ24.04 LTSへのアップグレードを考える時期になりました。ただしUbuntu Weekly Topicsでも紹介しているとおり、8月30日から当面の間アップグレードの告知は表示されないようになっています。

PPAなども含めたリポジトリにパッケージがある場合は特に困ることはありませんが、ピンポイントで新しいパッケージを使用したい場合には自前でビルド環境が必要となります。

systemd-nspawnとpbuilderを組み合わせてパッケージをビルドする環境は第659回でも紹介しましたが、3年半近い時間が経って少しやり方が変更されています。よって今回あらためて紹介することにしました。第659回ほど詳しくは解説しないので、必要に応じてそちらも参照してください。

メインPCとビルドPCの葛藤

ビルドは多コアのCPU(16コアなど)を使用すると速く済みます。しかし、そういったPCは得てして消費電力が多く、ということは排熱量も多くて特に夏場には辛いです。そのような理由からメインPCとは別に用意し、必要なときだけビルドPCを運用するのがベストという判断になります。

それはそれでいいのですが、どれもこれもビルドに時間がかかるパッケージというわけでもないので、多くの場合は牛刀割鶏となりがちです。ではやはりメインPCとビルドPCを兼用するのがいいのかという判断になります。しかしメインPCで時間がかかるパッケージをビルドすると、その間は何もできなくて不便です。

メインPCとビルドPCにそれぞれビルド環境を用意すると、今度はメンテナンスが面倒になります。

では、どうすればいいのか。ここで、データ自体はメインPCにおいて必要に応じてビルドPCからビルド環境をマウントすればいいことに気づきました。方法としては、NFS(Network File System)がまっさきに思い浮かびます。

はたして実用に足るのか試してみることにしました。

コンテナーを作成する

ではビルド環境を整えていきます。まずは必要なパッケージをインストールし、ユーザーを作成します。

$ sudo apt install systemd-container debootstrap
$ sudo mkdir -p /var/nspawn/noble
$ sudo debootstrap noble /var/nspawn/noble/
$ sudo systemd-nspawn -D /var/nspawn/noble/

これでコンテナーに入れたので、ユーザーを作成します。ユーザー名はここではikuyaとしますが適宜変更してください。

# useradd ikuya -G sudo -m
# passwd ikuya
(パスワードを2回入力する)
# exit

コンテナーをブートします。

$ sudo systemd-nspawn -b -D /var/nspawn/noble/

先ほど作成したユーザー名とパスワードを入力してログインしてください。

以降、コンテナー内での作業になります。

コンテナー内での初期設定

何はなくともまずはログインシェルを変更しましょう。

$ sudo chsh -s /bin/bash ikuya

一度ログアウトして再ログインしてください。

続けてリポジトリの情報を更新します。

sudo vi /etc/apt/sources.list

エディターはここではviとしていますが、お好みのものにしてください。また24.04 LTSでは/etc/apt/sources.list.d/ubuntu.sourcesのほうがいいのではと思われがちですが、検証したところではsources.listのほうがよかったくらいです。

中身は以下のようにしてください。

deb http://jp.archive.ubuntu.com/ubuntu noble main universe multiverse
deb-src http://jp.archive.ubuntu.com/ubuntu noble main universe multiverse
deb http://jp.archive.ubuntu.com/ubuntu noble-updates main universe multiverse
deb-src http://jp.archive.ubuntu.com/ubuntu noble-updates main universe multiverse

リポジトリ情報を更新します。

$ sudo apt update

シェルの補完を効かせたい場合はbash-completionパッケージをインストールし、一度ログアウトして再ログインします。

pbuilderの準備

pbuilderに必要なパッケージをインストールします。

$ sudo apt install ubuntu-dev-tools pbuilder arch-test --no-install-recommends

ここが大きな変更点その1で、必要なパッケージarch-testが追加されました。

続けて実際にpbuilder環境を構築します。

$ pbuilder-dist noble create

ビルドしたパッケージをビルド時にも使用できるようにD05depsを用意します。

$ sudo vi ~/pbuilder/noble_result/D05deps

中身は次のとおりです。

#!/bin/bash
(cd /home/ikuya/pbuilder/noble_result/; apt-ftparchive packages . > Packages && rm -f Packages.xz && xz Packages)
apt update

ここが大きな変更点その2で、第659回ではbzipで圧縮していたのが、今回はxzで圧縮しています。

さらに実行権限を付与して完了です。

$ chmod 755 pbuilder/noble_result/D05deps

pbuilderの設定は~/.pbuilderrcを作成し、以下の内容を記述してください。もちろんユーザー名は適宜書き換えてください。

# this is your configuration file for pbuilder.
# the file in /usr/share/pbuilder/pbuilderrc is the default template.
# /etc/pbuilderrc is the one meant for overwriting defaults in
# the default template
#
# read pbuilderrc.5 document for notes on specific options.
MIRRORSITE=http://jp.archive.ubuntu.com/ubuntu
UBUNTUTOOLS_UBUNTU_MIRROR=http://jp.archive.ubuntu.com/ubuntu/
APTCACHEHARDLINK=no
COMPONENTS="main restricted multiverse universe"
#for internal repo
OTHERMIRROR="deb [trusted=yes] file:///home/ikuya/pbuilder/noble_result ./"
BINDMOUNTS="/home/ikuya/pbuilder/noble_result/"
HOOKDIR="/home/ikuya/pbuilder/noble_result/"
EXTRAPACKAGES="apt-utils"

pbuilderを更新します。

$ cd ~/pbuilder/noble_result/
$ apt-ftparchive packages . > Packages && rm -f Packages.xz && xz Packages                                                             
$ cd -
$ pbuilder-dist noble update --override-config
$ pbuilder-dist noble update --override-config --othermirror "deb [trusted=yes] file:///home/ikuya/pbuilder/noble_result /|deb http://j
p.archive.ubuntu.com/ubuntu/ noble-updates main universe restricted"  --mirror http://jp.archive.ubuntu.com/ubuntu/ --components "main restr
icted universe multiverse"

試しに24.10開発版のVirtualBox 7.0.20をビルドしてみましょう。

$ pull-lp-source virtualbox oracular
$ time pbuilder-dist noble virtualbox_7.0.20-dfsg-1.dsc

今回の検証機であるAMD Ryzen 7 5800X[1]搭載PCでは9分21秒かかりました図1図2⁠。

図1 ビルドPCのスペック概要
図2 ネイティブでビルドした場合

ビルドPCからのビルド

作成したコンテナーをビルドPCからマウントできるようにします。具体的にはNFSを使用します。NFSの使用方法はドキュメントにあるとおりで、非常に簡単です。

NFSサーバーの設定は次のとおりです。

$ sudo apt install nfs-kernel-server
$ sudo systemctl start nfs-kernel-server.service
$ sudo vi /etc/exports 

/etc/exportsの中身は次のとおりです。

# /etc/exports: the access control list for filesystems which may be exported
#               to NFS clients.  See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes       hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4        gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes  gss/krb5i(rw,sync,no_subtree_check)
#
/var/nspawn  *(rw,async,no_subtree_check,no_root_squash)

次のコマンドを実行して、設定を適用します。

$ sudo exportfs -a

続けてクライアントの設定をします。ここからはビルドPCでの作業になります。

$ sudo apt install nfs-common
$ sudo mkdir /media/nspawn
$ sudo mount takao.local:/var/nspawn /media/nspawn
$ sudo systemd-nspawn -b -D /media/nspawn/noble/

takao.localはNFSサーバーのホスト名です。お察しのことでしょうが。

この状態でVirtualBox 7.0.20をビルドしてみると図3のようになりました。

図3 NFS経由でのビルド

16分程度かかり、ビルドマシンを使用したほうがはるかに遅くなりました。ビルドマシンのCPUはRyzen 9 7950Xで、5800Xよりもコア数とスレッド数が倍なので単純に半分の時間でビルドが完了するはずです。……ということはネットワークのトラフィックが足を引っ張っていると考えるのが自然です。世の中なかなかままならないものです。2.5GbEから10GbEへの移行など、ネットワークの高速化を検討する必要がありそうです。

おすすめ記事

記事・ニュース一覧