File systemd-update-helper of Package systemd
#!/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
UPDATE_HELPER_USER_TIMEOUT_SEC=15
do_mark_install_units() {
mode=$1
shift
mkdir -p /run/systemd/rpm/$mode/{needs-preset,dont-disable}
for unit in "$@" ; do
if [ ! -e /usr/lib/systemd/$mode/"$unit" ]; then
# The unit is being introduced: remember we need to apply preset on
# this new unit regardless of whether it's a package update or
# installation.
touch /run/systemd/rpm/$mode/needs-preset/"$unit"
fi
# All passed units are part of a package being installed or updated and
# therefore should not be disabled by the removal of a different package
# part of the same rpm transaction. This can happen when the package
# shipping the unit is being renamed (e.g. from "A" to "B"), where "A"
# is installed first, followed by the removal "B". In that case, "B" is
# removed and its %preun scriptlet runs %systemd_preun on the unit.
touch /run/systemd/rpm/$mode/dont-disable/"$unit"
done
}
do_install_units() {
mode=$1
shift
units=()
for unit in "$@" ; do
if [ -e /run/systemd/rpm/$mode/needs-preset/"$unit" ]; then
units+=("$unit")
fi
done
[ ${#units[*]} -gt 0 ] && {
case $mode in
system)
systemctl --no-reload preset "${units[@]}" ;;
user)
systemctl --no-reload preset --global "${units[@]}" ;;
esac
}
}
do_remove_units() {
mode=$1
shift
units=()
for unit in "$@" ; do
if [ ! -e /run/systemd/rpm/$mode/dont-disable/"$unit" ]; then
units+=("$unit")
fi
done
[ ${#units[*]} -eq 0 ] && return
case $mode in
system)
if [ -d /run/systemd/system ]; then
systemctl --no-reload disable --now --no-warn "${units[@]}"
else
systemctl --no-reload disable --no-warn "${units[@]}"
fi
;;
user)
systemctl --global disable --no-warn "${units[@]}"
[ -d /run/systemd/system ] || return
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_SEC}s \
systemctl --user -M "$user@" disable --now --no-warn "${units[@]}" &
done
wait
;;
esac
}
case "$command" in
mark-install-system-units) # called from %pre
do_mark_install_units system "$@"
;;
mark-install-user-units)
do_mark_install_units user "$@"
;;
install-system-units) # called from %post
do_install_units system "$@"
;;
install-user-units)
do_install_units user "$@"
;;
remove-system-units) # called from %preun
do_remove_units system "$@"
;;
remove-user-units)
do_remove_units user "$@"
;;
mark-restart-system-units) # called from %postun
[ -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_SEC}s \
systemctl --user -M "$user@" set-property "$unit" Markers=+needs-restart &
done
done
wait
;;
system-reload-restart|system-reload|system-restart) # called from the filetriggers
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-reload-restart|user-reload|user-restart|user-reexec) # called from the filetriggers
if [ -n "$*" ]; then
echo >&2 "Unexpected arguments for '$command': $*"
exit 2
fi
[ -d /run/systemd/system ] || exit 0
if [[ "$command" =~ reexec|reload ]]; then
SYSTEMD_BUS_TIMEOUT=${UPDATE_HELPER_USER_TIMEOUT_SEC}s systemctl reload "user@*.service"
fi
if [[ "$command" =~ restart ]]; then
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_SEC}s \
systemctl --user -M "$user@" reload-or-restart --marked &
done
wait
fi
;;
clean-state)
rm -fr /run/systemd/rpm
;;
*)
echo >&2 "Unknown verb '$command'"
exit 3
;;
esac