Как получить служебную информацию systemd внутри функции обратного вызова dbus - PullRequest
0 голосов
/ 11 марта 2020

У меня есть следующий python скрипт для отслеживания сигнала «PropertiesChanged» от всех служб systemd.

#!/usr/bin/env python

import sys
import dbus
import traceback
import dbus.mainloop.glib
from gi.repository import GLib

def catchall_signal_handler(*args, **kwargs):
    bus = dbus.SystemBus()
    if args:
        print(args[0])
        print(args[1])
    if kwargs:
        print(kwargs["path"])
        #systemd = bus.get_object('org.freedesktop.systemd1', kwargs["path"])
        #manager = dbus.Interface(systemd, dbus_interface='org.freedesktop.systemd1.Manager')


if __name__ == '__main__':
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

    bus = dbus.SystemBus()
    try:
        systemd_proxy_obj = bus.get_object("org.freedesktop.systemd1", "/org/freedesktop/systemd1")

    except dbus.DBusException:
        traceback.print_exc()
        print(usage)
        sys.exit(1)

    bus.add_signal_receiver(catchall_signal_handler,  \
            dbus_interface="org.freedesktop.DBus.Properties", signal_name="PropertiesChanged",\
                        sender_keyword='sender', \
                        path_keyword='path', \
                        interface_keyword='interface')

    loop = GLib.MainLoop()
    loop.run()

Я могу получить информацию, как показано ниже.

org.freedesktop.systemd1.Unit

dbus.Dictionary({dbus.String('ActiveState'): dbus.String('activating', variant_level=1), dbus.String('SubState'): dbus.String('auto-restart', variant_level=1), dbus.String('StateChangeTimestamp'): dbus.UInt64(1583953715755499, variant_level=1), dbus.String('StateChangeTimestampMonotonic'): dbus.UInt64(207876008581, variant_level=1), dbus.String('InactiveExitTimestamp'): dbus.UInt64(1583953715755499, variant_level=1), dbus.String('InactiveExitTimestampMonotonic'): dbus.UInt64(207876008581, variant_level=1), dbus.String('ActiveEnterTimestamp'): dbus.UInt64(1583953704417956, variant_level=1), dbus.String('ActiveEnterTimestampMonotonic'): dbus.UInt64(207864671038, variant_level=1), dbus.String('ActiveExitTimestamp'): dbus.UInt64(1583953715754514, variant_level=1), dbus.String('ActiveExitTimestampMonotonic'): dbus.UInt64(207876007596, variant_level=1), dbus.String('InactiveEnterTimestamp'): dbus.UInt64(1583953715754514, variant_level=1), dbus.String('InactiveEnterTimestampMonotonic'): dbus.UInt64(207876007596, variant_level=1), dbus.String('Job'): dbus.Struct((dbus.UInt32(0), dbus.ObjectPath('/')), signature=None, variant_level=1), dbus.String('ConditionResult'): dbus.Boolean(True, variant_level=1), dbus.String('AssertResult'): dbus.Boolean(True, variant_level=1), dbus.String('ConditionTimestamp'): dbus.UInt64(1583953704415513, variant_level=1), dbus.String('ConditionTimestampMonotonic'): dbus.UInt64(207864668599, variant_level=1), dbus.String('AssertTimestamp'): dbus.UInt64(1583953704415517, variant_level=1), dbus.String('AssertTimestampMonotonic'): dbus.UInt64(207864668600, variant_level=1), dbus.String('InvocationID'): dbus.Array([dbus.Byte(134), dbus.Byte(157), dbus.Byte(36), dbus.Byte(192), dbus.Byte(223), dbus.Byte(108), dbus.Byte(77), dbus.Byte(86), dbus.Byte(174), dbus.Byte(132), dbus.Byte(254), dbus.Byte(35), dbus.Byte(71), dbus.Byte(91), dbus.Byte(246), dbus.Byte(215)], signature=dbus.Signature('y'), variant_level=1)}, signature=dbus.Signature('sv'))

/org/freedesktop/systemd1/unit/tftp_2eservice

Внутри функции catchall_signal_handler () теперь я хочу получить имя службы, т.е. (tftp.service)

Как правильно получить эту информацию?

Я новичок в программировании на dbus API.

Пробовал этот ( Как извлечь состояние сервиса через Systemd DBus API? ), но не помогло. Пожалуйста, предоставьте несколько полезных советов / указателей.

Моя конечная цель - отслеживать набор предопределенных услуг. Пример: ["tftp.service", "docker .service", "kubernetes.service"]

Является ли вышеуказанный подход правильным способом сделать это? Пожалуйста, предложите.

1 Ответ

0 голосов
/ 13 марта 2020

Используя приведенные ниже вызовы API, я смог получить имя службы.

def catchall_signal_handler(*args, **kwargs):
    bus = dbus.SystemBus()
    if args:
        print(args[0])
        print(args[1])
    if kwargs:
        print(kwargs["path"])
        service_proxy = bus.get_object('org.freedesktop.systemd1', kwargs["path"])
        service_properties = dbus.Interface(service_proxy, dbus_interface="org.freedesktop.DBus.Properties") 
        name = service_properties.Get("org.freedesktop.systemd1.Unit", 'Id')
        print(name)
...