第485回 で紹介したaptlyを使えば、かんたんに自分専用のリポジトリを構築できます。作ったリポジトリを有効活用するためにはパッケージが必要です。そこで今回はARM用のバイナリパッケージをx86マシン上でビルドする方法を紹介しましょう。
Ubuntuにおける「バックポート」
Ubuntuの公式リポジトリには「バックポート 」という概念が存在します。Ubuntuにおけるバックポートリポジトリとは、より新しいリリースのUbuntuで提供されているパッケージを、ソースコードはそのままに古いリリース上でビルドしなおした上で古いリリースの公式リポジトリからも提供する仕組みです。
ここから先は、なぜバックポートが存在するのかという点を説明します。すぐにビルド環境を用意したい場合は、次のページ に移動してください。
何のためにこの仕組みが存在するのでしょうか。まず前提として、Ubuntuでは公式のパッケージリポジトリを運用しています。何かソフトウェアをインストールしたい場合は、原則としてそのパッケージリポジトリから取得・インストールを行うのです[1] 。公式のリポジトリでは、パッケージのバージョンアップや不具合に修正にあわせて公式のビルドサーバーがビルドを行ったバイナリパッケージを提供します。またその提供されるパッケージのバージョンはリリース毎に異なります。
[1] もちろん「原則」であって、ユーザーがそれを順守しなくてはならないということはありません。使いたいソフトウェアに応じてインストールする方法を変えるほうが便利なことも多いでしょう。最近は公式のツールですらsnapパッケージとしてインストールする方法を推奨するケースも増えています。
そのUbuntuリポジトリには「リリースしたあとはパッケージとして提供するソフトウェアのバージョンをあげない」という原則が存在します。より正確には6ヶ月の開発期間の後半ぐらいでリポジトリの「フリーズ」が宣言され、リリースまでは不具合修正に専念するため、リリース前からバージョンの固定が行われます。これはリリース後にむやみにバージョンを上げると、ディストリビューションの安定性に懸念が生じる可能性があるためです。もちろんまったくパッケージを更新しなくなるわけではありません。セキュリティアップデートへの対応、リリース後に見つかった不具合の修正などは、Ubuntuのサポート期間を通じて行われますし、それによって新しいパッケージが配布されることになります。
セキュリティ・不具合対応においては、なるべくパッケージの変更点を小さくなるように対応します。ソフトウェアの開発元が最新版のみ修正している場合は、修正箇所を抽出して取り込みます。よってパッケージそのもののバージョンはあがりますが、ソフトウェア本体のバージョンは原則として変わりません。これにより特定のリリース版を使い続けているそのソフトウェアについて詳しくないユーザーに対して、予期しないアップグレードによる混乱を与えないようにしているわけです。
とはいえ、最近はソフトウェアエンジニアリングの進歩により、個々のソフトウェアのリリース周期が非常に短くなっています。次のUbuntuリリースが行われた半年後には数十バージョンぐらい離されていたというケースもざらにあります。状況によってはFirefoxのように、一部のソフトウェアに対して例外的に新しいバージョンをそのまま既存のリリースに取り込むこともあります。しかし新しいバージョンを取り込む場合は、多くのユーザーに影響を与えるため、それなりに慎重な動作確認が必要になります。動作確認している間に次のリリースが出てしまう可能性だって起こりえます。
そこで出てくるのが「バックポートリポジトリ」です。このリポジトリは「バージョンをあげない」という制約を限定的に回避する公式の手段です。もしそのパッケージが、システムの他のコンポーネントに影響を与えない、もしくは最小限の影響にとどまるのであれば、Ubuntuでは比較的簡単な手続きでより新しいリリースからパッケージを公式リポジトリにバックポートできます。つまりUbuntu 17.10で使われているバージョンのソフトウェアを、そのままUbuntu 16.04 LTS上でリビルドして提供するのです。Ubuntuの不具合修正はスイートとして「RELEASE-updates」を、セキュリティ対応は「RELEASE-security」を指定しますが、バックポートの場合は「RELEASE-backports」を指定する必要があります。
この「RELEASE-backports」は他のスイートと比べると優先度が低くなっています。つまり「RELEASE-backports」がより新しいバージョンのパッケージを提供していたとしても、ユーザーが明示的に指定しない限り「RELEASE-backports」からはインストールしないのです。
たとえばUbuntu 16.04 LTSのLXDパッケージの場合、「 xenial-backports」からより新しい2.17が提供されています。しかしながら、実際にインストールされるのはもっとも優先度が高いスイートの、一番新しいバージョンである2.0.10です。もし「xenial-backports」パッケージをインストールしたければ、インストール時や更新時に「-t xenial-backports
」と明示的にスイートを指定する必要があります。
$ apt policy lxd
lxd:
インストールされているバージョン: 2.0.10-0ubuntu1~16.04.1
候補: 2.0.10-0ubuntu1~16.04.1
バージョンテーブル:
2.17-0ubuntu2~ubuntu16.04.1 100
100 http://jp.archive.ubuntu.com/ubuntu xenial-backports/main amd64 Packages
*** 2.0.10-0ubuntu1~16.04.1 500
500 http://jp.archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages
100 /var/lib/dpkg/status
2.0.2-0ubuntu1~16.04.1 500
500 http://security.ubuntu.com/ubuntu xenial-security/main amd64 Packages
2.0.0-0ubuntu4 500
500 http://jp.archive.ubuntu.com/ubuntu xenial/main amd64 Packages
ただし一度バックポートしてしまえば、公式リポジトリから普通のaptコマンドを使ってインストールできます。特別なリポジトリやリポジトリの鍵を追加する必要も何かインストールスクリプトをダウンロードする必要もないのです。これがPPAなどのサードパーティのリポジトリとの一番の違いでしょう。
当然のことながらバックポートパッケージを導入することは、程度の差こそあれ、Ubuntuの安定性を犠牲にすることでもあります。ユーザーは本当に必要なバックポートパッケージだけ導入するべきですし、必要かどうか判断できない場合は導入を避けるべきです。またバックポートによって更新されたパッケージは、Ubuntuのセキュリティチームによるセキュリティアップデートの対象外となることにも注意が必要です。
ARM向けバイナリのバックポート
このように公式リポジトリだけで完結するバックポートですが、もちろんバックポートが難しいパッケージも存在します。特に他のパッケージから使われうるライブラリやツールを提供するパッケージについては、そのパッケージに依存しているすべてのパッケージが期待通り動くことを確認しなくてはなりません。ライブラリの中身が変わるのであれば、他のパッケージの再ビルドも必要になるでしょう。言い方を変えると、広く利用されているライブラリはその確認作業の手間を考えるとバックポートを行うことは現実的ではありません。
もしローカルで使う特定のプログラムのためにライブラリのバージョンを変えたいのであれば、広く使われるバックポートは使用せず、たとえばPPAなどを使って特定の環境用という限定で提供すべきでしょう。しかしながらPPAを使う場合、リポジトリのサイズに上限があります。2GiB程度なので、よほど大きなプロジェクトでない限りあふれることはまずありませんし、申請すれば増やすことも可能ではありますが、上限があることは事実です。またタイミングによってはビルドサーバーが混んでいて、なかなかビルドされないこともあります。あとは当然のことですが、再配布可能なライセンス のものでない限りPPAにはアップロードできません。
特定のプロジェクト・ターゲット向けパッケージセットの構築を目的としてバックポートするのであれば、ローカルでビルドし、ローカルのリポジトリにアップロードできる環境があると何かと便利です。ローカルのリポジトリについては第485回 で紹介しましたので、今回は開発版のUbuntuからローカルにパッケージをバックポートし、それをARM用バイナリとしてビルドするところまでを紹介します。話の流れ上ARM固有の話もありますが、全体を通してアーキテクチャに依存しませんので、amd64やその他のアーキテクチャーでも参考になることでしょう[2] 。
armhf向けクロスビルド環境の準備
パッケージのビルドには「ネイティブビルド」と「クロスビルド」 、それに「QEMUを使ったビルド」の3種類の方法が存在します。一番確実なのはネイティブビルドです。しかしながらx86以外のアーキテクチャーの場合、ビルドに使えるターゲットマシンが必ずしも存在するわけではありません。速度の面ではクロスビルドが有利ではありますが、クロスビルドはアーキテクチャによって環境構築の手間が異なります。構築の手間とビルド時間のバランスを考えると、QEMUを使ったビルドになるでしょう[3] 。
[3] Launchpadの場合、OpenStackを用いて複数のホストマシンの上に仮想マシンとして複数台のビルドサーバーを用意しています。ARMについてもarm64のホストマシンの上にarm64・armhf・armelの仮想マシンを用意しているようです。以前はqemu-user-staticを使ったビルド方法を使っていました。また、特定のプロジェクト向けにPandBoardやBeagleBoardを使ったビルドクラスターを構築していました。どちらもスケールの面で難があったのですが、arm64+OpenStackになってからは、個人のPPAにもARMビルド機能が提供されています。
さらにQEMUを使ったビルドも、仮想マシンを作る方法と作らない方法があります。作る方法はカーネルから用意しなくてはなりません。今回は作らない方法を紹介します。
Debianパッケージを個人でビルドする場合、pbuider-distやcowbuilder-distを使うのが一番お手軽です。ただ残念ながら現在のpbuilder-dist/cowbuilder-distには、ホスト以外のアーキテクチャをビルドするとこける という問題が存在します[4] 。よって今回は、本家のビルドサーバー(buildd)でも使われているsbuild を用いてビルドしましょう。
まずは必要なパッケージをインストールして、いくつかの環境変数の設定、所属グループの追加を行います。
$ sudo apt install packaging-dev sbuild
$ cat >>~/.profile <<'EOSEOS'
export DEBFULLNAME='Mitsuya Shibata'
export DEBEMAIL='shibata@example.com'
EOSEOS
$ sudo usermod -aG sbuild $USER
(一度ログアウトしてログインし直す)
環境変数「DEBFULLNAME
」と「DEBEMAIL
」はDebianパッケージで使われるさまざまなスクリプトから参照される環境変数です。ここで設定した名前とメールアドレスはdebian/changelog
ファイルなどを経由して、作成したパッケージにアクセス可能なすべてのユーザーに公開されますので注意してください。
また第485回 などを参考に、GPG鍵も作っておいてください。この鍵はソースパッケージの署名に使います。自分自身でビルドし、自分自身で構築したリポジトリにアップロードするのであればGPG鍵を使う必要はないのですが、パッケージングのツールが要求してくることもあるので、作っておいたほうが便利です。今のうちに使い慣れておけば、将来的に公式リポジトリのパッケージの開発に携わる際に役に立つでしょう。ちなみに作ったGPG鍵は、原則としてDEBEMAILの値を使ってツールから参照することになるため、作成時に値を合わせておきましょう。
さっそくarmhfアーキテクチャー用のビルド環境を構築しましょう。環境構築にはsbuild標準のsbuild-createchroot
コマンドと、ubuntu-dev-toolsパッケージのmk-sbuild
コマンドの両方を使えます。今回はpackaging-dev経由でubuntu-dev-toolsパッケージをインストールしているため、作成時のオプションを減らせるmk-sbuild
を使います。ビルドサーバーの様に必要最低限なビルドマシンを構築するのであればsbuildパッケージのみをインストールしてsbuild-createchroot
を使うと良いでしょう。
$ mk-sbuild --arch=armhf xenial
(中略)
Done building xenial-armhf.
To CHANGE the golden image: sudo schroot -c source:xenial-armhf -u root
To ENTER an image snapshot: schroot -c xenial-armhf
To BUILD within a snapshot: sbuild -A -d xenial-armhf PACKAGE*.dsc
To BUILD for : sbuild -A -d xenial-armhf --host PACKAGE*.dsc
最後の「xenial
」はリリース名です。Ubuntu 16.04 LTS以外の環境を構築したいのであれば、それにあわせてリリース名を変更してください。たとえばDebianの開発版なら「sid
」を指定します。「 --arch
」オプションで対象アーキテクチャーを指定しています。省略するとホストと同じアーキテクチャーが指定されます。最終的に「/var/lib/schroot/chroots/RELEASE-ARCH
」なビルド環境が構築されるはずです。ちなみにリリースは同じでも別名の環境を構築したい場合は、「 --name
」オプションを指定してください。
今回の場合は、/var/lib/schroot/chroots/xenial-armhf
が作られているはずです。
$ ls /var/lib/schroot/chroots/xenial-armhf
bin build etc lib mnt proc run srv tmp var
boot dev home media opt root sbin sys usr
また個々の環境の定義ファイルは、/etc/schroot/chroot.d
以下に作成されます。
これで開発環境の事前準備は完了です。
既存のパッケージをそのままバックポートする
パッケージをバックポートしたい場合は、一般的に以下のステップを経ます。
バックポート元のリリースからソースパッケージを取得する
必要に応じてパッケージの中身を修正する
debian/changelogにバックポートする旨のエントリを追加する
debian/changelogのバージョンをバックポートに即した値にする
ソースパッケージを再構築する
ソースパッケージをビルド・テストする
ソースパッケージをビルドサーバーにアップロードする
このうち「バージョンをバックポートに即した値にする」部分ですが、これは将来的なアップグレードを見越して値を決める必要があります。
たとえばUbuntu 16.04 LTSでv1.0、17.10でv2.0なパッケージがあったとします。v2.0のパッケージを16.04にバックポートする際にバージョンをv2.0に設定しそれをインストールしてしまうと、将来17.10にアップグレードする際に、16.04と17.10の同名のパッケージが同じバージョンになってしまいます。その結果として、そのパッケージは更新されません。
バージョンが大きくなっているので更新される:
v2.0(16.04用) > v1.0(16.04用)
バージョンが同じなので更新されない:
v2.0(17.10用) = v2.0(16.04用)
つまり16.04でビルドされたパッケージがそのまま17.10で使われてしまうのです。しかしながら16.04と17.10の間で関連するライブラリなどが変更されている場合、本来であればこのパッケージも更新されないといけません。そこでバックポートのパッケージにバージョンを付ける場合は、「 バックポート先のパッケージより新しいけれども、バックポート元のパッケージよりは古いと判定されるバージョン」を付ける必要があるのです。
もしバックポート対象のソースパッケージをそのままバックポートできるのであれば、backportpackage
コマンドを使うのが便利です。上記の2.と6.や7.以外の作業はすべて自動的に行ってくれます。さらに6.や7.についてもオプションで対応可能です。たとえばtmuxパッケージはUbuntu 16.04 LTSだと2.1ですが、開発中の17.10だと2.5になっています。これをそのままバックポートしてみましょう。
$ mkdir -p ~/backport/tmux && cd $_
$ backportpackage -s artful -d xenial -w . tmux
backportpackage: Downloading tmux_2.5.orig.tar.gz from archive.ubuntu.com (0.454 MiB)
backportpackage: Downloading tmux_2.5-3build1.debian.tar.xz from archive.ubuntu.com (0.012 MiB)
dpkg-source: info: extracting tmux in tmux-xenial
(中略)
dpkg-buildpackage: source package tmux
dpkg-buildpackage: source version 2.5-3build1~ubuntu16.04.1
dpkg-buildpackage: source distribution xenial-backports
(中略)
次のユーザの秘密鍵のロックを解除するには
パスフレーズがいります:"Mitsuya Shibata <shibata@example.com>"
(中略)
Successfully signed dsc and changes files
これだけです。「 -s artful
」が取得元のリリース名(artfulは17.10のリリース名)であり、「 -d xenial
」がバックポート先のリリース名です。「 -w .
」で作業ディレクトリを指定し、最後にパッケージ名を指定します。
実行ログを眺めると、ソースパッケージを取得し、changelogエントリを追加し、バージョンを設定し、ソースパッケージを再構築してくれていることがわかります。ソースパッケージを公式のビルドサーバーにアップロードする際は、「 その人が作った」ことを確実に保証するためにGPG鍵で署名を行う必要があります。dscファイルとchangesファイルにそれぞれ署名しますので、gpg-agentを使っていない環境であれば2回パスフレーズの入力が必要です。
実際には以下のようなファイルが生成されます。
$ ls
tmux_2.5-3build1.debian.tar.xz
=> artfulのパッケージデータ
tmux_2.5-3build1.dsc
=> artfulのソースパッケージ情報ファイル
tmux_2.5-3build1~ubuntu16.04.1.debian.tar.xz
=> xenialにバックポートしたパッケージデータ
tmux_2.5-3build1~ubuntu16.04.1.dsc
=> xenialにバックポートしたソースパッケージ情報ファイル
tmux_2.5-3build1~ubuntu16.04.1_source.build
=> ソースパッケージの構築ログ
tmux_2.5-3build1~ubuntu16.04.1_source.changes
=> ソースパッケージの変更情報
tmux_2.5.orig.tar.gz
=> tmuxオリジナルのソースコードアーカイブ
Debianパッケージのソースパッケージは、パッケージの情報を記載したdscファイルと、オリジナルのソースコードであるorig.tar.gz、さらにはオリジナルからの変更点やパッケージビルドに必要なスクリプトなどを格納したdebain.tar.xzファイルから構成されます。changesファイルは新しいソースパッケージ一式のリストを記載したファイルです。
dscファイルのファイル名から、artfuのバージョンは「2.5-3build1
」だったことがわかります。さらに今回作ったバックポートパッケージは「2.5-3build1~ubuntu16.04.1
」になっています。この「~
」がポイントです。Debianパッケージのバージョンルールでは「~
」は特殊な扱いとなっており、「 2.5-3build1
より古いバージョン」という意味を持たせたかったら、「 2.5-3build1~FOO
」のような付け方ができるのです。
さらにbackportpackageはUbuntu 16.04 LTS向けの最初のバックポートということで、「 ubuntu16.04.1
」というバージョンを後置しています。このバックポートパッケージを大元のバージョンを変えずに更新する場合は、「 ubuntu16.04.2
」「 ubuntu16.04.3
」と変更していくというわけです。
バージョンの関係:
2.5-3build1 > 2.5-3build1~ubuntu16.04.2 > 2.5-3build1-ubuntu16.04.1 > 2.5-3build0
作られたソースパッケージを展開してみましょう。ソースパッケージは「dpkg-source -x
」で展開できます。
$ dpkg-source -x tmux_2.5-3build1~ubuntu16.04.1.dsc
$ head tmux-2.5/debian/changelog
tmux (2.5-3build1~ubuntu16.04.1) xenial-backports; urgency=medium
* No-change backport to xenial
-- Mitsuya Shibata <shibata@example.com> Fri, 01 Sep 2017 23:03:28 +0900
tmux (2.5-3build1) artful; urgency=medium
* No-change rebuild against libevent-2.1-6
きちんと新しいchangelogエントリが追加されていることがわかりますね。これでソースパッケージの作成は完了です。もしソースパッケージの内容も変更したいのであれば、展開したあとに適切な対応を行った上で、dpkg-buildpackage
コマンドなどでソースパッケージを生成することになります。変更対象や変更内容によっては、git-buildpackage
のようなbackportpackage以外のパッケージングツールとも組み合わせたほうがいいかもしれません。このあたりの話はまた別の機会に。
ちなみにリポジトリからバイナリパッケージをダウンロード・展開したい場合は「 apt download PACKAGE && dpkg-deb -x PACKAGE_VERSOION.deb DIRECTORY
」を実行します。単にパッケージの中のファイルのリストを取得したければ「less PACKAGE_VERSION.deb
」でもかまいません。lesspipeが適切に展開してくれます。
パッケージをビルドする
さてソースパッケージも無事に作られたので、これをビルドしてバイナリパッケージとしましょう。先ほど構築したsbuildの環境を使います。といっても、コマンドをひとつ実行するだけです。
$ sbuild -A --arch=armhf --dist=xenial tmux_*ubuntu16*.dsc
sbuild (Debian sbuild) 0.67.0 (26 Dec 2015) on ubuntu-desktop
+==============================================================================+
Wide character in print at /usr/share/perl5/Sbuild/Base.pm line 90.
| tmux 2.5-3build1~ubuntu16.04.1 (armhf) 01 9月 2017 23:45 |
+==============================================================================+
Package: tmux
Version: 2.5-3build1~ubuntu16.04.1
Source Version: 2.5-3build1~ubuntu16.04.1
Distribution: xenial-armhf
Machine Architecture: amd64
Host Architecture: armhf
Build Architecture: armhf
(中略)
Build Architecture: armhf
Build-Space: 11816
Build-Time: 374
Distribution: xenial-armhf
Host Architecture: armhf
Install-Time: 91
Job: tmux_2.5-3build1~ubuntu16.04.1.dsc
Machine Architecture: amd64
Package: tmux
Package-Time: 680
Source-Version: 2.5-3build1~ubuntu16.04.1
Space: 11816
Status: successful
Version: 2.5-3build1~ubuntu16.04.1
--------------------------------------------------------------------------------
Finished at 20170901-2356
Build needed 00:11:20, 11816k disc space
とっても簡単ですね。「 -A
」を指定すると設定ファイルなどのアーキテクチャーに依存しないファイルだけが含まれたパッケージも一緒にビルドします。「 --arch
」と「--dist
」は構築時と同じようにアーキテクチャーとリリース名です。最後にビルドするパッケージのdscファイルを渡します。
amd64マシンでarmhf用のパッケージを構築する場合、qemu-user-staticを使うためにビルド時間はそれなりにかかります。ビルドに成功すれば、次のようなファイルがカレントディレクトリに追加されるはずです[5] 。
tmux_2.5-3build1~ubuntu16.04.1_armhf-20170828-1445.build
=> ビルドログ
tmux_2.5-3build1~ubuntu16.04.1_armhf.build
=> 上記ファイルへのシンボリックリンク
tmux_2.5-3build1~ubuntu16.04.1_armhf.changes
=> バイナリパッケージの変更情報
tmux_2.5-3build1~ubuntu16.04.1_armhf.deb
=> バイナリパッケージ
ビルドエラーが発生した場合は、.build
のログを随時確認することになります。
本来必要なのは.deb
ファイルなのですが、「 リポジトリにアップロードする」のであれば.changes
ファイルを指定することになるでしょう。.changes
ファイルには作成したバイナリパッケージの情報と.deb
ファイルのハッシュが記載されています。ソースパッケージと同様に、.changes
に作成者のGPG鍵で署名することで、バイナリパッケージ一式の正当性を担保するわけです[6] 。
[6] UbuntuやDebianの一般的な開発フローにおいて、「 バイナリパッケージをどこかにアップロードする」ことは原則としてありません。基本的に開発者はソースパッケージ一式を提供しするだけです。その後、適切な権限を持った人がビルドサーバーに配置し、ビルドサーバーがビルドしたバイナリパッケージが自動的・半自動的にリポジトリに配置されることになります。
このようにすでに存在するパッケージをビルドするだけなら、とてもかんたんです。もちろん「きちんと動く」ようにするまでにはトライアンドエラーを繰り返すことになるのですが、バックポートパッケージであればより新しいリリースでは動作した実績があるパッケージですので、新規に作るよりは手間は少ないでしょう。
また第311回 でも言及しているように、作成したソースパッケージやバイナリパッケージに対してlintianやpiuparts、autopkgtestを用いたパッケージのテストを行っておくと、パッケージ品質を保証できますし、余計なトラブルを防止できます。こちらも合わせて使い方を覚えておくと良いでしょう。
sbuild環境のカスタマイズ
このようにsbuildを使えば、公式のリポジトリを用いて簡単にビルドできます。しかしながら、PPAからパッケージを取得したい、ローカルミラーを使いたいなど、公式リポジトリ以外も使いたい場合は、別途設定を行わなくてはなりません。そこで最後にsbuild環境のカスタマイズ方法をいくつか紹介しておきましょう。
ビルド環境の中身を変更する
sbuildはビルド環境の構築にschrootというコマンドを使用しています。schrootは普通のchrootコマンドと異なりセッションという概念を持っており、schrootを実行した段階でセッションを開始し、セッションを終了した時点でセッション内で行われた変更を破棄します。このセッションのマスターイメージ(ソース)となるのが、/var/lib/schroot/chroots/
以下にあるディレクトリです。もしビルド環境を恒久的に書き換えたい場合は、次のように、sourceタイプの名前空間を指定した上でchroot環境にログインしましょう。
$ sudo schroot -c source:xenial-armhf -u root
W: Failed to change to directory ‘/home/shibata’: No such file or directory
I: The directory does not exist inside the chroot. Use the --directory option to run the command in a different directory.
W: Falling back to directory ‘/root’
(xenial-armhf)root@ubuntu-desktop:~#
(何か変更を加える)
(xenial-armhf)root@ubuntu-desktop:~# exit
ポイントは「source:xenial-armhf
」の部分です。「 source:
」プレフィックスをつけることで、マスターイメージを指定することになります。ちなみにschrootコマンドはchrootしたら、カレントディレクトリに移動しようとするため、上記のように警告メッセージが出てしまいます。
なお、schrootの「-c
」で指定できるchroot環境は、「 -l
」でリストアップできます。
$ schroot -l
chroot:xenial-amd64
chroot:xenial-armhf
source:xenial-amd64
source:xenial-armhf
「chroot:
」は名前空間を指定しなかったときに使われる環境です。もし特にマスターイメージに変更を加える必要がなく、単純にchroot環境内での動作を確認したいだけであれば、次のようにプレフィックスなしで実行しましょう。
$ schroot -c xenial-armhf
このセッションで行った変更は、exitすると基本的に破棄されます。rootとしてログインしたければ、「 -u root
」をつけてください。
sbuild実行時に一時的に環境を変更したい場合は、sbuildの「EXTERNAL COMMANDS」の機能を利用できます。かなり細かく制御できますので、詳細についてはsbuildのmanページのEXTERNAL COMMANDS を参照してください。
パッケージリポジトリのURLを変更する
「jp.archive.ubuntu.com」のような公式ミラーを使いたい場合や、apt-cacher-ngなどで作ったミラー・キャッシュリポジトリを参照したい場合、/etc/apt/sources.list
を書き換える必要があります。一度作ったschroot環境であれば、前項のようにマスターイメージを書き換えるという手が使えます。
mk-sbuild
の時点で変更したい場合は、オプションもしくは環境変数でリポジトリのURLを変更できます。
オプションの場合は「--debootstrap-mirror=http://jp.archive.ubuntu.com/ubuntu
」
環境変数の場合は「DEBOOTSTRAP_MIRROR=http://jp.archive.ubuntu.com/ubuntu
」
毎回指定するのが面倒であれば、~/.mk-sbuild.sources
に/etc/apt/sources.list
に相当するファイルを作っておけば、それが使われます。ちなみに「RELASE
」という文字列は自動的にmk-sbuild時に指定したリリース名に置き換わります。
ちなみに「~/.mk-sbuild.rc
」に環境変数を設定しておくと、mk-sbuild時はそのファイルが読み込まれますので、そちらを使うという手もあります。
パッケージリポジトリを追加する
ミラーではなく、PPAなどの外部のパッケージリポジトリを追加したい場合は、sources.listの変更に加えてリポジトリ鍵の追加が必要になります。恒久的に追加したい場合はやはりマスターイメージを書き換えるのが一番確実です。
もしあるパッケージをビルドしたいときに、一時的に有効にしたい場合であれば、sbuildのオプションを指定するという手もあります[7] 。この方法であれば、sbuildコマンド時に指定することになるので、マスターイメージは書き換わりません。
[7] たとえばあるライブラリパッケージと、それに依存するもうひとつのパッケージをビルドしたい場合などが相当します。ライブラリパッケージができたら、それをPPAやローカルリポジトリにアップロードした上で、そのリポジトリを指定してもうひとつのパッケージをビルドする手順が必要です。
リポジトリのURL:「--extra-repository="deb http://ppa.launchpad.net/USER/PPA/ubuntu RELEASE main"
」
リポジトリのGPG鍵:「--extra-repository-key=KEY.asc
」
上記はPPAの例です。USERはPPAを提供するユーザーの、PPAはそのPPAの名前を、RELASEはインストール先のリリース名になります。実際の例は対象のPPAのページの「Technical details about this PPA」をクリックすると、sources.listに記載する内容が示されていますので、それを参考にしてください。
リポジトリを追加する場合は、原則としてそのリポジトリのGPG鍵を設定する必要があります[8] 。PPAの場合は、上記と同様にPPAのページから鍵IDを確認できますので、keyserverから取得するという手があります。
$ gpg --keyserver keyserver.ubuntu.com --recv 鍵ID
$ gpg --export --armour '鍵ID' > KEY.asc
$ gpg --delete-key '鍵ID'
PPA以外であれば、何らかの方法でリポジトリのGPG鍵を提供しているはずなので、それを利用してください。
ちなみに「--extra-package=PACKAGE.deb
」を指定すると、そのパッケージファイルがリポジトリに存在するかのように設定されます。一時的に特定のパッケージだけ、依存関係として指定したい場合に便利です。
sbuildの全体の動作を設定する
sbuildはビルドサーバーとして使われていることもあって、ビルド時のイベントごとのフックやユーザー管理などを細かく設定できます。基本的に/etc/sbuild/sbuild.conf
に設定することになるのですが、個々のユーザーごとの設定を「~/.sbuildrc
」として記述することも可能です。
設定例やデフォルト値は/etc/sbuild/sbuild.conf
や/usr/share/doc/sbuild/examples/example.sbuildrc
を参照してください。たとえばビルド完了時のメール通知や、lintian、piupartsの実行なども設定で変更できますし、先ほどの「EXTERNAL COMMANDS」も設定ファイルの中に落としこむことが可能です。
このようにsbuildを使うと、本格的なパッケージビルドサーバーとしても運用できるのです。