Получить «состояние» из dbus с помощью python

Я хочу сделать на питоне очень простую вещь — прочитать состояние из firewalld через dbus — «org.freedesktop.DBus.Properties».

Согласно https://firewalld.org/documentation/man-pages/firewalld.dbus.html

state - s - (ro)
firewalld state. This can be either INIT or RUNNING. In INIT state, firewalld is starting up and initializing.

Я нашел, как это сделать с помощью dbus-send из Linux, но я просто не могу сделать это правильно в python.

Вот самый близкий ответ SO на мой вопрос, но я до сих пор не могу понять. [dbus_to_python() принимает ровно 1 аргумент?

Here's how to do it in shell:
firewall-cmd --state
running 

And with dbus-send:
dbus-send --system --print-reply --dest=org.fedoraproject.FirewallD1 /org/fedoraproject/FirewallD1 org.freedesktop.DBus.Properties.Get string:"org.fedoraproject.FirewallD1" string:"state"
method return time=1563593597.133270 sender=:1.2 -> destination=:1.116 serial=691 reply_serial=2
   variant       string "RUNNING"
# Here's my incorrect code:
import dbus
Bus = dbus.SystemBus()
Proxy = Bus.get_object('org.fedoraproject.FirewallD1', '/org/fedoraproject/FirewallD1')
Proxy.Get('state', dbus_interface='org.freedesktop.DBus.Properties')

И вот сообщение об ошибке, которое я получаю от python:

ERROR:dbus.connection:Unable to set arguments ('state',) according to signature 'ss': <class 'TypeError'>: More items found in D-Bus signature than in Python arguments
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3/dist-packages/dbus/proxies.py", line 70, in __call__
    return self._proxy_method(*args, **keywords)
  File "/usr/lib/python3/dist-packages/dbus/proxies.py", line 145, in __call__
    **keywords)
  File "/usr/lib/python3/dist-packages/dbus/connection.py", line 641, in call_blocking
    message.append(signature=signature, *args)
TypeError: More items found in D-Bus signature than in Python arguments
>>> 


person Kenneth A    schedule 20.07.2019    source источник
comment
Вот решение:   -  person Kenneth A    schedule 20.07.2019


Ответы (2)


Проблема в том, что метод Get интерфейса org.freedesktop.DBus.Properties фактически принимает два аргумента: интерфейс для доступа к свойству и имя этого свойства:

org.freedesktop.DBus.Properties.Get (in STRING interface_name,
                                     in STRING property_name,
                                     out VARIANT value);

Из https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties

import dbus
Bus = dbus.SystemBus()
Proxy = Bus.get_object('org.fedoraproject.FirewallD1', '/org/fedoraproject/FirewallD1')
Proxy.Get('org.fedoraproject.FirewallD1', 'state', dbus_interface='org.freedesktop.DBus.Properties')

Протестировано с разными константами, поскольку у меня нет этой конкретной службы или объекта DBus.

person Dan D.    schedule 20.07.2019
comment
Спасибо за это. В конце концов я понял это и отправил ответ точно в то же время, когда вы опубликовали свой ответ. - person Kenneth A; 20.07.2019

Вот решение:

Proxy.Get('org.fedoraproject.FirewallD1', 'state', dbus_interface='org.freedesktop.DBus.Properties')
person Kenneth A    schedule 20.07.2019