← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad-buildd:systemd-service into launchpad-buildd:master

 

Colin Watson has proposed merging ~cjwatson/launchpad-buildd:systemd-service into launchpad-buildd:master.

Commit message:
Convert daemon startup to systemd

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  Bug #1964615 in launchpad-buildd: "XDG_RUNTIME_DIR set to a non-existing directory in sbuild"
  https://bugs.launchpad.net/launchpad-buildd/+bug/1964615

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad-buildd/+git/launchpad-buildd/+merge/416757

As well as simplifying away 150 lines of shell script, this avoids relying on su(1) to run the daemon as the `buildd` user, which in turn avoids accidental pollution of the daemon's environment by whatever su(1) thinks is appropriate in interactive environments.

There's a bit of extra complexity due to supporting multiple daemon instances, which is mostly historical at this point, but it was easy enough to handle using a template unit and a generator.

I dropped the explicit hostname condition, since all our builders already have `RUN_NETWORK_REQUESTS_AS_ROOT=yes` set in `/etc/default/launchpad-buildd`.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad-buildd:systemd-service into launchpad-buildd:master.
diff --git a/debian/changelog b/debian/changelog
index 2dc69b1..6d5ce62 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -4,6 +4,7 @@ launchpad-buildd (210) UNRELEASED; urgency=medium
     lucid.
   * Make more loop device nodes available in LXD containers (LP: #1963706).
   * Drop pre-Python-3.6 code using pyupgrade.
+  * Convert daemon startup to systemd (LP: #1964615).
 
  -- Colin Watson <cjwatson@xxxxxxxxxx>  Mon, 28 Feb 2022 11:27:20 +0000
 
diff --git a/debian/control b/debian/control
index 6bbe218..5938781 100644
--- a/debian/control
+++ b/debian/control
@@ -8,7 +8,7 @@ Standards-Version: 3.9.5
 Build-Depends: apt-utils,
                bzr,
                curl,
-               debhelper (>= 9~),
+               debhelper (>= 9.20160709~),
                dh-exec,
                dh-python,
                git,
diff --git a/debian/launchpad-buildd-generator b/debian/launchpad-buildd-generator
new file mode 100755
index 0000000..797f453
--- /dev/null
+++ b/debian/launchpad-buildd-generator
@@ -0,0 +1,19 @@
+#! /bin/sh
+set -e
+
+# Generate systemd unit dependency symlinks for all configured
+# launchpad-buildd instances.
+
+wantdir="$1/launchpad-buildd.service.wants"
+template=/lib/systemd/system/launchpad-buildd@.service
+
+mkdir -p "$wantdir"
+
+for conf in /etc/launchpad-buildd/*; do
+    # Skip nonexistent files (perhaps due to the glob matching no files).
+    [ -e "$conf" ] || continue
+    # Skip backup files.
+    case $conf in -*|*~) continue ;; esac
+
+    ln -s "$template" "$wantdir/launchpad-buildd@${conf##*/}.service"
+done
diff --git a/debian/launchpad-buildd.init b/debian/launchpad-buildd.init
deleted file mode 100755
index b92d911..0000000
--- a/debian/launchpad-buildd.init
+++ /dev/null
@@ -1,150 +0,0 @@
-#!/bin/sh
-#
-# Copyright 2009,2011 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-#
-# launchpad-buildd
-#               This file is used to start and stop launchpad buildds
-
-### BEGIN INIT INFO
-# Provides:          launchpad_buildd
-# Required-Start:    $local_fs $network $syslog $time $remote_fs
-# Required-Stop:     $local_fs $network $syslog $time $remote_fs
-# Should-Start:      cloud-init
-# Default-Start:     2 3 4 5
-# Default-Stop:      0 1 6
-# X-Interactive:     false
-# Short-Description: Start/stop launchpad buildds
-### END INIT INFO
-
-set -e
-
-PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
-DESC="launchpad build slaves"
-
-TACFILE="/usr/lib/launchpad-buildd/buildd-slave.tac"
-
-PIDROOT="/var/run/launchpad-buildd"
-LOGROOT="/var/log/launchpad-buildd"
-CONFROOT="/etc/launchpad-buildd"
-
-# Gracefully exit if the package has been removed.
-test -e $TACFILE || exit 0
-
-
-d_check_enabled() {
-RUN_NETWORK_REQUESTS_AS_ROOT=no   # Good idea generally
-
-[ -f /etc/default/launchpad-buildd ] && . /etc/default/launchpad-buildd
-
-hostname="`hostname -f`"
-case "$hostname" in
-*.ppa|*.buildd)
-	cat <<END
-
-launchpad-buildd: starting automatically because $hostname seems to be a buildd machine.
-
-CAUTION: this service accepts network commands and runs them as root.
-END
-	return
-	;;
-*)
-	echo "launchpad-buildd: not starting automatically on $hostname"
-	;;
-esac
-
-if [ "$RUN_NETWORK_REQUESTS_AS_ROOT" != yes ]
-then
-	cat <<END
-
-launchpad-buildd is disabled.
-When enabled, launchpad-buildd accepts network commands and runs them as root.
-If you are sure this server will only be reachable by trusted machines, edit
-/etc/default/launchpad-buildd.
-
-END
-	exit 0
-fi
-}
-
-
-#
-#       Function that starts a buildd slave
-#
-d_start() {
-    CONF=$1
-    PIDFILE="$PIDROOT"/"$CONF".pid
-    LOGFILE="$LOGROOT"/"$CONF".log
-
-    # Useful for certain kinds of image builds.
-    modprobe nbd || true
-
-    su - buildd -c "BUILDD_CONFIG=$CONFROOT/$CONF twistd3 --no_save --pidfile $PIDFILE --python $TACFILE --logfile $LOGFILE --umask 022"
-}
-
-#
-#       Function that stops a buildd slave
-#
-d_stop() {
-    CONF=$1
-    PIDFILE="$PIDROOT"/"$CONF".pid
-    test -r $PIDFILE && kill -TERM $(cat $PIDFILE) || true
-}
-
-#
-#       Function that reloads a buildd slave
-#
-d_reload() {
-    CONF=$1
-    PIDFILE="$PIDROOT"/"$CONF".pid
-    test -r $PIDFILE && kill -HUP $(cat $PIDFILE) || true
-}
-
-CONFS=$(cd $CONFROOT; ls|grep -v "^-"|grep -v "~$")
-
-case "$1" in
-  start)
-	d_check_enabled
-
-        echo -n "Starting $DESC:"
-        install -m 755 -o buildd -g buildd -d $PIDROOT
-
-	# Create any missing directories and chown them appropriately
-	install -d -o buildd -g buildd /home/buildd/filecache-default
-
-	for conf in $CONFS; do
-	    echo -n " $conf"
-	    d_start $conf
-	done
-        echo "."
-        ;;
-  stop)
-        echo -n "Stopping $DESC:"
-	for conf in $CONFS; do
-	    echo -n " $conf"
-	    d_stop $conf
-	done
-        echo "."
-        ;;
-  restart|force-reload)
-        #
-        #       If the "reload" option is implemented, move the "force-reload"
-        #       option to the "reload" entry above. If not, "force-reload" is
-        #       just the same as "restart".
-        #
-	$0 stop
-	sleep 1
-	$0 start
-        ;;
-  reload)
-        for conf in $CONFS; do
-            d_reload $conf
-        done
-        ;;
-  *)
-        echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload|reload}" >&2
-        exit 1
-        ;;
-esac
-
-exit 0
diff --git a/debian/launchpad-buildd.install b/debian/launchpad-buildd.install
index 95db295..208bfde 100644
--- a/debian/launchpad-buildd.install
+++ b/debian/launchpad-buildd.install
@@ -5,6 +5,7 @@ bin/in-target				usr/share/launchpad-buildd/bin
 bin/lpbuildd-git-proxy			usr/share/launchpad-buildd/bin
 bin/sbuild-package			usr/share/launchpad-buildd/bin
 buildd-genconfig			usr/share/launchpad-buildd
+debian/launchpad-buildd-generator	lib/systemd/system-generators
 debian/upgrade-config			usr/share/launchpad-buildd
 default/launchpad-buildd 		etc/default
 sbuildrc				usr/share/launchpad-buildd
diff --git a/debian/launchpad-buildd.maintscript b/debian/launchpad-buildd.maintscript
new file mode 100644
index 0000000..cfeedce
--- /dev/null
+++ b/debian/launchpad-buildd.maintscript
@@ -0,0 +1 @@
+rm_conffile /etc/init.d/launchpad-buildd 210~
diff --git a/debian/launchpad-buildd.service b/debian/launchpad-buildd.service
new file mode 100644
index 0000000..ca425b3
--- /dev/null
+++ b/debian/launchpad-buildd.service
@@ -0,0 +1,15 @@
+# This service is really a systemd target, but we use a service since
+# targets cannot be reloaded.  See launchpad-buildd@.service for instance
+# configuration.
+
+[Unit]
+Description=Launchpad build daemon
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/bin/true
+ExecReload=/bin/true
+
+[Install]
+WantedBy=multi-user.target
diff --git a/debian/launchpad-buildd@.service b/debian/launchpad-buildd@.service
new file mode 100644
index 0000000..690e0fd
--- /dev/null
+++ b/debian/launchpad-buildd@.service
@@ -0,0 +1,26 @@
+[Unit]
+Description=Launchpad build daemon (%i)
+PartOf=launchpad-buildd.service
+Before=launchpad-buildd.service
+ReloadPropagatedFrom=launchpad-buildd.service
+After=network.target time-sync.target cloud-init.service
+# Useful for certain kinds of image builds.
+After=modprobe@nbd.service
+Requires=modprobe@nbd.service
+
+[Service]
+Type=simple
+RuntimeDirectory=launchpad-buildd
+LogsDirectory=launchpad-buildd
+User=buildd
+EnvironmentFile=-/etc/default/launchpad-buildd
+Environment=BUILDD_CONFIG=/etc/launchpad-buildd/%i
+# When enabled, launchpad-buildd accepts network commands and runs them as
+# root.  If you are sure this server will only be reachable by trusted
+# machines, edit /etc/default/launchpad-buildd.
+ExecStartPre=/usr/bin/test ${RUN_NETWORK_REQUESTS_AS_ROOT} = yes
+ExecStartPre=/usr/bin/install -d /home/buildd/filecache-default
+ExecStart=/usr/bin/twistd3 --no_save --pidfile /run/launchpad-buildd/%i.pid --python /usr/lib/launchpad-buildd/buildd-slave.tac --logfile /var/log/launchpad-buildd/%i.log --umask 022 --nodaemon
+
+[Install]
+WantedBy=multi-user.target
diff --git a/debian/postrm b/debian/postrm
index 7d847de..a331fa2 100644
--- a/debian/postrm
+++ b/debian/postrm
@@ -9,3 +9,7 @@ if [ "$1" = purge ]; then
 		rmdir -p --ignore-fail-on-non-empty /etc/systemd/timesyncd.conf.d
 	fi
 fi
+
+#DEBHELPER#
+
+exit 0
diff --git a/debian/rules b/debian/rules
index ebf0618..be006d8 100755
--- a/debian/rules
+++ b/debian/rules
@@ -9,10 +9,15 @@ export PYBUILD_NAME := lpbuildd
 export LIBDIR := $(shell python3 -c 'import distutils.sysconfig; print(distutils.sysconfig.get_python_lib())')
 
 %:
-	dh $@ --with=python3 --buildsystem=pybuild
+	dh $@ --with=python3,systemd --buildsystem=pybuild
 
 override_dh_auto_build:
 	dh_auto_build
 	python3 buildd-genconfig --template=template-buildd-slave.conf \
 	--arch=i386 --port=8221 --name=default --host=buildd.buildd \
 		> buildd-slave-example.conf
+
+# Required in debhelper compatibility level <=10 to avoid generating
+# postinst fragments to register a nonexistent init.d script.
+override_dh_installinit:
+	dh_installinit -n