debuild で一度に複数のパッケージ作る時のメモ
Tags: debuild
Published: 2020-03-26 00:45:01

 [@yoshimo](https://twitter.com/m_yoshimo) です。
debuild で一度に複数のパッケージを作ることが多いので、メモ代わりに残します。

# 概要

ちょっとした HTTP Server アプリ作った時に、ポート番号や URI を production や staging といった環境で変えたい。
chef や ansible といったオーケストレーションツールだったり、Cloud インスタンス側の環境変数を使えば良いんだけど、オーケストレーションツール使うほどでもなく、でも変更履歴くらいは管理したい。

お手軽に config パッケージで管理する程度で良いが、git の repository は増やしたくない。

ということで、複数のパッケージを一度の debuild で作れるようにしておけば良いやってことで、備忘録的に最低限何を記述すれば出来るのか記載しておきたいと思います。

# 前提

debian/rules の記載は CDBS を使うことを前提にしています。
CDBS については、有用な記事がいっぱい転がっているので、そちらを探してください。
[こことか](https://eng-entrance.com/linux-package-deb-create)

# configs

環境毎の設定ファイルは configs というディレクトリに置くことにします。
例えばこんな感じ。

```
$ ls -l configs/*
-rwxr-xr-x 1 m-yoshimo m-yoshimo 136  4月  5 15:26 configs/config.develop.yml
-rwxr-xr-x 1 m-yoshimo m-yoshimo 135  4月  5 15:26 configs/config.prod.yml
-rwxr-xr-x 1 m-yoshimo m-yoshimo 132  4月  5 15:26 configs/config.stg.yml

$ cat configs/config.prod.yml
port: 8080

$ cat configs/config.stg.yml
port: 80
```

# debian/control

debian/control で Package を複数定義します。

```
Source: my-http-server
Section: non-free
Priority: optional
Maintainer: Masanori Yoshimoto <masanori.yoshimoto@zenkigen.jp>
Build-Depends: debhelper (>= 9), cdbs
Standards-Version: 4.0.0

Package: my-http-server
Architecture: amd64
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: My HTTP server

Package: my-http-server-conf
Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Configuration of my-http-server for production

Package: my-http-server-conf-staging
Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Configuration of my-http-server for staging

Package: my-http-server-conf-development
Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Configuration of my-http-server for development
```

# debian/rules

```
#!/usr/bin/make -f

include /usr/share/cdbs/1/rules/debhelper.mk

DEB_DESTDIR_app = "debian/my-http-server"
DEB_DESTDIR_conf = "debian/my-http-server-conf"
DEB_DESTDIR_conf_stg = "debian/my-http-server-conf-staging"
DEB_DESTDIR_conf_dev = "debian/my-http-server-conf-development"
TARGET_DIR = "/opt/zenkigen/my-http-server"
SYSTEMD_PATH = "/etc/systemd/system"

install/my-http-server::
	install -pd $(DEB_DESTDIR_app)$(TARGET_DIR)
	install -pm 755 bin/my-http-server $(DEB_DESTDIR_app)$(TARGET_DIR)
	install -pd $(DEB_DESTDIR_app)$(SYSTEMD_PATH)
	install -pm 644 my-http-server.service $(DEB_DESTDIR_app)$(SYSTEMD_PATH)

install/my-http-server-conf::
	install -pd $(DEB_DESTDIR_conf)$(TARGET_DIR)
	install -pm 755 configs/config.prod.yml $(DEB_DESTDIR_conf)$(TARGET_DIR)/config.yml

install/my-http-server-conf-staging::
	install -pd $(DEB_DESTDIR_conf_stg)$(TARGET_DIR)
	install -pm 755 configs/config.stg.yml $(DEB_DESTDIR_conf_stg)$(TARGET_DIR)/config.yml

install/my-http-server-conf-development::
	install -pd $(DEB_DESTDIR_conf_dev)$(TARGET_DIR)
	install -pm 755 configs/config.develop.yml $(DEB_DESTDIR_conf_dev)$(TARGET_DIR)/config.yml
```

install を列挙するだけですね。
複数のパッケージがある場合は、debian ディレクトリ以下にパッケージ毎のディレクトリが生成されて、その下にインストール先が展開されます。
そのため、自動で生成される $(DEB_DESTDIR) 定数では対応できないので、各パッケージのディレクトリ ("debian/app" など) を指定します。

# rules と control 以外

1つのパッケージを作る時と変更はしなくてよいはず。
postinst とか使っている場合は注意が必要かもしれません。
試してないので後日試そうかと思います。

# debuild 成果物

こんな感じでパッケージが生成されます。

```
$ debuild -us -uc
(長いので省略。Warning とか出たら頑張って直して)

$ ls -la ../my-http-server*.deb
-rw-r--r-- 1 m-yoshimo m-yoshimo    1400  4月  5 16:47 my-http-server-conf-development_1.0.0_all.deb
-rw-r--r-- 1 m-yoshimo m-yoshimo    1398  4月  5 16:47 my-http-server-conf-staging_1.0.0_all.deb
-rw-r--r-- 1 m-yoshimo m-yoshimo    1386  4月  5 16:47 my-http-server-conf_1.0.0_all.deb
-rw-r--r-- 1 m-yoshimo m-yoshimo 3761490  4月  5 16:47 my-http-server_1.0.0_amd64.deb
```

# まとめ & デメリット

同じ repository で一度の debuild で app と conf のパッケージが作れるのでお手軽。
しかし、debian/changelog が共通なので、conf を修正するだけで app (ここでいう my-http-server_1.0.0) の version も上げないといけなくなります。
これは非常に良くないデメリットです。
また、バージョンが破綻することにもなります。

chef や ansible といったツールを使った方が良いでしょう。
Kubernetes なら ConfigMap といった環境変数使った方が良いと思います。