systemd/systemd-update-helper
Franck Bui 51ccc3bb3e - Reexecute user managers on package updates.
For now we send signal to user instances to trigger their reexecution. It's
  asynchronous but it shouldn't cause any problem in practice and it's probably
  safer than triggering reexecution with "systemctl --user -M 1000@
  daemon-reexec" command. The latter command creates a new PAM session behind
  the scene bringing with it the known issue (upstream issue #8598) with
  "(sd-pam)" helper process when the PAM session is being closed.

OBS-URL: https://build.opensuse.org/package/show/Base:System/systemd?expand=0&rev=1393
2023-06-01 15:56:32 +00:00

173 lines
4.8 KiB
Bash

#!/usr/bin/env bash
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This helper is aimed at being used by the systemd rpm macros only.
#
set -eu
set -o pipefail
command="${1:?}"
shift
command -v systemctl >/dev/null || exit 0
case "$command" in
mark-install-system-units)
mkdir -p /run/systemd/rpm/needs-preset
for unit in "$@" ; do
if [ ! -e /usr/lib/systemd/system/"$unit" ]; then
touch /run/systemd/rpm/needs-preset/"$unit"
fi
done
;;
install-system-units)
units=()
for unit in "$@" ; do
if [ -e /run/systemd/rpm/needs-preset/"$unit" ]; then
rm /run/systemd/rpm/needs-preset/"$unit"
units+=("$unit")
fi
done
[ ${#units[*]} -gt 0 ] &&
systemctl --no-reload preset "${units[@]}"
;;
mark-install-user-units)
mkdir -p /run/systemd/rpm/needs-user-preset
for unit in "$@" ; do
if [ ! -e /usr/lib/systemd/user/"$unit" ]; then
touch /run/systemd/rpm/needs-user-preset/"$unit"
fi
done
;;
install-user-units)
units=()
for unit in "$@" ; do
if [ -e /run/systemd/rpm/needs-user-preset/"$unit" ]; then
rm /run/systemd/rpm/needs-user-preset/"$unit"
units+=("$unit")
fi
done
[ ${#units[*]} -gt 0 ] &&
systemctl --no-reload preset --global "$@" || :
;;
remove-system-units)
if [ -d /run/systemd/system ]; then
systemctl --no-reload disable --now --no-warn "$@"
else
systemctl --no-reload disable --no-warn "$@"
fi
;;
remove-user-units)
systemctl --global disable --no-warn "$@"
[ -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=15s \
systemctl --user -M "$user@" disable --now --no-warn "$@" &
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=15s \
systemctl --user -M "$user@" set-property "$unit" Markers=+needs-restart &
done
done
wait
;;
system-reload-restart|system-reload|system-restart)
if [ -n "$*" ]; then
echo >&2 "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-reexec)
if [ -n "$*" ]; then
echo >&2 "Unexpected arguments for '$command': $*"
exit 2
fi
[ -d /run/systemd/system ] || exit 0
# Reexecute user manager instances (if any). It is asynchronous but it
# shouldn't be a problem in practice because systemd main package is not
# shipping any user services currently. A problem would arise only if a
# new version of a user service relied on an option that would be only
# understood by the latest version of the user manager and the user unit
# would be restarted before the user manager get reexecuted.
systemctl kill --kill-who=main --signal=SIGRTMIN+25 "user@*.service"
;;
user-reload-restart|user-reload|user-restart)
if [ -n "$*" ]; then
echo >&2 "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" =~ reload ]]; then
for user in $users; do
SYSTEMD_BUS_TIMEOUT=15s \
systemctl --user -M "$user@" daemon-reload &
done
wait
fi
if [[ "$command" =~ restart ]]; then
for user in $users; do
SYSTEMD_BUS_TIMEOUT=15s \
systemctl --user -M "$user@" reload-or-restart --marked &
done
wait
fi
;;
*)
echo >&2 "Unknown verb '$command'"
exit 3
;;
esac