3e5297
From 09e8c6aa71ee4b5ff3ee85fc4855e2c1a246a079 Mon Sep 17 00:00:00 2001
3e5297
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
3e5297
Date: Thu, 22 Jul 2021 11:22:33 +0200
3e5297
Subject: [PATCH 2/5] rpm: use a helper script to actually invoke systemctl
3e5297
 commands
3e5297
MIME-Version: 1.0
3e5297
Content-Type: text/plain; charset=UTF-8
3e5297
Content-Transfer-Encoding: 8bit
3e5297
3e5297
Instead of embedding the commands to invoke directly in the macros,
3e5297
let's use a helper script as indirection. This has a couple of advantages:
3e5297
3e5297
- the macro language is awkward, we need to suffix most commands by "|| :"
3e5297
  and "\", which is easy to get wrong. In the new scheme, the macro becomes
3e5297
  a single simple command.
3e5297
- in the script we can use normal syntax highlighting, shellcheck, etc.
3e5297
- it's also easier to test the invoked commands by invoking the helper
3e5297
  manually.
3e5297
- most importantly, the logic is contained in the helper, i.e. we can
3e5297
  update systemd rpm and everything uses the new helper. Before, we would
3e5297
  have to rebuild all packages to update the macro definition.
3e5297
3e5297
This raises the question whether it makes sense to use the lua scriptlets when
3e5297
the real work is done in a bash script. I think it's OK: we still have the
3e5297
efficient lua scripts that do the short scripts, and we use a single shared
3e5297
implementation in bash to do the more complex stuff.
3e5297
3e5297
The meson version is raised to 0.47 because that's needed for install_mode.
3e5297
We were planning to raise the required version anyway…
3e5297
3e5297
(cherry picked from commit 6d825ab2d42d3219e49a192bf99f9c09134a0df4)
3e5297
---
3e5297
 README                           |  2 +-
3e5297
 meson.build                      |  3 +-
3e5297
 src/rpm/macros.systemd.in        | 30 ++++++++--------
3e5297
 src/rpm/meson.build              | 13 ++++---
3e5297
 src/rpm/systemd-update-helper.in | 60 ++++++++++++++++++++++++++++++++
3e5297
 src/rpm/triggers.systemd.in      | 43 ++++++++---------------
3e5297
 src/rpm/triggers.systemd.sh.in   | 13 ++-----
3e5297
 7 files changed, 105 insertions(+), 59 deletions(-)
3e5297
 create mode 100755 src/rpm/systemd-update-helper.in
3e5297
3e5297
diff --git a/README b/README
3e5297
index 0e5c326deb..a8f23a0d5b 100644
3e5297
--- a/README
3e5297
+++ b/README
3e5297
@@ -193,7 +193,7 @@ REQUIREMENTS:
3e5297
         python-jinja2
3e5297
         python-lxml (optional, required to build the indices)
3e5297
         python >= 3.5
3e5297
-        meson >= 0.46 (>= 0.49 is required to build position-independent executables)
3e5297
+        meson >= 0.47 (>= 0.49 is required to build position-independent executables)
3e5297
         ninja
3e5297
         gcc, awk, sed, grep, and similar tools
3e5297
         clang >= 10.0, llvm >= 10.0 (optional, required to build BPF programs
3e5297
diff --git a/meson.build b/meson.build
3e5297
index 738879eb21..fb986e84f7 100644
3e5297
--- a/meson.build
3e5297
+++ b/meson.build
3e5297
@@ -10,7 +10,7 @@ project('systemd', 'c',
3e5297
                 'localstatedir=/var',
3e5297
                 'warning_level=2',
3e5297
         ],
3e5297
-        meson_version : '>= 0.46',
3e5297
+        meson_version : '>= 0.47',
3e5297
        )
3e5297
 
3e5297
 libsystemd_version = '0.32.0'
3e5297
@@ -253,6 +253,7 @@ conf.set_quoted('SYSTEMD_SHUTDOWN_BINARY_PATH',               join_paths(rootlib
3e5297
 conf.set_quoted('SYSTEMD_STDIO_BRIDGE_BINARY_PATH',           join_paths(bindir, 'systemd-stdio-bridge'))
3e5297
 conf.set_quoted('SYSTEMD_TEST_DATA',                          join_paths(testsdir, 'testdata'))
3e5297
 conf.set_quoted('SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH', join_paths(rootbindir, 'systemd-tty-ask-password-agent'))
3e5297
+conf.set_quoted('SYSTEMD_UPDATE_HELPER_PATH',                 join_paths(rootlibexecdir, 'systemd-update-helper'))
3e5297
 conf.set_quoted('SYSTEMD_USERWORK_PATH',                      join_paths(rootlibexecdir, 'systemd-userwork'))
3e5297
 conf.set_quoted('SYSTEMD_VERITYSETUP_PATH',                   join_paths(rootlibexecdir, 'systemd-veritysetup'))
3e5297
 conf.set_quoted('SYSTEM_CONFIG_UNIT_DIR',                     join_paths(pkgsysconfdir, 'system'))
3e5297
diff --git a/src/rpm/macros.systemd.in b/src/rpm/macros.systemd.in
3e5297
index 3129ab2d61..bbdf036da7 100644
3e5297
--- a/src/rpm/macros.systemd.in
3e5297
+++ b/src/rpm/macros.systemd.in
3e5297
@@ -46,31 +46,33 @@ OrderWithRequires(postun): systemd \
3e5297
 
3e5297
 %systemd_post() \
3e5297
 %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_post}} \
3e5297
-if [ $1 -eq 1 ] && command -v systemctl >/dev/null; then \
3e5297
+if [ $1 -eq 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
3e5297
     # Initial installation \
3e5297
-    systemctl --no-reload preset %{?*} || : \
3e5297
+    {{SYSTEMD_UPDATE_HELPER_PATH}} install-system-units %{?*} || : \
3e5297
 fi \
3e5297
 %{nil}
3e5297
 
3e5297
-%systemd_user_post() %{expand:%systemd_post \\--global %%{?*}}
3e5297
+%systemd_user_post() \
3e5297
+%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_user_post}} \
3e5297
+if [ $1 -eq 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
3e5297
+    # Initial installation \
3e5297
+    {{SYSTEMD_UPDATE_HELPER_PATH}} install-user-units %{?*} || : \
3e5297
+fi \
3e5297
+%{nil}
3e5297
 
3e5297
 %systemd_preun() \
3e5297
 %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_preun}} \
3e5297
-if [ $1 -eq 0 ] && command -v systemctl >/dev/null; then \
3e5297
+if [ $1 -eq 0 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
3e5297
     # Package removal, not upgrade \
3e5297
-    if [ -d /run/systemd/system ]; then \
3e5297
-          systemctl --no-reload disable --now %{?*} || : \
3e5297
-    else \
3e5297
-          systemctl --no-reload disable %{?*} || : \
3e5297
-    fi \
3e5297
+    {{SYSTEMD_UPDATE_HELPER_PATH}} remove-system-units %{?*} || : \
3e5297
 fi \
3e5297
 %{nil}
3e5297
 
3e5297
 %systemd_user_preun() \
3e5297
 %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_user_preun}} \
3e5297
-if [ $1 -eq 0 ] && command -v systemctl >/dev/null; then \
3e5297
+if [ $1 -eq 0 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
3e5297
     # Package removal, not upgrade \
3e5297
-    systemctl --global disable %{?*} || : \
3e5297
+    {{SYSTEMD_UPDATE_HELPER_PATH}} remove-user-units %{?*} || : \
3e5297
 fi \
3e5297
 %{nil}
3e5297
 
3e5297
@@ -84,11 +86,9 @@ fi \
3e5297
 
3e5297
 %systemd_postun_with_restart() \
3e5297
 %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_postun_with_restart}} \
3e5297
-if [ $1 -ge 1 ] && command -v systemctl >/dev/null; then \
3e5297
+if [ $1 -ge 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
3e5297
     # Package upgrade, not uninstall \
3e5297
-    for unit in %{?*}; do \
3e5297
-        systemctl set-property $unit Markers=+needs-restart || : \
3e5297
-    done \
3e5297
+    {{SYSTEMD_UPDATE_HELPER_PATH}} mark-restart-system-units %{?*} || : \
3e5297
 fi \
3e5297
 %{nil}
3e5297
 
3e5297
diff --git a/src/rpm/meson.build b/src/rpm/meson.build
3e5297
index fc72fee73c..2ad3308cc1 100644
3e5297
--- a/src/rpm/meson.build
3e5297
+++ b/src/rpm/meson.build
3e5297
@@ -1,9 +1,13 @@
3e5297
 # SPDX-License-Identifier: LGPL-2.1-or-later
3e5297
 
3e5297
 in_files = [
3e5297
-        ['macros.systemd',      rpmmacrosdir != 'no'],
3e5297
-        ['triggers.systemd',    false],
3e5297
-        ['triggers.systemd.sh', false]]
3e5297
+        ['macros.systemd',        rpmmacrosdir != 'no', rpmmacrosdir],
3e5297
+
3e5297
+        # we conditionalize on rpmmacrosdir, but install into rootlibexecdir
3e5297
+        ['systemd-update-helper', rpmmacrosdir != 'no', rootlibexecdir, 'rwxr-xr-x'],
3e5297
+
3e5297
+        ['triggers.systemd',      false],
3e5297
+        ['triggers.systemd.sh',   false]]
3e5297
 
3e5297
 # The last two don't get installed anywhere, one of them needs to included in
3e5297
 # the rpm spec file definition instead.
3e5297
@@ -17,6 +21,7 @@ foreach tuple : in_files
3e5297
                 command : [meson_render_jinja2, config_h, '@INPUT@'],
3e5297
                 capture : true,
3e5297
                 install : tuple[1],
3e5297
-                install_dir : rpmmacrosdir,
3e5297
+                install_dir : tuple.length() > 2 ? tuple[2] : '',
3e5297
+                install_mode : tuple.length() > 3 ? tuple[3] : false,
3e5297
                 build_by_default : true)
3e5297
 endforeach
3e5297
diff --git a/src/rpm/systemd-update-helper.in b/src/rpm/systemd-update-helper.in
3e5297
new file mode 100755
3e5297
index 0000000000..9fa49fa131
3e5297
--- /dev/null
3e5297
+++ b/src/rpm/systemd-update-helper.in
3e5297
@@ -0,0 +1,60 @@
3e5297
+#!/bin/bash
3e5297
+set -eu
3e5297
+set -o pipefail
3e5297
+
3e5297
+command="${1:?}"
3e5297
+shift
3e5297
+
3e5297
+command -v systemctl >/dev/null || exit 0
3e5297
+
3e5297
+case "$command" in
3e5297
+    install-system-units)
3e5297
+        systemctl --no-reload preset "$@"
3e5297
+        ;;
3e5297
+
3e5297
+    install-user-units)
3e5297
+        systemctl --no-reload preset --global "$@"
3e5297
+        ;;
3e5297
+
3e5297
+    remove-system-units)
3e5297
+        if [ -d /run/systemd/system ]; then
3e5297
+            systemctl --no-reload disable --now "$@"
3e5297
+        else
3e5297
+            systemctl --no-reload disable "$@"
3e5297
+        fi
3e5297
+        ;;
3e5297
+
3e5297
+    remove-user-units)
3e5297
+        systemctl --global disable "$@"
3e5297
+        ;;
3e5297
+
3e5297
+    mark-restart-system-units)
3e5297
+        [ -d /run/systemd/system ] || exit 0
3e5297
+
3e5297
+        for unit in "$@"; do
3e5297
+            systemctl set-property "$unit" Markers=+needs-restart || :
3e5297
+        done
3e5297
+        ;;
3e5297
+
3e5297
+    system-reload-restart|system-reload|system-restart)
3e5297
+        if [ -n "$*" ]; then
3e5297
+            echo "Unexpected arguments for '$command': $*"
3e5297
+            exit 2
3e5297
+        fi
3e5297
+
3e5297
+        [ -d /run/systemd/system ] || exit 0
3e5297
+
3e5297
+        if [[ "$command" =~ reload ]]; then
3e5297
+            systemctl daemon-reload
3e5297
+        fi
3e5297
+
3e5297
+        if [[ "$command" =~ restart ]]; then
3e5297
+            systemctl reload-or-restart --marked
3e5297
+        fi
3e5297
+        ;;
3e5297
+
3e5297
+    *)
3e5297
+        echo "Unknown verb '$command'"
3e5297
+        exit 3
3e5297
+        ;;
3e5297
+esac
3e5297
diff --git a/src/rpm/triggers.systemd.in b/src/rpm/triggers.systemd.in
3e5297
index 247358008a..d29cc33dfd 100644
3e5297
--- a/src/rpm/triggers.systemd.in
3e5297
+++ b/src/rpm/triggers.systemd.in
3e5297
@@ -13,20 +13,11 @@
3e5297
 -- upgraded. We care about the case where a package is initially
3e5297
 -- installed, because other cases are covered by the *un scriptlets,
3e5297
 -- so sometimes we will reload needlessly.
3e5297
-if posix.access("/run/systemd/system") then
3e5297
-    pid = posix.fork()
3e5297
-    if pid == 0 then
3e5297
-        assert(posix.execp("systemctl", "daemon-reload"))
3e5297
-    elseif pid > 0 then
3e5297
-        posix.wait(pid)
3e5297
-    end
3e5297
-
3e5297
-    pid = posix.fork()
3e5297
-    if pid == 0 then
3e5297
-        assert(posix.execp("systemctl", "reload-or-restart", "--marked"))
3e5297
-    elseif pid > 0 then
3e5297
-        posix.wait(pid)
3e5297
-    end
3e5297
+pid = posix.fork()
3e5297
+if pid == 0 then
3e5297
+    assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "system-reload-restart"))
3e5297
+elseif pid > 0 then
3e5297
+    posix.wait(pid)
3e5297
 end
3e5297
 
3e5297
 %transfiletriggerpostun -P 1000100 -p <lua> -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
3e5297
@@ -35,24 +26,20 @@ end
3e5297
 -- On upgrade, we need to run daemon-reload after any new unit files
3e5297
 -- have been installed, but before %postun scripts in packages get
3e5297
 -- executed.
3e5297
-if posix.access("/run/systemd/system") then
3e5297
-    pid = posix.fork()
3e5297
-    if pid == 0 then
3e5297
-        assert(posix.execp("systemctl", "daemon-reload"))
3e5297
-    elseif pid > 0 then
3e5297
-        posix.wait(pid)
3e5297
-    end
3e5297
+pid = posix.fork()
3e5297
+if pid == 0 then
3e5297
+    assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "system-reload"))
3e5297
+elseif pid > 0 then
3e5297
+    posix.wait(pid)
3e5297
 end
3e5297
 
3e5297
 %transfiletriggerpostun -P 10000 -p <lua> -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
3e5297
 -- We restart remaining services that should be restarted here.
3e5297
-if posix.access("/run/systemd/system") then
3e5297
-    pid = posix.fork()
3e5297
-    if pid == 0 then
3e5297
-        assert(posix.execp("systemctl", "reload-or-restart", "--marked"))
3e5297
-    elseif pid > 0 then
3e5297
-        posix.wait(pid)
3e5297
-    end
3e5297
+pid = posix.fork()
3e5297
+if pid == 0 then
3e5297
+    assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "system-restart"))
3e5297
+elseif pid > 0 then
3e5297
+    posix.wait(pid)
3e5297
 end
3e5297
 
3e5297
 %transfiletriggerin -P 100700 -p <lua> -- {{SYSUSERS_DIR}}
3e5297
diff --git a/src/rpm/triggers.systemd.sh.in b/src/rpm/triggers.systemd.sh.in
3e5297
index 1631be18c9..83cd7617f8 100644
3e5297
--- a/src/rpm/triggers.systemd.sh.in
3e5297
+++ b/src/rpm/triggers.systemd.sh.in
3e5297
@@ -14,10 +14,7 @@
3e5297
 # upgraded. We care about the case where a package is initially
3e5297
 # installed, because other cases are covered by the *un scriptlets,
3e5297
 # so sometimes we will reload needlessly.
3e5297
-if test -d "/run/systemd/system"; then
3e5297
-  systemctl daemon-reload || :
3e5297
-  systemctl reload-or-restart --marked || :
3e5297
-fi
3e5297
+{{SYSTEMD_UPDATE_HELPER_PATH}} system-reload-restart || :
3e5297
 
3e5297
 %transfiletriggerpostun -P 1000100 -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
3e5297
 # On removal, we need to run daemon-reload after any units have been
3e5297
@@ -25,15 +22,11 @@ fi
3e5297
 # On upgrade, we need to run daemon-reload after any new unit files
3e5297
 # have been installed, but before %postun scripts in packages get
3e5297
 # executed.
3e5297
-if test -d "/run/systemd/system"; then
3e5297
-  systemctl daemon-reload || :
3e5297
-fi
3e5297
+{{SYSTEMD_UPDATE_HELPER_PATH}} system-reload || :
3e5297
 
3e5297
 %transfiletriggerpostun -P 10000 -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
3e5297
 # We restart remaining services that should be restarted here.
3e5297
-if test -d "/run/systemd/system"; then
3e5297
-  systemctl reload-or-restart --marked || :
3e5297
-fi
3e5297
+{{SYSTEMD_UPDATE_HELPER_PATH}} system-restart || :
3e5297
 
3e5297
 %transfiletriggerin -P 1000700 -- {{SYSUSERS_DIR}}
3e5297
 # This script will process files installed in {{SYSUSERS_DIR}} to create
3e5297
-- 
3e5297
2.31.1
3e5297