Gentoo Linux (OpenRC) でinitスクリプトを書くには [多重起動編]
基本編から続く。
「楽をするためならどんな努力も惜しまない」のが、良いプログラマの条件なんだって。
それが正しいかどうかはともかく、確かに同じようなこと何度も繰り返すのは面倒だと思う。
例えば、こういう場合。
- 複数のWebアプリ、例えばSinatraでWebアプリを作った場合を考える。
- その場合、サービスを提供するにはWEBrickかThinを使うことが多い。
- そうすると、各Webアプリの起動方法は同じだが、起動オプションや設定ファイル (文書ルートやDBの接続先など) のみが異なることになる。
このように多くのWebアプリを、initシステムを使って管理する必要がある場合、細かいオプションのみ変えたinitスクリプトをたくさん作らないといけない……。
コピー&ペーストでもいいけど、数が多くなるとバグの温床になりそうだ。
これを解決するには、1つのinitスクリプトを異なる設定で起動できるようにして、initスクリプトと設定ファイルを分割して、多重起動できるようにする方向でがんばる。
今回は、こんなユースケースに対応するinitスクリプトをメモメモ。
initスクリプトの設定ファイル
initスクリプトは設定を外部化できる。場所は、
/etc/conf.d/
となる。ここに、サービス名と同名のファイルを置いておくと、initスクリプトを呼び出したとき、自動的に読み込んでくれる。具体的には、
# touch /etc/conf.d/hogehoge
# nano /etc/conf.d/hogehoge
# /etc/init.d/hogehoge
とすると、/etc/conf.d/hogehoge
の内容が読み込まれた後、/etc/init.d/hogehoge
が実行される。ここでは、hogehoge
がサービス名。
/etc/conf.d/hogehoge
の中には、変数 (もしかしたらちょっとしたロジックも) などを入れておく。具体例を挙げると、次の通り。
config_file="sample.conf"
...
...
start() {
...
ebegin "Starting Hogehoge with ${config_file}
...
}
...
/etc/init.d/hogehoge start
すると、
* Starting Hogehoge with sample.conf
と表示されるはず。
複数の設定ファイル
設定ファイルは、1つのサービスについて複数使用できる。
ただし、命名規則があり、
/etc/conf.d/service.config
形式である必要がある。
service
がサービス名、config
が設定名。
具体的にはこんなかんじだ。
/etc/conf.d/hogehoge.app1
/etc/conf.d/hogehoge.app2
/etc/conf.d/hogehoge.app3
initスクリプトの命名規則
以上のように設定ファイルの名前をつけておくと、1つのinitスクリプトで複数の設定を使用できる。
では、どうやって設定を切り替えるのか?
それには、シンボリックリンクを使う。こんなかんじだ。
# cd /etc/init.d
# ln -s hogehoge hogehoge.app1
# ln -s hogehoge hogehoge.app2
# ln -s hogehoge hogehoge.app3
そして、
# /etc/init.d/hogehoge.app1 start
とすれば設定app1
でhogehoge
が開始される。
設定ファイルの読み込み順序
# /etc/init.d/hogehoge.app1 start
としてサービスhogehoge
を起動した場合、設定ファイルは次のような順序で読み込まれる。
/etc/conf.d/hogehoge
/etc/conf.d/hogehoge.app1
/etc/init.d/hogehoge.app1
(実体は/etc/init.d/hogehoge
)
つまり、設定名がない設定ファイルが一番最初に読み込まれる。
これを利用して、共通設定や既定の設定は、サービス名と同名の設定ファイル (例では/etc/conf.d/hogehoge
) に保存しておくといい。
設定ファイルの中で依存関係を設定する
同じサービスなのに、設定によって依存関係が違ってしまう場合がある。
ある設定ではロガーが必要だけど、別の設定ではcronが必要とか。
この場合、設定ごとに依存関係を指定できる。
具体的には、設定ファイルの中で次のようにする。
rc_need cron
rc_use logger
...
要は、基本編で書いた依存関係を設定するコマンドに、rc_
をつけたもので指定する。
設定なしでのinitスクリプトの使用を禁止する
設定なしのinitスクリプトを使わせたくない場合がある。
その場合、こんなかんじで対応できる。
#! /sbin/runscript
service="${RC_SVCNAME%%.*}"
config="${RC_SVCNAME##*.}"
...
start() {
...
if [ ${config} == ${service} ]; then
eerror "Cannot start ${RC_SVCNAME} directly"
return
fi
...
}
...
service
にはサービス名が入る。config
には設定名が入る。
/etc/init.d/hogehoge.app1
なら、service == hogehoge
、config == app1
だ。
ただし、/etc/init.d/hogehoge start
とされた場合、service == hogehoge
、config == hogehoge
となる。
これを利用して、設定名が指定されていない場合、サービスを開始しないようにしているのが上記の例。
なんか黒魔法的なのですが、このあたりはbashのパラメータ展開を参照のこと。
内部で使われる変数
ついでなのでここでメモメモ。
initスクリプト内では、内部で設定するといろいろな動作に影響を与える内部変数がある。代表的なのは、
descirption |
サービスの説明文。 |
---|
など。
こんなかんじにする。
#! /sbin/runscript
...
service="${RC_SVCNAME%%.*}"
config="${RC_SVCNAME##*.}"
description="Service Hogehoge"
if [ ${config} != ${service} ]; then
description="${description} with ${config}"
fi
...
こうすると、
# /etc/init.d/hogehoge describe
で
* Service Hogehoge
となり、
# /etc/init.d/hogehoge.app1 describe
で
* Service Hogehoge with app1
と表示される。
以上、initスクリプト多重起動編でした。
次回に続く。