diff options
Diffstat (limited to 'src/rpm')
-rw-r--r-- | src/rpm/macros.systemd.in | 176 | ||||
-rw-r--r-- | src/rpm/meson.build | 25 | ||||
-rwxr-xr-x | src/rpm/systemd-update-helper.in | 119 | ||||
-rw-r--r-- | src/rpm/triggers.systemd.in | 122 | ||||
-rw-r--r-- | src/rpm/triggers.systemd.sh.in | 87 |
5 files changed, 529 insertions, 0 deletions
diff --git a/src/rpm/macros.systemd.in b/src/rpm/macros.systemd.in new file mode 100644 index 0000000..8880078 --- /dev/null +++ b/src/rpm/macros.systemd.in @@ -0,0 +1,176 @@ +# -*- Mode: rpm-spec; indent-tabs-mode: nil -*- */ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# This file is part of systemd. + +# RPM macros for packages installing systemd unit files + +%_systemd_util_dir {{ROOTLIBEXECDIR}} +%_unitdir {{SYSTEM_DATA_UNIT_DIR}} +%_userunitdir {{USER_DATA_UNIT_DIR}} +%_presetdir {{SYSTEM_PRESET_DIR}} +%_userpresetdir {{USER_PRESET_DIR}} +%_udevhwdbdir {{UDEV_HWDB_DIR}} +%_udevrulesdir {{UDEV_RULES_DIR}} +%_journalcatalogdir {{SYSTEMD_CATALOG_DIR}} +%_binfmtdir {{BINFMT_DIR}} +%_sysctldir {{SYSCTL_DIR}} +%_sysusersdir {{SYSUSERS_DIR}} +%_tmpfilesdir {{TMPFILES_DIR}} +%_user_tmpfilesdir {{USER_TMPFILES_DIR}} +%_environmentdir {{ENVIRONMENT_DIR}} +%_modulesloaddir {{MODULESLOAD_DIR}} +%_modprobedir {{MODPROBE_DIR}} +%_systemdgeneratordir {{SYSTEM_GENERATOR_DIR}} +%_systemdusergeneratordir {{USER_GENERATOR_DIR}} +%_systemd_system_env_generator_dir {{SYSTEM_ENV_GENERATOR_DIR}} +%_systemd_user_env_generator_dir {{USER_ENV_GENERATOR_DIR}} + +# Because we had one release with a typo... +# This is temporary (Remove after systemd 240 is released) +%_environmnentdir %{warn:Use %%_environmentdir instead}%_environmentdir + +%systemd_requires \ +Requires(post): systemd \ +Requires(preun): systemd \ +Requires(postun): systemd \ +%{nil} + +%systemd_ordering \ +OrderWithRequires(post): systemd \ +OrderWithRequires(preun): systemd \ +OrderWithRequires(postun): systemd \ +%{nil} + +%__systemd_someargs_0(:) %{error:The %%%1 macro requires some arguments} +%__systemd_twoargs_2() %{nil} + +%systemd_post() \ +%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_post}} \ +if [ $1 -eq 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \ + # Initial installation \ + {{SYSTEMD_UPDATE_HELPER_PATH}} install-system-units %{?*} || : \ +fi \ +%{nil} + +%systemd_user_post() \ +%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_user_post}} \ +if [ $1 -eq 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \ + # Initial installation \ + {{SYSTEMD_UPDATE_HELPER_PATH}} install-user-units %{?*} || : \ +fi \ +%{nil} + +%systemd_preun() \ +%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_preun}} \ +if [ $1 -eq 0 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \ + # Package removal, not upgrade \ + {{SYSTEMD_UPDATE_HELPER_PATH}} remove-system-units %{?*} || : \ +fi \ +%{nil} + +%systemd_user_preun() \ +%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_user_preun}} \ +if [ $1 -eq 0 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \ + # Package removal, not upgrade \ + {{SYSTEMD_UPDATE_HELPER_PATH}} remove-user-units %{?*} || : \ +fi \ +%{nil} + +%systemd_postun() \ +%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_postun}} \ +%{nil} + +%systemd_user_postun() \ +%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_user_postun}} \ +%{nil} + +%systemd_postun_with_restart() \ +%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_postun_with_restart}} \ +if [ $1 -ge 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \ + # Package upgrade, not uninstall \ + {{SYSTEMD_UPDATE_HELPER_PATH}} mark-restart-system-units %{?*} || : \ +fi \ +%{nil} + +%systemd_user_postun_with_restart() \ +%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_user_postun_with_restart}} \ +if [ $1 -ge 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \ + # Package upgrade, not uninstall \ + {{SYSTEMD_UPDATE_HELPER_PATH}} mark-restart-user-units %{?*} || : \ +fi \ +%{nil} + +%udev_hwdb_update() %{nil} + +%udev_rules_update() %{nil} + +%journal_catalog_update() %{nil} + +# Deprecated. Use %tmpfiles_create_package instead +%tmpfiles_create() \ +%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# tmpfiles_create}} \ +command -v systemd-tmpfiles >/dev/null && systemd-tmpfiles --create %{?*} || : \ +%{nil} + +# Deprecated. Use %sysusers_create_package instead +%sysusers_create() \ +%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# sysusers_create}} \ +command -v systemd-sysusers >/dev/null && systemd-sysusers %{?*} || : \ +%{nil} + +%sysusers_create_inline() \ +command -v systemd-sysusers >/dev/null && systemd-sysusers - <<SYSTEMD_INLINE_EOF || : \ +%{?*} \ +SYSTEMD_INLINE_EOF\ +%{nil} + +# This should be used by package installation scripts which require users or +# groups to be present before the files installed by the package are present on +# disk (for example because some files are owned by those users or groups). +# +# Example: +# Source1: %{name}-sysusers.conf +# ... +# %install +# install -D %SOURCE1 %{buildroot}%{_sysusersdir}/%{name}.conf +# %pre +# %sysusers_create_package %{name} %SOURCE1 +# %files +# %{_sysusersdir}/%{name}.conf +%sysusers_create_package() \ +%{expand:%%{?!__systemd_twoargs_%#:%%{error:The %%%%sysusers_create_package macro requires two arguments}}} \ +systemd-sysusers --replace=%_sysusersdir/%1.conf - <<SYSTEMD_INLINE_EOF || : \ +%(cat %2) \ +SYSTEMD_INLINE_EOF\ +%{nil} + +# This may be used by package installation scripts to create files according to +# their tmpfiles configuration from a package installation script, even before +# the files of that package are installed on disk. +# +# Example: +# Source1: %{name}-tmpfiles.conf +# ... +# %install +# install -D %SOURCE1 %{buildroot}%{_tmpfilesdir}/%{name}.conf +# %pre +# %tmpfiles_create_package %{name} %SOURCE1 +# %files +# %{_tmpfilesdir}/%{name}.conf +%tmpfiles_create_package() \ +%{expand:%%{?!__systemd_twoargs_%#:%%{error:The %%%%tmpfiles_create_package macro requires two arguments}}} \ +systemd-tmpfiles --replace=%_tmpfilesdir/%1.conf --create - <<SYSTEMD_INLINE_EOF || : \ +%(cat %2) \ +SYSTEMD_INLINE_EOF\ +%{nil} + +%sysctl_apply() \ +%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# sysctl_apply}} \ +[ -x {{ROOTLIBEXECDIR}}/systemd-sysctl ] && {{ROOTLIBEXECDIR}}/systemd-sysctl %{?*} || : \ +%{nil} + +%binfmt_apply() \ +%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# binfmt_apply}} \ +[ -x {{ROOTLIBEXECDIR}}/systemd-binfmt ] && {{ROOTLIBEXECDIR}}/systemd-binfmt %{?*} || : \ +%{nil} diff --git a/src/rpm/meson.build b/src/rpm/meson.build new file mode 100644 index 0000000..8176659 --- /dev/null +++ b/src/rpm/meson.build @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +in_files = [ + ['macros.systemd', rpmmacrosdir != 'no', rpmmacrosdir], + + # we conditionalize on rpmmacrosdir, but install into rootlibexecdir + ['systemd-update-helper', rpmmacrosdir != 'no', rootlibexecdir], + + ['triggers.systemd', false], + ['triggers.systemd.sh', false]] + +# The last two don't get installed anywhere, one of them needs to included in +# the rpm spec file definition instead. + +foreach tuple : in_files + file = tuple[0] + custom_target( + file, + input : file + '.in', + output : file, + command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'], + install : tuple[1], + install_dir : tuple.length() > 2 ? tuple[2] : '', + build_by_default : true) +endforeach diff --git a/src/rpm/systemd-update-helper.in b/src/rpm/systemd-update-helper.in new file mode 100755 index 0000000..ab8cdc0 --- /dev/null +++ b/src/rpm/systemd-update-helper.in @@ -0,0 +1,119 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -eu +set -o pipefail + +command="${1:?}" +shift + +command -v systemctl >/dev/null || exit 0 + +case "$command" in + install-system-units) + systemctl --no-reload preset "$@" + ;; + + install-user-units) + systemctl --no-reload preset --global "$@" + ;; + + remove-system-units) + if [ -d /run/systemd/system ]; then + systemctl --no-reload disable --now "$@" + else + systemctl --no-reload disable "$@" + fi + ;; + + remove-user-units) + systemctl --global disable "$@" + + [ -d /run/systemd/system ] || exit 0 + + users=$(systemctl list-units 'user@*' --legend=no | sed -n -r 's/.*user@([0-9]+).service.*/\1/p') + for user in $users; do + SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \ + systemctl --user -M "$user@" disable --now "$@" & + done + wait + ;; + + mark-restart-system-units) + [ -d /run/systemd/system ] || exit 0 + + for unit in "$@"; do + systemctl set-property "$unit" Markers=+needs-restart & + done + wait + ;; + + mark-restart-user-units) + [ -d /run/systemd/system ] || exit 0 + + users=$(systemctl list-units 'user@*' --legend=no | sed -n -r 's/.*user@([0-9]+).service.*/\1/p') + for user in $users; do + for unit in "$@"; do + SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \ + systemctl --user -M "$user@" set-property "$unit" Markers=+needs-restart & + done + done + wait + ;; + + system-reload-restart|system-reload|system-restart) + if [ -n "$*" ]; then + echo "Unexpected arguments for '$command': $*" + exit 2 + fi + + [ -d /run/systemd/system ] || exit 0 + + if [[ "$command" =~ reload ]]; then + systemctl daemon-reload + fi + + if [[ "$command" =~ restart ]]; then + systemctl reload-or-restart --marked + fi + ;; + + user-reload-restart|user-reload|user-restart|user-reexec) + if [ -n "$*" ]; then + echo "Unexpected arguments for '$command': $*" + exit 2 + fi + + [ -d /run/systemd/system ] || exit 0 + + users=$(systemctl list-units 'user@*' --legend=no | sed -n -r 's/.*user@([0-9]+).service.*/\1/p') + + if [[ "$command" =~ reexec ]]; then + for user in $users; do + SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \ + systemctl --user -M "$user@" daemon-reexec & + done + wait + fi + + if [[ "$command" =~ reload ]]; then + for user in $users; do + SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \ + systemctl --user -M "$user@" daemon-reload & + done + wait + fi + + if [[ "$command" =~ restart ]]; then + for user in $users; do + SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \ + systemctl --user -M "$user@" reload-or-restart --marked & + done + wait + fi + ;; + + *) + echo "Unknown verb '$command'" + exit 3 + ;; +esac diff --git a/src/rpm/triggers.systemd.in b/src/rpm/triggers.systemd.in new file mode 100644 index 0000000..39a1f8d --- /dev/null +++ b/src/rpm/triggers.systemd.in @@ -0,0 +1,122 @@ +# -*- Mode: rpm-spec; indent-tabs-mode: nil -*- */ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# This file is part of systemd. +# Copyright © 2018 Neal Gompa + +# The contents of this are an example to be copied into systemd.spec. +# +# Minimum rpm version supported: 4.14.0 + +%transfiletriggerin -P 900900 -p <lua> -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system +-- This script will run after any package is initially installed or +-- upgraded. We care about the case where a package is initially +-- installed, because other cases are covered by the *un scriptlets, +-- so sometimes we will reload needlessly. +pid = posix.fork() +if pid == 0 then + assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "system-reload-restart")) +elseif pid > 0 then + posix.wait(pid) +end + +%transfiletriggerin -P 900899 -p <lua> -- {{USER_DATA_UNIT_DIR}} /etc/systemd/user +pid = posix.fork() +if pid == 0 then + assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "user-reload-restart")) +elseif pid > 0 then + posix.wait(pid) +end + +%transfiletriggerpostun -P 1000100 -p <lua> -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system +-- On removal, we need to run daemon-reload after any units have been +-- removed. +-- On upgrade, we need to run daemon-reload after any new unit files +-- have been installed, but before %postun scripts in packages get +-- executed. +pid = posix.fork() +if pid == 0 then + assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "system-reload")) +elseif pid > 0 then + posix.wait(pid) +end + +%transfiletriggerpostun -P 1000100 -p <lua> -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system +-- Execute daemon-reload in user managers. +pid = posix.fork() +if pid == 0 then + assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "user-reload")) +elseif pid > 0 then + posix.wait(pid) +end + +%transfiletriggerpostun -P 10000 -p <lua> -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system +-- We restart remaining system services that should be restarted here. +pid = posix.fork() +if pid == 0 then + assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "system-restart")) +elseif pid > 0 then + posix.wait(pid) +end + +%transfiletriggerpostun -P 9999 -p <lua> -- {{USER_DATA_UNIT_DIR}} /etc/systemd/user +-- We restart remaining user services that should be restarted here. +pid = posix.fork() +if pid == 0 then + assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "user-restart")) +elseif pid > 0 then + posix.wait(pid) +end + +%transfiletriggerin -P 1000700 -p <lua> -- {{SYSUSERS_DIR}} +-- This script will process files installed in {{SYSUSERS_DIR}} to create +-- specified users automatically. The priority is set such that it +-- will run before the tmpfiles file trigger. +assert(rpm.execute("systemd-sysusers")) + +%transfiletriggerin -P 1000700 udev -p <lua> -- {{UDEV_HWDB_DIR}} +-- This script will automatically invoke hwdb update if files have been +-- installed or updated in {{UDEV_HWDB_DIR}}. +assert(rpm.execute("systemd-hwdb", "update")) + +%transfiletriggerin -P 1000700 -p <lua> -- {{SYSTEMD_CATALOG_DIR}} +-- This script will automatically invoke journal catalog update if files +-- have been installed or updated in {{SYSTEMD_CATALOG_DIR}}. +assert(rpm.execute("journalctl", "--update-catalog")) + +%transfiletriggerin -P 1000700 -p <lua> -- {{BINFMT_DIR}} +-- This script will automatically apply binfmt rules if files have been +-- installed or updated in {{BINFMT_DIR}}. +if posix.access("/run/systemd/system") then + pid = posix.fork() + if pid == 0 then + assert(posix.exec("{{ROOTLIBEXECDIR}}/systemd-binfmt")) + elseif pid > 0 then + posix.wait(pid) + end +end + +%transfiletriggerin -P 1000600 -p <lua> -- {{TMPFILES_DIR}} +-- This script will process files installed in {{TMPFILES_DIR}} to create +-- tmpfiles automatically. The priority is set such that it will run +-- after the sysusers file trigger, but before any other triggers. +assert(rpm.execute("systemd-tmpfiles", "--create")) + +%transfiletriggerin -P 1000600 udev -p <lua> -- {{UDEV_RULES_DIR}} +-- This script will automatically update udev with new rules if files +-- have been installed or updated in {{UDEV_RULES_DIR}}. +if posix.access("/run/udev/control") then + assert(rpm.execute("udevadm", "control", "--reload")) +end + +%transfiletriggerin -P 1000500 -p <lua> -- {{SYSCTL_DIR}} +-- This script will automatically apply sysctl rules if files have been +-- installed or updated in {{SYSCTL_DIR}}. +if posix.access("/run/systemd/system") then + pid = posix.fork() + if pid == 0 then + assert(posix.exec("{{ROOTLIBEXECDIR}}/systemd-sysctl")) + elseif pid > 0 then + posix.wait(pid) + end +end diff --git a/src/rpm/triggers.systemd.sh.in b/src/rpm/triggers.systemd.sh.in new file mode 100644 index 0000000..8c301f5 --- /dev/null +++ b/src/rpm/triggers.systemd.sh.in @@ -0,0 +1,87 @@ +# -*- Mode: rpm-spec; indent-tabs-mode: nil -*- */ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# This file is part of systemd. +# +# Copyright 2018 Neal Gompa + +# The contents of this are an example to be copied into systemd.spec. +# +# Minimum rpm version supported: 4.14.0 + +%transfiletriggerin -P 900900 -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system +# This script will run after any package is initially installed or +# upgraded. We care about the case where a package is initially +# installed, because other cases are covered by the *un scriptlets, +# so sometimes we will reload needlessly. +{{SYSTEMD_UPDATE_HELPER_PATH}} system-reload-restart || : + +%transfiletriggerin -P 900899 -- {{USER_DATA_UNIT_DIR}} /etc/systemd/user +{{SYSTEMD_UPDATE_HELPER_PATH}} user-reload-restart || : + +%transfiletriggerpostun -P 1000100 -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system +# On removal, we need to run daemon-reload after any units have been +# removed. +# On upgrade, we need to run daemon-reload after any new unit files +# have been installed, but before %postun scripts in packages get +# executed. +{{SYSTEMD_UPDATE_HELPER_PATH}} system-reload || : + +%transfiletriggerpostun -P 1000099 -- {{USER_DATA_UNIT_DIR}} /etc/systemd/user +# Execute daemon-reload in user managers. +{{SYSTEMD_UPDATE_HELPER_PATH}} user-reload || : + +%transfiletriggerpostun -P 10000 -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system +# We restart remaining system services that should be restarted here. +{{SYSTEMD_UPDATE_HELPER_PATH}} system-restart || : + +%transfiletriggerpostun -P 9999 -- {{USER_DATA_UNIT_DIR}} /etc/systemd/user +# We restart remaining user services that should be restarted here. +{{SYSTEMD_UPDATE_HELPER_PATH}} user-restart || : + +%transfiletriggerin -P 1000700 -- {{SYSUSERS_DIR}} +# This script will process files installed in {{SYSUSERS_DIR}} to create +# specified users automatically. The priority is set such that it +# will run before the tmpfiles file trigger. +systemd-sysusers || : + +%transfiletriggerin -P 1000700 udev -- {{UDEV_HWDB_DIR}} +# This script will automatically invoke hwdb update if files have been +# installed or updated in {{UDEV_HWDB_DIR}}. +systemd-hwdb update || : + +%transfiletriggerin -P 1000700 -- {{SYSTEMD_CATALOG_DIR}} +# This script will automatically invoke journal catalog update if files +# have been installed or updated in {{SYSTEMD_CATALOG_DIR}}. +journalctl --update-catalog || : + +%transfiletriggerin -P 1000700 -- {{BINFMT_DIR}} +# This script will automatically apply binfmt rules if files have been +# installed or updated in {{BINFMT_DIR}}. +if test -d "/run/systemd/system"; then + # systemd-binfmt might fail if binfmt_misc kernel module is not loaded + # during install + {{ROOTLIBEXECDIR}}/systemd-binfmt || : +fi + +%transfiletriggerin -P 1000600 -- {{TMPFILES_DIR}} +# This script will process files installed in {{TMPFILES_DIR}} to create +# tmpfiles automatically. The priority is set such that it will run +# after the sysusers file trigger, but before any other triggers. +if test -d "/run/systemd/system"; then + systemd-tmpfiles --create || : +fi + +%transfiletriggerin -P 1000600 udev -- {{UDEV_RULES_DIR}} +# This script will automatically update udev with new rules if files +# have been installed or updated in {{UDEV_RULES_DIR}}. +if test -e /run/udev/control; then + udevadm control --reload || : +fi + +%transfiletriggerin -P 1000500 -- {{SYSCTL_DIR}} +# This script will automatically apply sysctl rules if files have been +# installed or updated in {{SYSCTL_DIR}}. +if test -d "/run/systemd/system"; then + {{ROOTLIBEXECDIR}}/systemd-sysctl || : +fi |