From 4f7c49685e223d1c90e52852f40ac9097ea11b0c Mon Sep 17 00:00:00 2001
From: Clayton Craft <clayton@craftyguy.net>
Date: Fri, 19 Jul 2024 13:13:42 -0700
Subject: [PATCH] systemd/systemd: add macros for package install scripts (MR
 5377)

These macros are based off of the upstream systemd RPM macros, but it
doesn't implement all of the macro functionality upstream. Initially
they will be used in the install scripts for apkbuilds that provide
systemd service unit files.

For example, a `$pkgname-systemd.post-install` script might have:
    . /usr/lib/systemd/systemd-apk-macros.sh
    systemd_service-post_install system sshd

And a `$pkgname-systemd.pre-deinstall` script might have:
    . /usr/lib/systemd/systemd-apk-macros.sh
    systemd_service_pre_deinstall user pipewire

One day maybe these could be upstreamed to systemd to provide some
apk/abuild compatible macros.

Co-authored-by: jane400 <pmos@j4ne.de>
---
 extra-repos/systemd/systemd/APKBUILD          |  5 ++
 .../systemd/systemd/systemd-apk-macros.sh     | 88 +++++++++++++++++++
 2 files changed, 93 insertions(+)
 create mode 100644 extra-repos/systemd/systemd/systemd-apk-macros.sh

diff --git a/extra-repos/systemd/systemd/APKBUILD b/extra-repos/systemd/systemd/APKBUILD
index c3ad018cd26..cecb45ba145 100644
--- a/extra-repos/systemd/systemd/APKBUILD
+++ b/extra-repos/systemd/systemd/APKBUILD
@@ -124,6 +124,7 @@ subpackages="
 
 source="
 	https://gitlab.com/postmarketOS/systemd/-/archive/$_pkgver/systemd-$_pkgver.tar.gz
+	systemd-apk-macros.sh
 	wired.network
 	"
 builddir="$srcdir/systemd-$_pkgver"
@@ -218,6 +219,9 @@ package() {
 	# ship default policy to leave services disabled
 	mkdir -p "$pkgdir"/usr/lib/systemd/system-preset
 	echo 'disable' > "$pkgdir"/usr/lib/systemd/system-preset/99-default.preset
+
+	install -Dm755 "$srcdir"/systemd-apk-macros.sh -t \
+		"$pkgdir"/usr/lib/systemd
 }
 
 udevd() {
@@ -396,5 +400,6 @@ dev() {
 
 sha512sums="
 f556d2eabcb732bed6bf7a5396be6f6d67eebf80218c7ae5525042fba661b1d242cb7941a720ff6d015a3b6af0ee545a4a647044a9da2acd16914d6c0cdda4c2  systemd-musl-v256.tar.gz
+73d10e72413c6b688c847c667ccb42ef1f273d498e4b4ff5344dc98432e05aab92bbcd42725935b15f3ebcc627729318ac592c3372cf22465f39ea93a5dedc8b  systemd-apk-macros.sh
 81c897fed8a3fbfb67ec591b2398a5d65e4af1b3ef379376c157c98d71f085b707f8ebc896d5571a94f99f8fc84fd6b43e3b879ca9b0d57fc6c4596034c7a777  wired.network
 "
diff --git a/extra-repos/systemd/systemd/systemd-apk-macros.sh b/extra-repos/systemd/systemd/systemd-apk-macros.sh
new file mode 100644
index 00000000000..446dc386534
--- /dev/null
+++ b/extra-repos/systemd/systemd/systemd-apk-macros.sh
@@ -0,0 +1,88 @@
+#!/bin/sh
+# systemd.preset reference:
+# 	https://www.freedesktop.org/software/systemd/man/latest/systemd.preset.html
+# Systemd macro file for RPM:
+# 	https://github.com/systemd/systemd/blob/main/src/rpm/macros.systemd.in
+# 	https://github.com/systemd/systemd/blob/main/src/rpm/systemd-update-helper.in
+
+SYSTEMD_BUS_TIMEOUT=5s
+
+is_systemd_running() {
+	[ -d "/run/systemd/running" ]
+}
+
+# runs `systemctl preset` on the list of services of the given type
+# $1: type of service, supported values: "user" or "system"
+# $@: list of service unit names, as you'd pass to `systemctl preset`
+# FIXME: this may not work with wildcards in unit names, and other input you
+# can give to the preset command
+systemd_service_post_install() {
+	local type="$1"
+	shift
+
+	if [ -z "$type" ]; then
+		echo "service type (user or service) not given"
+		exit 1
+	fi
+
+	if ! command -v systemctl > /dev/null; then
+		echo "systemctl is not available"
+		exit 1
+	fi
+
+	case "$type" in
+		"user")
+			systemctl --no-reload preset --global "$@"
+			;;
+		"system")
+			systemctl --no-reload preset "$@" || true
+			;;
+		*)
+			echo "unsupported service type: $type"
+		exit 1
+	esac
+}
+
+# disables the list of services of the given type
+# $1: type of service, supported values: "user" or "system"
+# $@: list of service unit names, as you'd pass to `systemctl disable`
+# FIXME: this may not work with wildcards in unit names, and other input you
+# can give to the disable command
+systemd_service_pre_deinstall() {
+	local type="$1"
+	shift
+
+	if [ -z "$type" ]; then
+		echo "service type (user/service) not given"
+		exit 1
+	fi
+
+	if ! command -v systemctl > /dev/null; then
+		echo "systemctl is not available"
+		exit 1
+	fi
+
+	case "$type" in
+		"user")
+			systemctl --global disable --no-warn "$@"
+			if is_systemd_running; then
+				local users
+				users=$(systemctl list-units 'user@*' --legend=no | sed -n -r 's/.*user@([0-9]+).service.*/\1/p')
+				for user in $users; do
+					systemctl --user -M "$user@" disable --now --no-warn "$@" &
+				done
+				wait
+			fi
+			;;
+		"system")
+			if is_systemd_running; then
+				systemctl --no-reload disable --now --no-warn $system_preset
+			else
+				systemctl --no-reload disable --no-warn $system_preset
+			fi
+			;;
+		*)
+			echo "unsupported service type: $type"
+			exit 1
+	esac
+}
-- 
GitLab