diff --git a/Makefile b/Makefile index 6f4aba5..0b40f6f 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,16 @@ CONF_DIR=/etc/smart-restart-conf.d HOOK_ACTION=install.action HOOK_ACTION_TEMPLATE=$(HOOK_ACTION).in + +# dnf5 loads post-transaction hooks through the libdnf5 actions plugin: +# *.actions files under /etc/dnf/libdnf5-plugins/actions.d with a +# "HOOK:PKG_FILTER:DIRECTION:OPTIONS:CMD" line format. +ifeq ($(pkg_manager),dnf5) +HOOK_DIR=/etc/dnf/libdnf5-plugins/actions.d +HOOK_ACTION=smart-restart.actions +HOOK_ACTION_TEMPLATE=install.actions.in +endif + DENYLIST_CONF_FILE=default-denylist MAN_FILE=smart-restart.1 MAN_FILE_LOCATION=/usr/share/man/man1 diff --git a/bin/smart-restart.sh b/bin/smart-restart.sh index 8fb5d21..9e35962 100755 --- a/bin/smart-restart.sh +++ b/bin/smart-restart.sh @@ -22,6 +22,16 @@ readonly POST_RESTART=("$CONF_PATH"/*post-restart) shopt -u nullglob SYSCTL_COMMAND="${SYSCTL_COMMAND:-systemctl}" +# dnf5-only systems implement needs-restarting as a dnf5 subcommand (a +# compat shim may still provide /usr/bin/needs-restarting). Detect the +# active stack by what /usr/bin/dnf resolves to, so a side-installed dnf5 +# on a dnf4 system does not flip the tool. When this script runs from the +# libdnf5 actions plugin hook, the calling dnf process still holds the +# system repository lock, so the inner dnf5 must skip file locking to +# avoid deadlocking on its parent transaction. +if [[ -z "${NEEDS_RESTARTING_COMMAND:-}" ]] && [[ "$(readlink -f /usr/bin/dnf 2>/dev/null)" == *dnf5 ]]; then + NEEDS_RESTARTING_COMMAND="dnf5 needs-restarting --skip-file-locks" +fi NEEDS_RESTARTING_COMMAND="${NEEDS_RESTARTING_COMMAND:-/usr/bin/needs-restarting}" IS_TESTING=${IS_TESTING:-} diff --git a/conf/install.actions.in b/conf/install.actions.in new file mode 100644 index 0000000..f20183b --- /dev/null +++ b/conf/install.actions.in @@ -0,0 +1,4 @@ +# Run smart-restart after every transaction that installs or upgrades +# packages. The libdnf5 actions plugin deduplicates identical expanded +# commands, so this runs once per transaction. +post_transaction:*:#COMMAND#::sh #PREFIX#/smart-restart.sh diff --git a/smart-restart.spec b/smart-restart.spec index e3275fb..068b6e1 100644 --- a/smart-restart.spec +++ b/smart-restart.spec @@ -17,11 +17,22 @@ License: Apache 2.0 Requires: yum-utils Requires: yum-plugin-post-transaction-actions %define _plugin_path yum/post-actions/ +%define _hook_file install.action %define pkg_manager yum +%elif 0%{?amzn} >= 2027 +# dnf5-only. needs-restarting is the dnf5 subcommand from dnf5-plugins, +# and the post-transaction hook runs through the libdnf5 actions plugin +# instead of dnf4's post-transaction-actions plugin. +Requires: dnf5-plugins +Requires: libdnf5-plugin-actions +%define _plugin_path dnf/libdnf5-plugins/actions.d/ +%define _hook_file smart-restart.actions +%define pkg_manager dnf5 %else Requires: dnf-utils Requires: dnf-plugin-post-transaction-actions %define _plugin_path dnf/plugins/post-transaction-actions.d/ +%define _hook_file install.action %define pkg_manager dnf %endif @@ -42,7 +53,7 @@ make DEST_DIR=$RPM_BUILD_ROOT pkg_manager=%{pkg_manager} PREFIX=%{_bindir} insta %files %defattr(-,root,root,-) %{_bindir}/%{name}.sh -%config %{_sysconfdir}/%{_plugin_path}/install.action +%config %{_sysconfdir}/%{_plugin_path}/%{_hook_file} %config %{_sysconfdir}/smart-restart-conf.d/default-denylist %doc %{_mandir}/man1/smart-restart.1*