Files
supervisor/supervisor/dbus/network/interface.py
Stefan Agner 7a6663ba80 Use Python dbus-next D-Bus library (#3234)
* Use the correct interface name to get properties of systemd

It seems that gdbus (or systemd) automatically pick the correct
interface and return the properties. However, dbussy requires the
correct interface name to get all properties.

* Don't expect array from Strength property

The property returns a type "y" which equates to "guchar":
https://developer-old.gnome.org/NetworkManager/stable/gdbus-org.freedesktop.NetworkManager.AccessPoint.html#gdbus-property-org-freedesktop-NetworkManager-AccessPoint.Strength

It seems that the old D-Bus implementation returned an array. With
dbus-next a integer is returned, so no list indexing required.

* Support signals and remove no longer used tests and code

* Pass rauc update file path as string

That is what the interface is expecting, otherwise the new lib chocks on
the Pathlib type.

* Support Network configuration with dbus-next

Assemble Python native objects and pass them to dbus-next. Use dbus-next
specific Variant class where necessary.

* Use org.freedesktop.NetworkManager.Connection.Active.StateChanged

org.freedesktop.NetworkManager.Connection.Active.PropertyChanged is
depricated. Also it seems that StateChanged leads to fewer and more
accurate signals.

* Pass correct data type to RequestScan.

RequestScan expects an option dictionary. Pass an empty option
dictionary to it.

* Update unit tests

Replace gdbus specific fixtures with json files representing the return
values. Those can be easily converted into native Python objects.

* Rename D-Bus utils module gdbus to dbus
2021-10-18 23:06:44 +02:00

97 lines
3.0 KiB
Python

"""NetworkInterface object for Network Manager."""
from typing import Optional
from ...utils.dbus import DBus
from ..const import (
DBUS_ATTR_ACTIVE_CONNECTION,
DBUS_ATTR_DEVICE_INTERFACE,
DBUS_ATTR_DEVICE_TYPE,
DBUS_ATTR_DRIVER,
DBUS_ATTR_MANAGED,
DBUS_NAME_DEVICE,
DBUS_NAME_NM,
DBUS_OBJECT_BASE,
DeviceType,
)
from ..interface import DBusInterfaceProxy
from .connection import NetworkConnection
from .setting import NetworkSetting
from .wireless import NetworkWireless
class NetworkInterface(DBusInterfaceProxy):
"""NetworkInterface object for Network Manager."""
def __init__(self, nm_dbus: DBus, object_path: str) -> None:
"""Initialize NetworkConnection object."""
self.object_path = object_path
self.properties = {}
self.primary = False
self._connection: Optional[NetworkConnection] = None
self._settings: Optional[NetworkSetting] = None
self._wireless: Optional[NetworkWireless] = None
self._nm_dbus: DBus = nm_dbus
@property
def name(self) -> str:
"""Return interface name."""
return self.properties[DBUS_ATTR_DEVICE_INTERFACE]
@property
def type(self) -> int:
"""Return interface type."""
return self.properties[DBUS_ATTR_DEVICE_TYPE]
@property
def driver(self) -> str:
"""Return interface driver."""
return self.properties[DBUS_ATTR_DRIVER]
@property
def managed(self) -> bool:
"""Return interface driver."""
return self.properties[DBUS_ATTR_MANAGED]
@property
def connection(self) -> Optional[NetworkConnection]:
"""Return the connection used for this interface."""
return self._connection
@property
def settings(self) -> Optional[NetworkSetting]:
"""Return the connection settings used for this interface."""
return self._settings
@property
def wireless(self) -> Optional[NetworkWireless]:
"""Return the wireless data for this interface."""
return self._wireless
async def connect(self) -> None:
"""Get device information."""
self.dbus = await DBus.connect(DBUS_NAME_NM, self.object_path)
self.properties = await self.dbus.get_properties(DBUS_NAME_DEVICE)
# Abort if device is not managed
if not self.managed:
return
# If connection exists
if self.properties[DBUS_ATTR_ACTIVE_CONNECTION] != DBUS_OBJECT_BASE:
self._connection = NetworkConnection(
self.properties[DBUS_ATTR_ACTIVE_CONNECTION]
)
await self._connection.connect()
# Attach settings
if self.connection and self.connection.setting_object != DBUS_OBJECT_BASE:
self._settings = NetworkSetting(self.connection.setting_object)
await self._settings.connect()
# Wireless
if self.type == DeviceType.WIRELESS:
self._wireless = NetworkWireless(self.object_path)
await self._wireless.connect()