Debian Installer: preseed で pkgsel を実行しない方法

この記事は Debian/Ubuntu JP Advent Calendar 2012 の 12/23 の記事かもしれません。

最近 Debian Installerpreseed による自動ネットインストールで遊んでいます。表題のことをやろうと思ったら案外難しくて結構時間がかかってしまいました。大したことではないのですがせっかくなので記事にまとめました。

動機

私は Debian を愛用していますが、使わないパッケージがシステムに勝手にインストールされるのが我慢ならない性分なので、 Debian Installer を使うときはいつも Expert install (priority=low) で、必要なステップのみを選んでインストールするようにしています。

Debian Installer の各ステップの中でも “Select and install software” は最悪です。こいつをうっかり選んでしまうと tasksel の起動に加え、次のようなことをされてしまいます。

Expert install ならこれを避けることもできますが、そうでなければ自動的に各ステップを順番に実行されてしまうので、どうにかしてその挙動を変化させる必要があります。

そうはいっても Debian Installer に直接手を入れるのは面倒すぎるので、 preseed の設定だけでなんとかする方法を探すことにしました。

フック

Debian Installer の内部動作については Debian Installer internals という文書に詳しい説明があります。

Debian Installer のメインメニュー表示および進行は main-menu というパッケージの中の プログラム がやっています。メインメニューに表示される各ステップの実体は、 Installer-Menu-Item: 1800 といったヘッダを持つ udeb パッケージです。

最初これらのパッケージはシステムに展開されただけの半インストール状態 (unpacked) にされているので、 main-menu がそれらを順番に configure していく (postinst を実行する) ことでインストールは進行します。その途中で新たな udeb パッケージが展開されることで、選択可能なステップがメインメニューに動的に追加されたりします。

問題の “Select and install software” もその実体は途中で展開される pkgsel というパッケージに含まれる /var/lib/dpkg/info/pkgsel.postinst スクリプトとなっています。

ということで最初はこのパッケージの展開を阻止することを考えたのですが、これを行う net-retriever の動作を変更することは難しいことがわかり、断念しました。

そうなるとあとは pkgsel パッケージが展開された後で、その postinst を無力化するしかないということになり、そのようなコードを実行できるフックを探すことになります。

preseed で設定できる一般的なフックとして ドキュメント では preseed/early_command が紹介されていますが、これが実行される時点ではまだ pkgsel は展開されておらず、手を出すことができません。そこでこのフックはさらに後で実行される別の種類のフックを仕込むために使います。

先に紹介した Debian Installer internals には Available hooks という付録があり、フックを仕込むことができるポイントのリストがあります。

この中から pkgsel が展開された後かつ実行される前のフックということで探してみると、 base-installer (メインメニューの “Install the base system”) 完了後のフック /usr/lib/post-base-installer.d/* が使えそうなので、これを利用してみることにしました。このフックは run-parts 型のフックと呼ばれ、このディレクトリに実行可能ファイルを置いておけば、それらをすべて実行してくれます。

結論

ということで最終的に編み出された preseed は次のとおりです。

d-i preseed/early_command string a=/usr/lib/post-base-installer.d/99a && mkdir -p ${a%/*} && echo ">/var/lib/dpkg/info/pkgsel.postinst" >$a && chmod +x $a
d-i base-installer/excludes string nano,tasksel,tasksel-data

preseed/early_command は preseed の読み込み直後に実行され /usr/lib/post-base-installer.d/99a という実行可能なフックスクリプトを作ります。フックのディレクトリは base-installer が展開される前でまだ存在しないので、先にこれも作っておきます。

99a は base-installer 完了時に実行され /var/lib/dpkg/info/pkgsel.postinst を空にします。これにより main-menu により pkgsel が実行されても何もせず正常終了して次に進むようになり、 pkgsel を無効化するという目標を達成できたことになります。

またついでに base-installer/excludes で nano や tasksel といった使わないパッケージを最初からインストールしないようにしています。これは base-installer が実行する debootstrap の --exclude オプションに渡されます。

まとめ

Debian Installer のフックを活用して preseed だけで pkgsel の実行を阻止する手法を紹介しました。 Ubuntu のインストールでも基本的に一緒なので同じ方法が応用できると思います。よろしければ参考にしてください。

またこれよりもエレガントな手法があればぜひ教えて下さい。

2012/12/23 07:02:00 JST