Fix sys V init script so start/restart actions work properly 60/6760/4
authorAlexei Sheplyakov <asheplyakov@mirantis.com>
Sat, 16 May 2015 10:24:33 +0000 (13:24 +0300)
committerAlexei Sheplyakov <asheplyakov@mirantis.com>
Tue, 19 May 2015 19:06:53 +0000 (22:06 +0300)
The config file shipped with the package tells mcollectived to daemonize.
However the init script assumes mcollectived runs in the foreground
(start-stop-daemon -b) and tells start-stop-daemon put mcollective into
background and to manage the pid file. So start-stop-daemon forks, records
its pid, and starts mcollective which forks again. Therefore PID recorded
in the PID file is wrong. As a result the restart action spawns a new
instance of mcollective without stopping the old one, and start launches
a new mcollective even if it's already running.

Rewrite the init script, drop the trickery which start-stop-daemon does
on its own (provided that PID file is correct). While at it add dependency
on ruby-stomp (mcollectived won't even start without it).

Closes-Bug: #1454741
Change-Id: Iac4d3535c98881be7ccea256c50d58f337420205

debian/changelog
debian/control
debian/mcollective.default [new file with mode: 0644]
debian/mcollective.init
mcollective.init

index 8a98a5e9058de565fcfd7c0923a1bbb3a90c87d1..4edbe24efa494ec60bf8495b634d81efdd2bde21 100644 (file)
@@ -1,3 +1,10 @@
+mcollective (2.3.1-0u~u14.04+mos2) mos6.1; urgency=low
+
+  * Replace a broken sys V init script (LP #1454741)
+  * Add a missing dependency on ruby-stomp
+
+ -- Alexei Sheplyakov <asheplyakov@mirantis.com>  Sat, 16 May 2015 12:23:59 +0300
+
 mcollective (2.3.1-0~u14.04+mos1) mos6.1; urgency=medium
 
   * Minor packaging update; no actual code changes:
index f679770d1cb4eda48ab8f35516757e38495143fa..75238d1ee5fcbf756e17b98375b03f7409fed290 100644 (file)
@@ -25,7 +25,7 @@ Package: mcollective-common
 Replaces: mcollective (<< 2.0.0-1)
 Breaks: mcollective (<< 2.0.0-1), mcollective-client (<< 2.0.0-1)
 Architecture: all
-Depends: ruby (>= 1.8.1), rubygems | ruby (>= 1.9.1)
+Depends: ruby (>= 1.8.1), rubygems | ruby (>= 1.9.1), ruby-stomp
 Description: build server orchestration or parallel job execution systems
  The Marionette Collective aka. mcollective is a framework 
  to build server orchestration or parallel job execution systems.
diff --git a/debian/mcollective.default b/debian/mcollective.default
new file mode 100644 (file)
index 0000000..9ae29cf
--- /dev/null
@@ -0,0 +1,2 @@
+# Change to no, to disable Mcollective on boot
+RUN=yes
index ee8d68f757a37913cdf522cb36bb4d252b65041b..eaad7fb8b2ce91e456d8196e0b8f3ae950d336f7 100755 (executable)
-#!/bin/sh
-#
-# mcollective   Application Server for STOMP based agents
-#
-#
-# description:  mcollective lets you build powerful Stomp compatible middleware clients in ruby without having to worry too
-#               much about all the setup and management of a Stomp connection, it also provides stats, logging and so forth
-#               as a bonus.
-#
+#! /bin/sh
 ### BEGIN INIT INFO
 # Provides:          mcollective
-# Required-Start:    $remote_fs
-# Required-Stop:     $remote_fs
+# Required-Start:    $network $named $remote_fs $syslog
+# Required-Stop:     $network $named $remote_fs $syslog
 # Default-Start:     2 3 4 5
 # Default-Stop:      0 1 6
-# Short-Description: Start daemon at boot time
-# Description:       Enable service provided by mcollective.
+# Short-Description: MCollective daemon
+# Description:       Marionette Collective daemon - build server
+#                    orchestration or parallel job execution systems.
 ### END INIT INFO
 
-# check permissions
+# Author: Jonas Genannt <jonas.genannt@capi2name.de>
 
-uid=`id -u`
-[ $uid -gt 0 ] && { echo "You need to be root to run file" ; exit 4 ; }
+PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
+DESC="Marionette Collective daemon"
+NAME=mcollective
+DAEMON=/usr/sbin/mcollectived
+PIDFILE=/var/run/$NAME.pid
+DAEMON_ARGS="--config=/etc/mcollective/server.cfg --pid=$PIDFILE"
+SCRIPTNAME=/etc/init.d/$NAME
+RUN=yes
 
+# Exit if the package is not installed
+[ -x "$DAEMON" ] || exit 0
 
-# PID directory
-pidfile="/var/run/mcollective.pid"
+[ -r /etc/default/$NAME ] && . /etc/default/$NAME
 
-name="mcollective"
-mcollectived=/usr/sbin/mcollectived
-daemonopts="--config=/etc/mcollective/server.cfg"
+. /lib/init/vars.sh
 
-
-# Source function library.
 . /lib/lsb/init-functions
 
-# Check that binary exists
-if ! [ -f $mcollectived ]
-then
-    echo "mcollectived binary not found"
-    exit 5
-fi
+# XXX: cloud-init writes daemonize=0 into the server.conf
+# (https://github.com/stackforge/fuel-web/blob/master/fuel_agent/cloud-init-templates/cloud_config_ubuntu.jinja2#L50)
+# Undo that error here
+# FIXME: remove this hack after fixing the template
 
-# See how we were called.
-case "$1" in
-    start)
-        echo "Starting daemon: " $name
-        # start the program
-       if [ -f "$pidfile" ]; then
-               if [ -L "/proc/$(cat $pidfile)/exe" ] ; then
-                       echo MCollective appears to be running
-                       exit 1
-               else
-                       /sbin/start-stop-daemon --start -b --quiet --oknodo -m --pidfile $pidfile --exec $mcollectived -- $daemonopts
-               [ $? = 0 ] && { exit 0 ; } || { exit 1 ; }
-               fi
-       else
-               /sbin/start-stop-daemon --start -b --quiet --oknodo -m --pidfile $pidfile --exec $mcollectived -- $daemonopts
+conf_fixup()
+{
+       local conf=/etc/mcollective/server.cfg
+       if grep -q -e 'daemonize\s*=\s*0' $conf; then
+               sed -i $conf -re 's/^\s*daemonize\s*=\s*0\s*$/daemonize=1/'
        fi
-        log_success_msg "mcollective started"
-        ;;
-    stop)
-        echo "Stopping daemon: " $name
-        /sbin/start-stop-daemon --stop -q --pidfile $pidfile
-       if [ -f $pidfile ]; then
-               rm -f $pidfile
+}
+
+do_start()
+{
+       if [ "$RUN" != "yes" ] ; then
+               log_progress_msg "(disabled)"
+               log_end_msg 0
+
+               exit 0
        fi
-        [ $? = 0 ] && { exit 0 ; } || { exit 1 ; }
-        log_success_msg "mcollective stopped"
-        ;;
-    restart)
-        echo "Restarting daemon: " $name
-        $0 stop
-        sleep 2
-        $0 start
-        [ $? = 0 ] && { echo "mcollective restarted" ; exit 0 ; }
-        ;;
-    status)
-        status_of_proc -p ${pidfile} ${mcollectived} ${name} && exit 0 || exit $?
-        ;;
-    *)
-        echo "Usage: mcollectived {start|stop|restart|condrestart|status}"
-        exit 2
-        ;;
+       conf_fixup
+       start-stop-daemon --start --quiet --pidfile $PIDFILE \
+               --startas $DAEMON -- $DAEMON_ARGS \
+               || return 2
+}
+
+do_stop()
+{
+       if [ -s $PIDFILE ]; then
+               kill `cat ${PIDFILE}` >/dev/null 2>&1
+       fi
+       rm -f $PIDFILE
+       return "0"
+}
+
+case "$1" in
+  start)
+       [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
+       do_start
+       case "$?" in
+               0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+               2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
+       esac
+       ;;
+  stop)
+       [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
+       do_stop
+       case "$?" in
+               0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+               2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
+       esac
+       ;;
+  status)
+       status_of_proc -p "${PIDFILE}" "$DAEMON" "$NAME" && exit 0 || exit $?
+       ;;
+  restart|force-reload)
+       log_daemon_msg "Restarting $DESC" "$NAME"
+       do_stop
+       case "$?" in
+         0|1)
+               do_start
+               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
+       ;;
+  *)
+       echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
+       exit 3
+       ;;
 esac
+
+:
index ee8d68f757a37913cdf522cb36bb4d252b65041b..eaad7fb8b2ce91e456d8196e0b8f3ae950d336f7 100755 (executable)
-#!/bin/sh
-#
-# mcollective   Application Server for STOMP based agents
-#
-#
-# description:  mcollective lets you build powerful Stomp compatible middleware clients in ruby without having to worry too
-#               much about all the setup and management of a Stomp connection, it also provides stats, logging and so forth
-#               as a bonus.
-#
+#! /bin/sh
 ### BEGIN INIT INFO
 # Provides:          mcollective
-# Required-Start:    $remote_fs
-# Required-Stop:     $remote_fs
+# Required-Start:    $network $named $remote_fs $syslog
+# Required-Stop:     $network $named $remote_fs $syslog
 # Default-Start:     2 3 4 5
 # Default-Stop:      0 1 6
-# Short-Description: Start daemon at boot time
-# Description:       Enable service provided by mcollective.
+# Short-Description: MCollective daemon
+# Description:       Marionette Collective daemon - build server
+#                    orchestration or parallel job execution systems.
 ### END INIT INFO
 
-# check permissions
+# Author: Jonas Genannt <jonas.genannt@capi2name.de>
 
-uid=`id -u`
-[ $uid -gt 0 ] && { echo "You need to be root to run file" ; exit 4 ; }
+PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
+DESC="Marionette Collective daemon"
+NAME=mcollective
+DAEMON=/usr/sbin/mcollectived
+PIDFILE=/var/run/$NAME.pid
+DAEMON_ARGS="--config=/etc/mcollective/server.cfg --pid=$PIDFILE"
+SCRIPTNAME=/etc/init.d/$NAME
+RUN=yes
 
+# Exit if the package is not installed
+[ -x "$DAEMON" ] || exit 0
 
-# PID directory
-pidfile="/var/run/mcollective.pid"
+[ -r /etc/default/$NAME ] && . /etc/default/$NAME
 
-name="mcollective"
-mcollectived=/usr/sbin/mcollectived
-daemonopts="--config=/etc/mcollective/server.cfg"
+. /lib/init/vars.sh
 
-
-# Source function library.
 . /lib/lsb/init-functions
 
-# Check that binary exists
-if ! [ -f $mcollectived ]
-then
-    echo "mcollectived binary not found"
-    exit 5
-fi
+# XXX: cloud-init writes daemonize=0 into the server.conf
+# (https://github.com/stackforge/fuel-web/blob/master/fuel_agent/cloud-init-templates/cloud_config_ubuntu.jinja2#L50)
+# Undo that error here
+# FIXME: remove this hack after fixing the template
 
-# See how we were called.
-case "$1" in
-    start)
-        echo "Starting daemon: " $name
-        # start the program
-       if [ -f "$pidfile" ]; then
-               if [ -L "/proc/$(cat $pidfile)/exe" ] ; then
-                       echo MCollective appears to be running
-                       exit 1
-               else
-                       /sbin/start-stop-daemon --start -b --quiet --oknodo -m --pidfile $pidfile --exec $mcollectived -- $daemonopts
-               [ $? = 0 ] && { exit 0 ; } || { exit 1 ; }
-               fi
-       else
-               /sbin/start-stop-daemon --start -b --quiet --oknodo -m --pidfile $pidfile --exec $mcollectived -- $daemonopts
+conf_fixup()
+{
+       local conf=/etc/mcollective/server.cfg
+       if grep -q -e 'daemonize\s*=\s*0' $conf; then
+               sed -i $conf -re 's/^\s*daemonize\s*=\s*0\s*$/daemonize=1/'
        fi
-        log_success_msg "mcollective started"
-        ;;
-    stop)
-        echo "Stopping daemon: " $name
-        /sbin/start-stop-daemon --stop -q --pidfile $pidfile
-       if [ -f $pidfile ]; then
-               rm -f $pidfile
+}
+
+do_start()
+{
+       if [ "$RUN" != "yes" ] ; then
+               log_progress_msg "(disabled)"
+               log_end_msg 0
+
+               exit 0
        fi
-        [ $? = 0 ] && { exit 0 ; } || { exit 1 ; }
-        log_success_msg "mcollective stopped"
-        ;;
-    restart)
-        echo "Restarting daemon: " $name
-        $0 stop
-        sleep 2
-        $0 start
-        [ $? = 0 ] && { echo "mcollective restarted" ; exit 0 ; }
-        ;;
-    status)
-        status_of_proc -p ${pidfile} ${mcollectived} ${name} && exit 0 || exit $?
-        ;;
-    *)
-        echo "Usage: mcollectived {start|stop|restart|condrestart|status}"
-        exit 2
-        ;;
+       conf_fixup
+       start-stop-daemon --start --quiet --pidfile $PIDFILE \
+               --startas $DAEMON -- $DAEMON_ARGS \
+               || return 2
+}
+
+do_stop()
+{
+       if [ -s $PIDFILE ]; then
+               kill `cat ${PIDFILE}` >/dev/null 2>&1
+       fi
+       rm -f $PIDFILE
+       return "0"
+}
+
+case "$1" in
+  start)
+       [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
+       do_start
+       case "$?" in
+               0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+               2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
+       esac
+       ;;
+  stop)
+       [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
+       do_stop
+       case "$?" in
+               0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+               2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
+       esac
+       ;;
+  status)
+       status_of_proc -p "${PIDFILE}" "$DAEMON" "$NAME" && exit 0 || exit $?
+       ;;
+  restart|force-reload)
+       log_daemon_msg "Restarting $DESC" "$NAME"
+       do_stop
+       case "$?" in
+         0|1)
+               do_start
+               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
+       ;;
+  *)
+       echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
+       exit 3
+       ;;
 esac
+
+: