CentOSでデーモンの起動スクリプトを書く

CentOS上で動かすuWSGIをデーモンとして扱いたかったのですが、起動スクリプトを書いたことがなかったので少し調べてみました。

軽くググると/etc/init.d/skeletonにテンプレートファイルがあるという事だったのですが、手元のCentOSでは存在しませんでした。一方でUbuntuでは存在を確認できたのですが、UbuntuのテンプレートファイルをCentOSでそのまま流用はできないようです。

もう少し調べてみると、手元のCentOS 6.2の場合は下記のファイル内に、起動スクリプトのテンプレートが含まれていることがわかりました。(パス中の数字は環境によって異なりそうです。)

/usr/share/doc/initscripts-9.03.27/sysvinitfiles

上記ファイルからテンプレート部分を抜粋したものが以下になります。

#!/bin/bash
#
#       /etc/rc.d/init.d/<servicename>
#
#       <description of the *service*>
#       <any general comments about this init script>
#
# <tags -- see below for tag definitions.  *Every line* from the top
#  of the file to the end of the tags section must begin with a #
#  character.  After the tags section, there should be a blank line.
#  This keeps normal comments in the rest of the file from being
#  mistaken for tags, should they happen to fit the pattern.>

# Source function library.
. /etc/init.d/functions

<define any local shell functions used by the code that follows>

start() {
        echo -n "Starting <servicename>: "
        <start daemons, perhaps with the daemon function>
        touch /var/lock/subsys/<servicename>
        return <return code of starting daemon>
}

stop() {
        echo -n "Shutting down <servicename>: "

        <stop daemons, perhaps with the killproc function>
        rm -f /var/lock/subsys/<servicename>
        return <return code of stopping daemon>
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        <report the status of the daemons in free-form format,
        perhaps with the status function>
        ;;
    restart)
        stop
        start
        ;;
    reload)
        <cause the service configuration to be reread, either with
        kill -HUP or by restarting the daemons, in a manner similar
        to restart above>
        ;;
    condrestart)
        <restarts the servce if it is already running. For example:>
        [ -f /var/lock/subsys/<service> ] && restart || :
    probe)
        <optional .  If it exists, then it should determine whether
        or not the service needs to be restarted or reloaded (or
        whatever) in order to activate any changes in the configuration
        scripts.  It should print out a list of commands to give to
        $0; see the description under the probe tag below.>
        ;;
    *)
        echo "Usage: <servicename> {start|stop|status|reload|restart[|probe]"
        exit 1
        ;;
esac
exit $?

Ubuntuの複雑なテンプレートに比べるとシンプルで、これ位なら扱えそうな気がしてきますね。これを元に頑張ってuWSGIの起動スクリプト書いてみました。/etc/init.d/functionsにdaemonとかkillprocのような汎用ルーチンが用意されているので、実行ファイルのパスを渡すだけで軌道スクリプトが書けます。便利ですね。

#!/bin/bash
#
#       /etc/rc.d/init.d/uwsgi
#
#       start/stop/status uwsgi
#

. /etc/init.d/functions


UWSGI_DEFAULTS="/etc/default/uwsgi"
if [ -f "$UWSGI_DEFAULTS" ]; then
    . $UWSGI_DEFAULTS
fi

PROG=$UWSGI_BIN
PROGNAME=`basename $UWSGI_BIN`

[ -f $PROG ] || exit 0

start() {
        echo -n "Starting $PROGNAME: "
        daemon $PROG -s $UWSGI_ADDRESS --pp $UWSGI_APP_ROOT --module wsgi -d $UWSGI_LOG
        echo
}

stop() {
        echo -n "Shutting down $PROGNAME: "
        killproc $PROGNAME
        echo
}

show_status() {
        status $PROGNAME
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        show_status
        ;;
    *)
        echo "Usage: $PROGNAME {start|stop|status}"
        exit 1
        ;;
esac
exit $?

ここで/etc/default/uwsgiは以下のような内容になっています。

UWSGI_HOME="/path/to/project_root"
UWSGI_BIN="$UWSGI_HOME/bin/uwsgi"
UWSGI_APP_ROOT="$UWSGI_HOME/app_root"
UWSGI_LOG="$UWSGI_HOME/logs/uwsgi.log"
UWSGI_ADDRESS="127.0.0.1:4000"

/etc/init.d/functionsには他にもいろいろ処理が定義されているので、使いこなせばもっとかっこいいスクリプトがかける気がしますけど、とりあえずserviceコマンドでuwsgiが操作できるようになったので今日のところは満足です。

Leave a Reply

Your email address will not be published. Required fields are marked *