systemd: Always create the systemd unit files

Commit 5edae54 introduced the usage of systemd in Devstack. This allowed
the transition away from 'screen'. Systemd needs "user unit files" to
describe the services. Currently, those unit files get only created when
an openstack service (n-cpu, c-sch, g-api, ...) is in the list of enabled
services (`ENABLED_SERVICES`). This means, when Devstack is fully stacked,
there is no way to start the systemd unit of an openstack service which
is *not* in that list.

This commit changes that behavior, and creates the systemd unit files
independently of the list ENABLED_SERVICES. This means, when Devstack
is fully stacked, I can start a systemd unit of an openstack service which
wasn't in the ENABLED_SERVICES list. This allows more flexible lifecycle
management of openstack services in the gate, which is useful for tests
which test components which are not in the "default configuration" (e.g.
the "nova-serialproxy" service).

The `clean.sh` script purges all traces of systemd user unit files created
by devstack.

Change-Id: I0f7e1ee8723f4de47cbc56b727182f90a2b32bfb
diff --git a/clean.sh b/clean.sh
index ef38fbf..9ffe3be 100755
--- a/clean.sh
+++ b/clean.sh
@@ -125,6 +125,13 @@
     sudo rm -rf $SCREEN_LOGDIR
 fi
 
+# Clean out the sytemd user unit files if systemd was used.
+if [[ "$USE_SYSTEMD" = "True" ]]; then
+    sudo find $SYSTEMD_DIR -type f -name '*devstack@*service' -delete
+    # Make systemd aware of the deletion.
+    $SYSTEMCTL daemon-reload
+fi
+
 # Clean up venvs
 DIRS_TO_CLEAN="$WHEELHOUSE ${PROJECT_VENV[@]} .config/openstack"
 rm -rf $DIRS_TO_CLEAN
diff --git a/functions-common b/functions-common
index 30933ea..48ce725 100644
--- a/functions-common
+++ b/functions-common
@@ -1508,8 +1508,13 @@
 
 }
 
-# Helper function to build a basic unit file and run it under systemd.
-function _run_under_systemd {
+# Defines a systemd service which can be enabled and started later on.
+# arg1: The openstack service name ('n-cpu', 'c-sch', ...).
+# arg2: The command to start (e.g. path to service binary + config files).
+# arg3: The group which owns the process.
+# arg4: The user which owns the process.
+# Returns: The systemd service name which got defined.
+function _define_systemd_service {
     local service=$1
     local command="$2"
     local cmd=$command
@@ -1524,9 +1529,7 @@
     else
         write_user_unit_file $systemd_service "$cmd" "$group" "$user"
     fi
-
-    $SYSTEMCTL enable $systemd_service
-    $SYSTEMCTL start $systemd_service
+    echo $systemd_service
 }
 
 # Helper to remove the ``*.failure`` files under ``$SERVICE_DIR/$SCREEN_NAME``.
@@ -1567,11 +1570,19 @@
     local user=$4
 
     local name=$service
+    local systemd_service
 
     time_start "run_process"
+    # Note we deliberately make all service files, even if the service
+    # isn't enabled, so it can be enabled by a dev manually on command
+    # line.
+    if [[ "$USE_SYSTEMD" = "True" ]]; then
+        systemd_service=$(_define_systemd_service "$name" "$command" "$group" "$user")
+    fi
     if is_service_enabled $service; then
         if [[ "$USE_SYSTEMD" = "True" ]]; then
-            _run_under_systemd "$name" "$command" "$group" "$user"
+            $SYSTEMCTL enable $systemd_service
+            $SYSTEMCTL start $systemd_service
         elif [[ "$USE_SCREEN" = "True" ]]; then
             if [[ "$user" == "root" ]]; then
                 command="sudo $command"