How to create a Debian package of support to sysvinit, upstart, systemd

最近、サイボウズラボさんが開発した、yrmcdsというmemcached互換のKVSをDebianパッケージにして、main入りしました。 [1] いつもパッケージスポンサーをお願いしている 岩松さん 、upstreamの 山本さん のご協力のおかげです。 特に問題なければ、Ubuntuの次のLTSにも取り込まれるのではないかと思います。 お二人には、この場を借りてお礼申し上げます。

Python以外で、また、デーモンのパッケージ化は今回初めて行いました。 [2] sysvinitだけでなく、upstart, systemd対応も行ったので、デーモンのDebianパッケージを作成する場合のsysvinit, upstart, systemd対応の方法についてメモを残します。

sysvinit対応

sysvinitの対応は、dh_makeコマンドで生成されるテンプレートのdebian/init.dを使います。シングルバイナリパッケージの場合、ファイル名はdebian/init.dのままでも良いのですが、マルチバイナリパッケージの場合には、バイナリパッケージの名前をprefixにつけて、debian/<パッケージ名>.initのように変更します。yrmcdsのinit.dは sources.debian.net の次のURLで確認できます。 [3]

http://sources.debian.net/src/yrmcds/1.0.3-4/debian/yrmcds.init

check_for_upstart関数を定義し、/lib/lsb/init-functionsで定義されているinit_is_upstart関数を使って、upstartを使っている場合は、このスクリプト(つまり/etc/init.d/yrmcds)が実行されないようにしています。

upstart対応

upstartはテンプレートがありません。ファイル名は、debian/<パッケージ名>.upstartとして、upstart scriptを用意します。yrmcdsの場合、upstream側でetc/upstartが用意されています。upstreamのupstart scriptは、keepalivedの制御が入っていますが、Debianパッケージとしてはkeepalivedに依存するわけではないので、この部分はコメントアウトして、 debian/yrmcds.upstart としました。

systemd対応

systemdの場合は、debhelperのadd onとして、dh-systemdが用意されています。 ですので、まず、 debian/control のBuild-Dependsに、dh-systemdを追記します。

Build-Depends: debhelper (>= 8.0.0), (snip), dh-systemd (>= 1.5), (snip)

次に、 debian/rules の%ターゲットのdhコマンドのオプションとして、systemdを追記します。

%:
     dh $@ --with quilt,systemd

systemd用の設定ファイルは、upstartと同様テンプレートは用意されていません。debian/<パッケージ名>.serviceとして用意します。debian/yrmcds.service として作成します。

上記のみで、あとはdh-systemdが良きように設定してくれるのですが、これだけではpurge(apt-get purge)の時に残骸が残ります。 ですので、 postrm で下記のファイルを削除します。

  • /etc/systemd/system/yrmcds.service
  • /etc/systemd/system/multi-user.target.wants/yrmcds.service
  • /var/lib/systemd/deb-systemd-helper-enabled/yrmcds.service.dsh-also
  • /var/lib/systemd/deb-systemd-helper-enabled/multi-user.target.wants/yrmcds.service
  • /var/lib/systemd/deb-systemd-helper-masked/yrmcds.service

initの切替

debuildして作成したパッケージは、最小構成で作っておいたSidのVMを使ってテストを行います。パッケージ側ではsysvinit, upstart, systemdの切替の際に特に設定をすることはありません。 Debianはデフォルトではsysvinitになっているので、sysvinitからの切替が必要になります。upstartの場合は、upstartパッケージをインストールするだけで、sysvinitから自動的に切り替わります。 一方、systemdの場合は、systemdパッケージをインストールするだけでは、切り替わりません。今はブートローダーにGRUBを使っていることがほとんどだと思いますが、/etc/default/grubの GRUB_CMDLINE_LINUX_DEFAULTinit=/lib/systemd/systemd を追記し、 update-grub を実行する必要があります。 [4]

Footnotes

[1]2014/01/30現在のバージョンは 1.0.3-4 で、対応アーキテクチャは、linux-anyです。
[2]某所のローカルアーカイブ用には、FlaskやDjangoアプリ用にsysvinit対応のパッケージは作成していましたが、公式パッケージとしては初めてです。
[3]現状ではテンプレートの不要な処理をコメントアウトしただけの箇所が多いので、次のアップデートの時に削除する予定です。
[4]https://wiki.debian.org/systemd#Issue_.231:_sysvinit_vs._systemd-sysv