205 lines
5.9 KiB
Bash
205 lines
5.9 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
|
|
|
|
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
|
|
# Clean any leftovers that might remain from a previous transaction
|
|
# which exited abnormally.
|
|
rm -f /run/systemd/rpm/$mode/*/"$unit"
|
|
|
|
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 (on install or upgrade)
|
|
do_mark_install_units system "$@"
|
|
;;
|
|
|
|
mark-install-user-units)
|
|
do_mark_install_units user "$@"
|
|
;;
|
|
|
|
install-system-units) # called from %post (on install or upgrade)
|
|
do_install_units system "$@"
|
|
;;
|
|
|
|
install-user-units)
|
|
do_install_units user "$@"
|
|
;;
|
|
|
|
remove-system-units) # called from %preun (on removal)
|
|
do_remove_units system "$@"
|
|
;;
|
|
|
|
remove-user-units)
|
|
do_remove_units user "$@"
|
|
;;
|
|
|
|
mark-restart-system-units) # called from %postun (on upgrade)
|
|
[ -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 %transfiletriggerin
|
|
if [ -n "$*" ]; then
|
|
echo >&2 "Unexpected arguments for '$command': $*"
|
|
exit 2
|
|
fi
|
|
|
|
# Clean up all flags created during executions of %pre (i.e. on
|
|
# install/upgrade/rename) at the very end of the transaction.
|
|
rm -fr /run/systemd/rpm/system
|
|
|
|
[ -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 %transfiletriggerin
|
|
if [ -n "$*" ]; then
|
|
echo >&2 "Unexpected arguments for '$command': $*"
|
|
exit 2
|
|
fi
|
|
|
|
# Clean up all flags created during executions of %pre (i.e. on
|
|
# install/upgrade/rename) at the very end of the transaction.
|
|
rm -fr /run/systemd/rpm/user
|
|
|
|
[ -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)
|
|
# Not used anymore, to be removed
|
|
;;
|
|
|
|
*)
|
|
echo >&2 "Unknown verb '$command'"
|
|
exit 3
|
|
;;
|
|
esac
|