diff --git a/dnf-plugins-core.spec b/dnf-plugins-core.spec index 42d0884..012dde8 100644 --- a/dnf-plugins-core.spec +++ b/dnf-plugins-core.spec @@ -99,8 +99,10 @@ Summary: Core Plugins for DNF %{?python_provide:%python_provide python2-%{name}} BuildRequires: python2-dnf >= %{dnf_lowest_compatible} %if 0%{?rhel} && 0%{?rhel} <= 7 +BuildRequires: dbus-python BuildRequires: python-nose %else +BuildRequires: python2-dbus BuildRequires: python2-nose %endif BuildRequires: python2-devel @@ -110,8 +112,10 @@ Requires: python2-distro Requires: python2-dnf >= %{dnf_lowest_compatible} Requires: python2-hawkey >= %{hawkey_version} %if 0%{?rhel} && 0%{?rhel} <= 7 +Requires: dbus-python Requires: python-dateutil %else +Requires: python2-dbus Requires: python2-dateutil %endif Provides: python2-dnf-plugins-extras-debug = %{version}-%{release} @@ -140,12 +144,14 @@ Additionally provides generate_completion_cache passive plugin. %package -n python3-%{name} Summary: Core Plugins for DNF %{?python_provide:%python_provide python3-%{name}} +BuildRequires: python3-dbus BuildRequires: python3-devel BuildRequires: python3-dnf >= %{dnf_lowest_compatible} BuildRequires: python3-nose %if 0%{?fedora} Requires: python3-distro %endif +Requires: python3-dbus Requires: python3-dnf >= %{dnf_lowest_compatible} Requires: python3-hawkey >= %{hawkey_version} Requires: python3-dateutil diff --git a/doc/needs_restarting.rst b/doc/needs_restarting.rst index e79b43f..1a3fbbe 100644 --- a/doc/needs_restarting.rst +++ b/doc/needs_restarting.rst @@ -48,3 +48,6 @@ All general DNF options are accepted, see `Options` in :manpage:`dnf(8)` for det ``-r, --reboothint`` Only report whether a reboot is required (exit code 1) or not (exit code 0). + +``-s, --services`` + Only list the affected systemd services. diff --git a/plugins/needs_restarting.py b/plugins/needs_restarting.py index 69203f4..f6bf525 100644 --- a/plugins/needs_restarting.py +++ b/plugins/needs_restarting.py @@ -29,6 +29,7 @@ from dnfpluginscore import logger, _ import dnf import dnf.cli +import dbus import functools import os import re @@ -126,6 +127,30 @@ def print_cmd(pid): print('%d : %s' % (pid, command)) +def get_service_dbus(pid): + bus = dbus.SystemBus() + systemd_manager_object = bus.get_object( + 'org.freedesktop.systemd1', + '/org/freedesktop/systemd1' + ) + systemd_manager_interface = dbus.Interface( + systemd_manager_object, + 'org.freedesktop.systemd1.Manager' + ) + service_proxy = bus.get_object( + 'org.freedesktop.systemd1', + systemd_manager_interface.GetUnitByPID(pid) + ) + service_properties = dbus.Interface( + service_proxy, dbus_interface="org.freedesktop.DBus.Properties") + name = service_properties.Get( + "org.freedesktop.systemd1.Unit", + 'Id' + ) + if name.endswith(".service"): + return name + return + def smap2opened_file(pid, line): slash = line.find('/') if slash < 0: @@ -205,6 +230,8 @@ class NeedsRestartingCommand(dnf.cli.Command): parser.add_argument('-r', '--reboothint', action='store_true', help=_("only report whether a reboot is required " "(exit code 1) or not (exit code 0)")) + parser.add_argument('-s', '--services', action='store_true', + help=_("only report affected systemd services")) def configure(self): demands = self.cli.demands @@ -251,5 +278,11 @@ class NeedsRestartingCommand(dnf.cli.Command): if pkg.installtime > process_start(ofile.pid): stale_pids.add(ofile.pid) + if self.opts.services: + names = set([get_service_dbus(pid) for pid in sorted(stale_pids)]) + for name in names: + if name is not None: + print(name) + return 0 for pid in sorted(stale_pids): print_cmd(pid)