#! /bin/sh # Copyright 2016 Matthew Wall, all rights reserved # init script to run multiple instances of weewx # # each weewx instance is identified by name. that name is used to identify the # configuration and pid files. # # this init script expects the following configuration: # /etc/weewx/a.conf # /etc/weewx/b.conf # /var/run/weewx-a.pid # /var/run/weewx-b.pid # # with the appropriate rsyslog and logrotate configurations: # /var/log/weewx/a.log # /var/log/weewx/b.log # # to configure the script, override variables in /etc/default/weewx-multi # for example: # # WEEWX_INSTANCES="vantage acurite" # WEEWX_BINDIR=/opt/weewx/bin # WEEWX_CFGDIR=/etc/weewx ### BEGIN INIT INFO # Provides: weewx-multi # Required-Start: $local_fs $remote_fs $syslog $time # Required-Stop: $local_fs $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: weewx-multi # Description: Manages multiple instances of weewx ### END INIT INFO PATH=/sbin:/usr/sbin:/bin:/usr/bin WEEWX_INSTANCES="no_instances_specified" WEEWX_USER=root:root WEEWX_BINDIR=/home/weewx/bin WEEWX_CFGDIR=/home/weewx # Try to keep systemd from screwing everything up export SYSTEMCTL_SKIP_REDIRECT=1 # Read configuration variable file if it is present [ -r /etc/default/weewx-multi ] && . /etc/default/weewx-multi DESC=weewx DAEMON=$WEEWX_BINDIR/weewxd # Exit if the package is not installed if [ ! -x "$DAEMON" ]; then echo "The $DESC daemon is not installed at $DAEMON" exit 0 fi # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh # Define LSB log_* functions. # Depend on lsb-base (>= 3.0-6) to ensure that this file is present. . /lib/lsb/init-functions # start the daemon # 0 if daemon has been started # 1 if daemon was already running # 2 if daemon could not be started do_start() { INSTANCE=$1 NAME=weewx-$INSTANCE PIDFILE=/var/run/$NAME.pid CFGFILE=$WEEWX_CFGDIR/$INSTANCE.conf DAEMON_ARGS="--daemon --log-label $NAME --pidfile=$PIDFILE $CFGFILE" if [ ! -f "$CFGFILE" ]; then echo "The instance $INSTANCE does not have a config at $CFGFILE" return 2 fi NPROC=$(count_procs $INSTANCE) if [ $NPROC != 0 ]; then return 1 fi start-stop-daemon --start --chuid $WEEWX_USER --pidfile $PIDFILE --exec $DAEMON -- $DAEMON_ARGS || return 2 return 0 } # stop the daemon # 0 if daemon has been stopped # 1 if daemon was already stopped # 2 if daemon could not be stopped # other if a failure occurred do_stop() { INSTANCE=$1 NAME=weewx-$INSTANCE PIDFILE=/var/run/$NAME.pid # bail out if the app is not running NPROC=$(count_procs $INSTANCE) if [ $NPROC = 0 ]; then return 1 fi # bail out if there is no pid file if [ ! -f $PIDFILE ]; then return 1 fi start-stop-daemon --stop --pidfile $PIDFILE # we cannot trust the return value from start-stop-daemon RETVAL=2 c=0 while [ $c -lt 24 -a "$RETVAL" = "2" ]; do c=`expr $c + 1` # process may not really have completed, so check it NPROC=$(count_procs $INSTANCE) if [ $NPROC = 0 ]; then RETVAL=0 else echo -n "." sleep 5 fi done if [ "$RETVAL" = "0" -o "$RETVAL" = "1" ]; then # delete the pid file just in case rm -f $PIDFILE fi return "$RETVAL" } # send a SIGHUP to the daemon do_reload() { INSTANCE=$1 NAME=weewx-$INSTANCE PIDFILE=/var/run/$NAME.pid start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE return 0 } do_status() { INSTANCE=$1 NAME=weewx-$INSTANCE NPROC=$(count_procs $INSTANCE) echo -n "$INSTANCE is " if [ $NPROC = 0 ]; then echo -n "not " fi echo "running." } count_procs() { INSTANCE=$1 NAME=weewx-$INSTANCE NPROC=`ps ax | grep $DAEMON | grep $NAME.pid | wc -l` echo $NPROC } CMD=$1 if [ "$1" != "" ]; then shift fi INSTANCES="$@" if [ "$INSTANCES" = "" ]; then INSTANCES=$WEEWX_INSTANCES fi case "$CMD" in start) for i in $INSTANCES; do [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$i" do_start $i case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac done ;; stop) for i in $INSTANCES; do [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$i" do_stop $i case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac done ;; status) for i in $INSTANCES; do do_status "$i" done ;; reload|force-reload) for i in $INSTANCES; do log_daemon_msg "Reloading $DESC" "$i" do_reload $i log_end_msg $? done ;; restart) for i in $INSTANCES; do log_daemon_msg "Restarting $DESC" "$i" do_stop $i case "$?" in 0|1) do_start $i case "$?" in 0) log_end_msg 0 ;; 1) log_end_msg 1 ;; # Old process is still running *) log_end_msg 1 ;; # Failed to start esac ;; *) # Failed to stop log_end_msg 1 ;; esac done ;; *) echo "Usage: $0 {start|stop|restart|reload} [instance]" >&2 exit 3 ;; esac