Package: sysv-rc
Version: 2.88dsf-23
Severity: wishlist
Tags: patch

Hi again,

The policy proposal currently on the table for integration of alternate init
systems also requires invoke-rc.d implementations to correctly handle native
jobs in preference over sysvinit scripts.  I'm attaching an implementation
herewith.

This is a more or less direct port to invoke-rc.d of the
/lib/init/upstart-job script that's been in use in Ubuntu for a couple of
years, providing LSB initscript-like semantics on top of the upstart
control interface.  I have also thoroughly tested this with an
upstart-enabled service and a non-upstart-enabled service, confirming that
invoke-rc.d still works with this change applied.

I'd be grateful to have this included in the 2.88dsf-24 upload.

Thanks,
-- 
Steve Langasek                   Give me a lever long enough and a Free OS
Debian Developer                   to set it on, and I can move the world.
Ubuntu Developer                                    http://www.debian.org/
slanga...@ubuntu.com                                     vor...@debian.org
From bd18a1da90184eb0f30222d9708a7b86aa358b64 Mon Sep 17 00:00:00 2001
From: Steve Langasek <steve.langa...@canonical.com>
Date: Wed, 2 May 2012 16:43:14 -0700
Subject: [PATCH] Add upstart support to invoke-rc.d, per the policy
 discussion in bug #591791.

---
 debian/changelog                    |    2 +
 debian/src/sysv-rc/sbin/invoke-rc.d |   75 ++++++++++++++++++++++++++++++++---
 2 files changed, 71 insertions(+), 6 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index ce63f74..d7d4f6f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -28,6 +28,8 @@ sysvinit (2.88dsf-24) experimental; urgency=low
   [ Steve Langasek ]
   * Install the startpar bridge now that dh_installinit in Debian handles
     this.  Closes: #660824.
+  * Add upstart support to invoke-rc.d, per the policy discussion in bug
+    #591791.
 
  -- Roger Leigh <rle...@debian.org>  Sun, 29 Apr 2012 23:52:14 +0100
 
diff --git a/debian/src/sysv-rc/sbin/invoke-rc.d b/debian/src/sysv-rc/sbin/invoke-rc.d
index e5887ee..7712098 100644
--- a/debian/src/sysv-rc/sbin/invoke-rc.d
+++ b/debian/src/sysv-rc/sbin/invoke-rc.d
@@ -24,6 +24,7 @@
 RUNLEVEL=/sbin/runlevel
 POLICYHELPER=/usr/sbin/policy-rc.d
 INITDPREFIX=/etc/init.d/
+UPSTARTDIR=/etc/init/
 RCDPREFIX=/etc/rc
 
 # Options
@@ -36,6 +37,7 @@ FORCE=
 RETRY=
 RETURNFAILURE=
 RC=
+is_upstart=
 
 # Shell options
 set +e
@@ -265,9 +267,15 @@ case ${ACTION} in
 	;;
 esac
 
-## Verifies if the given initscript ID is known
-## For sysvinit, this error is critical
-if test ! -f "${INITDPREFIX}${INITSCRIPTID}" ; then
+# If we're running on upstart and there's an upstart job of this name, do
+# the rest with upstart instead of calling the init script.
+if which initctl >/dev/null && initctl version | grep -q upstart \
+   && [ -e "$UPSTARTDIR/${INITSCRIPTID}.conf" ]
+then
+    is_upstart=1
+elif test ! -f "${INITDPREFIX}${INITSCRIPTID}" ; then
+    ## Verifies if the given initscript ID is known
+    ## For sysvinit, this error is critical
     printerror unknown initscript, ${INITDPREFIX}${INITSCRIPTID} not found.
     exit 100
 fi
@@ -375,7 +383,7 @@ case ${ACTION} in
 esac
 
 # test if /etc/init.d/initscript is actually executable
-if testexec "${INITDPREFIX}${INITSCRIPTID}" ; then
+if [ -n "$is_upstart" ] || testexec "${INITDPREFIX}${INITSCRIPTID}" ; then
     if test x${RC} = x && test x${MODE} = xquery ; then
         RC=105
     fi
@@ -422,11 +430,25 @@ getnextaction () {
     ACTION="$@"
 }
 
+if [ -n "$is_upstart" ]; then
+    RUNNING=
+    DISABLED=
+    if status "$INITSCRIPTID" 2>/dev/null | grep -q ' start/'; then
+	RUNNING=1
+    fi
+    UPSTART_VERSION_RUNNING=$(initctl version|awk '{print $3}'|tr -d ')')
+
+    if dpkg --compare-versions "$UPSTART_VERSION_RUNNING" ge 0.9.7
+    then
+	initctl show-config -e "$INITSCRIPTID"|grep -q '^  start on' || DISABLED=1
+    fi
+fi
+
 ## Executes initscript
 ## note that $ACTION is a space-separated list of actions
 ## to be attempted in order until one suceeds.
 if test x${FORCE} != x || test ${RC} -eq 104 ; then
-    if testexec "${INITDPREFIX}${INITSCRIPTID}" ; then
+    if [ -n "$is_upstart" ] || testexec "${INITDPREFIX}${INITSCRIPTID}" ; then
 	RC=102
 	setechoactions ${ACTION}
 	while test ! -z "${ACTION}" ; do
@@ -435,7 +457,48 @@ if test x${FORCE} != x || test ${RC} -eq 104 ; then
 		printerror executing initscript action \"${saction}\"...
 	    fi
 
-	    "${INITDPREFIX}${INITSCRIPTID}" "${saction}" "$@" && exit 0
+	    if [ -n "$is_upstart" ]; then
+		case $saction in
+		    status)
+			"$saction" "$INITSCRIPTID" && exit 0
+			;;
+		    start|stop)
+			if [ -z "$RUNNING" ] && [ "$saction" = "stop" ]; then
+			    exit 0
+			elif [ -n "$RUNNING" ] && [ "$saction" = "start" ]; then
+			    exit 0
+			elif [ -n "$DISABLED" ] && [ "$saction" = "start" ]; then
+			    exit 0
+			fi
+			$saction "$INITSCRIPTID" && exit 0
+			;;
+		    restart)
+			if [ -n "$RUNNING" ] ; then
+			    stop "$INITSCRIPTID"
+			fi
+
+			# If the job is disabled and is not currently
+			# running, the job is not restarted. However, if
+			# the job is disabled but has been forced into
+			# the running state, we *do* stop and restart it
+			# since this is expected behaviour
+			# for the admin who forced the start.
+			if [ -n "$DISABLED" ] && [ -z "$RUNNING" ]; then
+			    exit 0
+			fi
+			start "$INITSCRIPTID" && exit 0
+			;;
+		    reload|force-reload)
+			reload "$INITSCRIPTID" && exit 0
+			;;
+		    *)
+			# This will almost certainly fail, but give it a try
+			initctl "$saction" "$INITSCRIPTID" && exit 0
+			;;
+		esac
+	    else
+		"${INITDPREFIX}${INITSCRIPTID}" "${saction}" "$@" && exit 0
+	    fi
 	    RC=$?
 
 	    if test ! -z "${ACTION}" ; then
-- 
1.7.9.5

Attachment: signature.asc
Description: Digital signature

Reply via email to