[File-rc-users] Bug#709481: file-rc: support for upstart in invoke-rc.d

Colin Watson cjwatson at ubuntu.com
Thu May 23 14:45:59 UTC 2013


Package: file-rc
Version: 0.8.15
Severity: wishlist
Tags: patch
User: ubuntu-devel at lists.ubuntu.com
Usertags: origin-ubuntu ubuntu-patch saucy

Hi,

In #671284, Steve patched sysv-rc's invoke-rc.d to add support for
handling Upstart jobs; and in #708720, he caused dh_installinit to add a
dependency on sysv-rc for packages shipping Upstart jobs in addition to
System V init scripts.  The combination of these means that, as Thorsten
Glaser pointed out to me this morning, forwarding Ubuntu's backlog of
Upstart jobs to Debian will cause a bunch of packages to be incompatible
with file-rc.  Now, I don't know how long file-rc is sticking around,
but it doesn't seem right for Upstart jobs to be the thing that force it
out, so I think we should fix this.

Fortunately, Steve's patch to sysv-rc's invoke-rc.d applies more or less
verbatim.  I've tested this successfully in an LXC container with one
Upstart job (ssh) and one System V init script (cron), with each of
sysvinit and upstart as the init daemon (in the latter case you have to
force it in despite dependencies, but it seems to work anyway).

diff -ru file-rc-0.8.15/debian/changelog file-rc-0.8.15+nmu1/debian/changelog
--- file-rc-0.8.15/debian/changelog	2013-03-26 07:01:37.000000000 +0000
+++ file-rc-0.8.15+nmu1/debian/changelog	2013-05-23 11:49:50.607314112 +0100
@@ -1,3 +1,12 @@
+file-rc (0.8.15+nmu1) UNRELEASED; urgency=low
+
+  * Non-maintainer upload.
+  * Add upstart support to invoke-rc.d, per the policy discussion in bug
+    #591791.  This is a straight port of Steve Langasek's implementation in
+    sysv-rc.
+
+ -- Colin Watson <cjwatson at debian.org>  Thu, 23 May 2013 11:48:40 +0100
+
 file-rc (0.8.15) unstable; urgency=low
 
   [ Michael Stapelberg ]
diff -ru file-rc-0.8.15/invoke-rc.d file-rc-0.8.15+nmu1/invoke-rc.d
--- file-rc-0.8.15/invoke-rc.d	2012-07-02 21:45:09.000000000 +0100
+++ file-rc-0.8.15+nmu1/invoke-rc.d	2013-05-23 15:28:37.954435538 +0100
@@ -33,6 +33,7 @@
 CFGFILE="/etc/runlevel.conf"
 BAKCFG="/etc/runlevel.fallback"
 LOCKFILE="/var/lock/runlevel.lock"
+UPSTARTDIR=/etc/init/
 # Should use filercconf if possible, and filercbak if filercconf is missing.
 
 valid_min_seq=0
@@ -48,6 +49,7 @@
 RETRY=
 RETURNFAILURE=
 RC=
+is_upstart=
 
 # Shell options
 set +e
@@ -275,9 +277,15 @@
 	;;
 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
@@ -447,7 +455,7 @@
 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 -a x${MODE} = xquery ; then
         RC=105
     fi
@@ -494,11 +502,25 @@
     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 -o ${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
@@ -507,7 +529,48 @@
 		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

Thanks,

-- 
Colin Watson                                       [cjwatson at ubuntu.com]



More information about the File-rc-users mailing list