Share MessageBus across dbus objects (#3860)

* Share MessageBus across dbus objects

* Fix connect calls in tests
This commit is contained in:
Mike Degatano 2022-09-12 14:10:12 -04:00 committed by GitHub
parent 4f272ad4fd
commit b71c6c60da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 222 additions and 136 deletions

View File

@ -298,6 +298,7 @@ class Core(CoreSysAttributes):
self.sys_websession.close(), self.sys_websession.close(),
self.sys_ingress.unload(), self.sys_ingress.unload(),
self.sys_hardware.unload(), self.sys_hardware.unload(),
self.sys_dbus.unload(),
] ]
) )
except asyncio.TimeoutError: except asyncio.TimeoutError:

View File

@ -4,6 +4,7 @@ import logging
from typing import Any from typing import Any
from awesomeversion import AwesomeVersion from awesomeversion import AwesomeVersion
from dbus_next.aio.message_bus import MessageBus
from ...exceptions import DBusError, DBusInterfaceError from ...exceptions import DBusError, DBusInterfaceError
from ...utils.dbus import DBus from ...utils.dbus import DBus
@ -78,14 +79,14 @@ class OSAgent(DBusInterface):
self.dbus.set_property(DBUS_IFACE_HAOS, DBUS_ATTR_DIAGNOSTICS, value) self.dbus.set_property(DBUS_IFACE_HAOS, DBUS_ATTR_DIAGNOSTICS, value)
) )
async def connect(self) -> None: async def connect(self, bus: MessageBus) -> None:
"""Connect to system's D-Bus.""" """Connect to system's D-Bus."""
try: try:
self.dbus = await DBus.connect(DBUS_NAME_HAOS, DBUS_OBJECT_HAOS) self.dbus = await DBus.connect(bus, DBUS_NAME_HAOS, DBUS_OBJECT_HAOS)
await self.cgroup.connect() await self.cgroup.connect(bus)
await self.apparmor.connect() await self.apparmor.connect(bus)
await self.system.connect() await self.system.connect(bus)
await self.datadisk.connect() await self.datadisk.connect(bus)
except DBusError: except DBusError:
_LOGGER.warning("Can't connect to OS-Agent") _LOGGER.warning("Can't connect to OS-Agent")
except DBusInterfaceError: except DBusInterfaceError:

View File

@ -3,6 +3,7 @@ from pathlib import Path
from typing import Any from typing import Any
from awesomeversion import AwesomeVersion from awesomeversion import AwesomeVersion
from dbus_next.aio.message_bus import MessageBus
from ...utils.dbus import DBus from ...utils.dbus import DBus
from ..const import ( from ..const import (
@ -28,9 +29,9 @@ class AppArmor(DBusInterface):
"""Return version of host AppArmor parser.""" """Return version of host AppArmor parser."""
return AwesomeVersion(self.properties[DBUS_ATTR_PARSER_VERSION]) return AwesomeVersion(self.properties[DBUS_ATTR_PARSER_VERSION])
async def connect(self) -> None: async def connect(self, bus: MessageBus) -> None:
"""Get connection information.""" """Get connection information."""
self.dbus = await DBus.connect(DBUS_NAME_HAOS, DBUS_OBJECT_HAOS_APPARMOR) self.dbus = await DBus.connect(bus, DBUS_NAME_HAOS, DBUS_OBJECT_HAOS_APPARMOR)
@dbus_connected @dbus_connected
async def update(self): async def update(self):

View File

@ -1,5 +1,7 @@
"""CGroup object for OS-Agent.""" """CGroup object for OS-Agent."""
from dbus_next.aio.message_bus import MessageBus
from ...utils.dbus import DBus from ...utils.dbus import DBus
from ..const import DBUS_NAME_HAOS, DBUS_OBJECT_HAOS_CGROUP from ..const import DBUS_NAME_HAOS, DBUS_OBJECT_HAOS_CGROUP
from ..interface import DBusInterface from ..interface import DBusInterface
@ -9,9 +11,9 @@ from ..utils import dbus_connected
class CGroup(DBusInterface): class CGroup(DBusInterface):
"""CGroup object for OS Agent.""" """CGroup object for OS Agent."""
async def connect(self) -> None: async def connect(self, bus: MessageBus) -> None:
"""Get connection information.""" """Get connection information."""
self.dbus = await DBus.connect(DBUS_NAME_HAOS, DBUS_OBJECT_HAOS_CGROUP) self.dbus = await DBus.connect(bus, DBUS_NAME_HAOS, DBUS_OBJECT_HAOS_CGROUP)
@dbus_connected @dbus_connected
async def add_devices_allowed(self, container_id: str, permission: str) -> None: async def add_devices_allowed(self, container_id: str, permission: str) -> None:

View File

@ -2,6 +2,8 @@
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
from dbus_next.aio.message_bus import MessageBus
from ...utils.dbus import DBus from ...utils.dbus import DBus
from ..const import ( from ..const import (
DBUS_ATTR_CURRENT_DEVICE, DBUS_ATTR_CURRENT_DEVICE,
@ -26,9 +28,9 @@ class DataDisk(DBusInterface):
"""Return current device used for data.""" """Return current device used for data."""
return Path(self.properties[DBUS_ATTR_CURRENT_DEVICE]) return Path(self.properties[DBUS_ATTR_CURRENT_DEVICE])
async def connect(self) -> None: async def connect(self, bus: MessageBus) -> None:
"""Get connection information.""" """Get connection information."""
self.dbus = await DBus.connect(DBUS_NAME_HAOS, DBUS_OBJECT_HAOS_DATADISK) self.dbus = await DBus.connect(bus, DBUS_NAME_HAOS, DBUS_OBJECT_HAOS_DATADISK)
@dbus_connected @dbus_connected
async def update(self): async def update(self):

View File

@ -1,5 +1,7 @@
"""System object for OS-Agent.""" """System object for OS-Agent."""
from dbus_next.aio.message_bus import MessageBus
from ...utils.dbus import DBus from ...utils.dbus import DBus
from ..const import DBUS_NAME_HAOS, DBUS_OBJECT_HAOS_SYSTEM from ..const import DBUS_NAME_HAOS, DBUS_OBJECT_HAOS_SYSTEM
from ..interface import DBusInterface from ..interface import DBusInterface
@ -9,9 +11,9 @@ from ..utils import dbus_connected
class System(DBusInterface): class System(DBusInterface):
"""System object for OS Agent.""" """System object for OS Agent."""
async def connect(self) -> None: async def connect(self, bus: MessageBus) -> None:
"""Get connection information.""" """Get connection information."""
self.dbus = await DBus.connect(DBUS_NAME_HAOS, DBUS_OBJECT_HAOS_SYSTEM) self.dbus = await DBus.connect(bus, DBUS_NAME_HAOS, DBUS_OBJECT_HAOS_SYSTEM)
@dbus_connected @dbus_connected
async def schedule_wipe_device(self) -> None: async def schedule_wipe_device(self) -> None:

View File

@ -2,6 +2,8 @@
import logging import logging
from typing import Any from typing import Any
from dbus_next.aio.message_bus import MessageBus
from ..exceptions import DBusError, DBusInterfaceError from ..exceptions import DBusError, DBusInterfaceError
from ..utils.dbus import DBus from ..utils.dbus import DBus
from .const import ( from .const import (
@ -33,10 +35,12 @@ class Hostname(DBusInterface):
"""Initialize Properties.""" """Initialize Properties."""
self.properties: dict[str, Any] = {} self.properties: dict[str, Any] = {}
async def connect(self): async def connect(self, bus: MessageBus):
"""Connect to system's D-Bus.""" """Connect to system's D-Bus."""
try: try:
self.dbus = await DBus.connect(DBUS_NAME_HOSTNAME, DBUS_OBJECT_HOSTNAME) self.dbus = await DBus.connect(
bus, DBUS_NAME_HOSTNAME, DBUS_OBJECT_HOSTNAME
)
except DBusError: except DBusError:
_LOGGER.warning("Can't connect to systemd-hostname") _LOGGER.warning("Can't connect to systemd-hostname")
except DBusInterfaceError: except DBusInterfaceError:

View File

@ -3,6 +3,8 @@ from abc import ABC, abstractmethod
from functools import wraps from functools import wraps
from typing import Any from typing import Any
from dbus_next.aio.message_bus import MessageBus
from ..utils.dbus import DBus from ..utils.dbus import DBus
@ -31,7 +33,7 @@ class DBusInterface(ABC):
return self.dbus is not None return self.dbus is not None
@abstractmethod @abstractmethod
async def connect(self): async def connect(self, bus: MessageBus):
"""Connect to D-Bus.""" """Connect to D-Bus."""
def disconnect(self): def disconnect(self):
@ -47,5 +49,5 @@ class DBusInterfaceProxy(ABC):
properties: dict[str, Any] | None = None properties: dict[str, Any] | None = None
@abstractmethod @abstractmethod
async def connect(self): async def connect(self, bus: MessageBus):
"""Connect to D-Bus.""" """Connect to D-Bus."""

View File

@ -1,6 +1,8 @@
"""Interface to Logind over D-Bus.""" """Interface to Logind over D-Bus."""
import logging import logging
from dbus_next.aio.message_bus import MessageBus
from ..exceptions import DBusError, DBusInterfaceError from ..exceptions import DBusError, DBusInterfaceError
from ..utils.dbus import DBus from ..utils.dbus import DBus
from .const import DBUS_NAME_LOGIND, DBUS_OBJECT_LOGIND from .const import DBUS_NAME_LOGIND, DBUS_OBJECT_LOGIND
@ -18,10 +20,10 @@ class Logind(DBusInterface):
name = DBUS_NAME_LOGIND name = DBUS_NAME_LOGIND
async def connect(self): async def connect(self, bus: MessageBus):
"""Connect to D-Bus.""" """Connect to D-Bus."""
try: try:
self.dbus = await DBus.connect(DBUS_NAME_LOGIND, DBUS_OBJECT_LOGIND) self.dbus = await DBus.connect(bus, DBUS_NAME_LOGIND, DBUS_OBJECT_LOGIND)
except DBusError: except DBusError:
_LOGGER.warning("Can't connect to systemd-logind") _LOGGER.warning("Can't connect to systemd-logind")
except DBusInterfaceError: except DBusInterfaceError:

View File

@ -1,8 +1,12 @@
"""D-Bus interface objects.""" """D-Bus interface objects."""
import logging import logging
from dbus_next import BusType
from dbus_next.aio.message_bus import MessageBus
from ..const import SOCKET_DBUS from ..const import SOCKET_DBUS
from ..coresys import CoreSys, CoreSysAttributes from ..coresys import CoreSys, CoreSysAttributes
from ..exceptions import DBusFatalError
from .agent import OSAgent from .agent import OSAgent
from .hostname import Hostname from .hostname import Hostname
from .interface import DBusInterface from .interface import DBusInterface
@ -31,6 +35,7 @@ class DBusManager(CoreSysAttributes):
self._agent: OSAgent = OSAgent() self._agent: OSAgent = OSAgent()
self._timedate: TimeDate = TimeDate() self._timedate: TimeDate = TimeDate()
self._resolved: Resolved = Resolved() self._resolved: Resolved = Resolved()
self._bus: MessageBus | None = None
@property @property
def systemd(self) -> Systemd: def systemd(self) -> Systemd:
@ -72,6 +77,11 @@ class DBusManager(CoreSysAttributes):
"""Return the resolved interface.""" """Return the resolved interface."""
return self._resolved return self._resolved
@property
def bus(self) -> MessageBus | None:
"""Return the message bus."""
return self._bus
async def load(self) -> None: async def load(self) -> None:
"""Connect interfaces to D-Bus.""" """Connect interfaces to D-Bus."""
if not SOCKET_DBUS.exists(): if not SOCKET_DBUS.exists():
@ -80,6 +90,15 @@ class DBusManager(CoreSysAttributes):
) )
return return
try:
self._bus = await MessageBus(bus_type=BusType.SYSTEM).connect()
except Exception as err:
raise DBusFatalError(
"Cannot connect to system D-Bus. Disabled any kind of host control!"
) from err
_LOGGER.info("Connected to system D-Bus.")
dbus_loads: list[DBusInterface] = [ dbus_loads: list[DBusInterface] = [
self.agent, self.agent,
self.systemd, self.systemd,
@ -93,8 +112,13 @@ class DBusManager(CoreSysAttributes):
for dbus in dbus_loads: for dbus in dbus_loads:
_LOGGER.info("Load dbus interface %s", dbus.name) _LOGGER.info("Load dbus interface %s", dbus.name)
try: try:
await dbus.connect() await dbus.connect(self._bus)
except Exception as err: # pylint: disable=broad-except except Exception as err: # pylint: disable=broad-except
_LOGGER.warning("Can't load dbus interface %s: %s", dbus.name, err) _LOGGER.warning("Can't load dbus interface %s: %s", dbus.name, err)
self.sys_host.supported_features.cache_clear() self.sys_host.supported_features.cache_clear()
async def unload(self) -> None:
"""Close connection to D-Bus."""
self._bus.disconnect()
_LOGGER.info("Closed conection to system D-Bus.")

View File

@ -4,6 +4,7 @@ import logging
from typing import Any from typing import Any
from awesomeversion import AwesomeVersion, AwesomeVersionException from awesomeversion import AwesomeVersion, AwesomeVersionException
from dbus_next.aio.message_bus import MessageBus
import sentry_sdk import sentry_sdk
from ...exceptions import ( from ...exceptions import (
@ -92,7 +93,7 @@ class NetworkManager(DBusInterface):
) )
obj_active_con = result[0] obj_active_con = result[0]
active_con = NetworkConnection(obj_active_con) active_con = NetworkConnection(obj_active_con)
await active_con.connect() await active_con.connect(self.dbus.bus)
return active_con return active_con
@dbus_connected @dbus_connected
@ -106,7 +107,9 @@ class NetworkManager(DBusInterface):
con_setting = NetworkSetting(obj_con_setting) con_setting = NetworkSetting(obj_con_setting)
active_con = NetworkConnection(obj_active_con) active_con = NetworkConnection(obj_active_con)
await asyncio.gather(con_setting.connect(), active_con.connect()) await asyncio.gather(
con_setting.connect(self.dbus.bus), active_con.connect(self.dbus.bus)
)
return con_setting, active_con return con_setting, active_con
@dbus_connected @dbus_connected
@ -117,12 +120,12 @@ class NetworkManager(DBusInterface):
else: else:
return await self.dbus.get_property(DBUS_IFACE_NM, DBUS_ATTR_CONNECTIVITY) return await self.dbus.get_property(DBUS_IFACE_NM, DBUS_ATTR_CONNECTIVITY)
async def connect(self) -> None: async def connect(self, bus: MessageBus) -> None:
"""Connect to system's D-Bus.""" """Connect to system's D-Bus."""
try: try:
self.dbus = await DBus.connect(DBUS_NAME_NM, DBUS_OBJECT_NM) self.dbus = await DBus.connect(bus, DBUS_NAME_NM, DBUS_OBJECT_NM)
await self.dns.connect() await self.dns.connect(bus)
await self.settings.connect() await self.settings.connect(bus)
except DBusError: except DBusError:
_LOGGER.warning("Can't connect to Network Manager") _LOGGER.warning("Can't connect to Network Manager")
except DBusInterfaceError: except DBusInterfaceError:
@ -167,7 +170,7 @@ class NetworkManager(DBusInterface):
# Connect to interface # Connect to interface
try: try:
await interface.connect() await interface.connect(self.dbus.bus)
except (DBusFatalError, DBusInterfaceMethodError) as err: except (DBusFatalError, DBusInterfaceMethodError) as err:
# Docker creates and deletes interfaces quite often, sometimes # Docker creates and deletes interfaces quite often, sometimes
# this causes a race condition: A device disappears while we # this causes a race condition: A device disappears while we

View File

@ -1,5 +1,7 @@
"""Connection object for Network Manager.""" """Connection object for Network Manager."""
from dbus_next.aio.message_bus import MessageBus
from ...utils.dbus import DBus from ...utils.dbus import DBus
from ..const import ( from ..const import (
DBUS_ATTR_FREQUENCY, DBUS_ATTR_FREQUENCY,
@ -54,7 +56,7 @@ class NetworkWirelessAP(DBusInterfaceProxy):
"""Return details about mac address.""" """Return details about mac address."""
return int(self.properties[DBUS_ATTR_STRENGTH]) return int(self.properties[DBUS_ATTR_STRENGTH])
async def connect(self) -> None: async def connect(self, bus: MessageBus) -> None:
"""Get connection information.""" """Get connection information."""
self.dbus = await DBus.connect(DBUS_NAME_NM, self.object_path) self.dbus = await DBus.connect(bus, DBUS_NAME_NM, self.object_path)
self.properties = await self.dbus.get_properties(DBUS_IFACE_ACCESSPOINT) self.properties = await self.dbus.get_properties(DBUS_IFACE_ACCESSPOINT)

View File

@ -1,6 +1,8 @@
"""Connection object for Network Manager.""" """Connection object for Network Manager."""
from ipaddress import ip_address, ip_interface from ipaddress import ip_address, ip_interface
from dbus_next.aio.message_bus import MessageBus
from ...const import ATTR_ADDRESS, ATTR_PREFIX from ...const import ATTR_ADDRESS, ATTR_PREFIX
from ...utils.dbus import DBus from ...utils.dbus import DBus
from ..const import ( from ..const import (
@ -89,9 +91,9 @@ class NetworkConnection(DBusInterfaceProxy):
"""Return a ip6 configuration object for the connection.""" """Return a ip6 configuration object for the connection."""
return self._ipv6 return self._ipv6
async def connect(self) -> None: async def connect(self, bus: MessageBus) -> None:
"""Get connection information.""" """Get connection information."""
self.dbus = await DBus.connect(DBUS_NAME_NM, self.object_path) self.dbus = await DBus.connect(bus, DBUS_NAME_NM, self.object_path)
await self.update() await self.update()
@dbus_connected @dbus_connected
@ -108,7 +110,9 @@ class NetworkConnection(DBusInterfaceProxy):
# IPv4 # IPv4
if self.properties[DBUS_ATTR_IP4CONFIG] != DBUS_OBJECT_BASE: if self.properties[DBUS_ATTR_IP4CONFIG] != DBUS_OBJECT_BASE:
ip4 = await DBus.connect(DBUS_NAME_NM, self.properties[DBUS_ATTR_IP4CONFIG]) ip4 = await DBus.connect(
self.dbus.bus, DBUS_NAME_NM, self.properties[DBUS_ATTR_IP4CONFIG]
)
ip4_data = await ip4.get_properties(DBUS_IFACE_IP4CONFIG) ip4_data = await ip4.get_properties(DBUS_IFACE_IP4CONFIG)
self._ipv4 = IpConfiguration( self._ipv4 = IpConfiguration(
@ -127,7 +131,9 @@ class NetworkConnection(DBusInterfaceProxy):
# IPv6 # IPv6
if self.properties[DBUS_ATTR_IP6CONFIG] != DBUS_OBJECT_BASE: if self.properties[DBUS_ATTR_IP6CONFIG] != DBUS_OBJECT_BASE:
ip6 = await DBus.connect(DBUS_NAME_NM, self.properties[DBUS_ATTR_IP6CONFIG]) ip6 = await DBus.connect(
self.dbus.bus, DBUS_NAME_NM, self.properties[DBUS_ATTR_IP6CONFIG]
)
ip6_data = await ip6.get_properties(DBUS_IFACE_IP6CONFIG) ip6_data = await ip6.get_properties(DBUS_IFACE_IP6CONFIG)
self._ipv6 = IpConfiguration( self._ipv6 = IpConfiguration(

View File

@ -2,6 +2,8 @@
from ipaddress import ip_address from ipaddress import ip_address
import logging import logging
from dbus_next.aio.message_bus import MessageBus
from ...const import ( from ...const import (
ATTR_DOMAINS, ATTR_DOMAINS,
ATTR_INTERFACE, ATTR_INTERFACE,
@ -53,10 +55,10 @@ class NetworkManagerDNS(DBusInterface):
"""Return Propertie configuraton.""" """Return Propertie configuraton."""
return self._configuration return self._configuration
async def connect(self) -> None: async def connect(self, bus: MessageBus) -> None:
"""Connect to system's D-Bus.""" """Connect to system's D-Bus."""
try: try:
self.dbus = await DBus.connect(DBUS_NAME_NM, DBUS_OBJECT_DNS) self.dbus = await DBus.connect(bus, DBUS_NAME_NM, DBUS_OBJECT_DNS)
except DBusError: except DBusError:
_LOGGER.warning("Can't connect to DnsManager") _LOGGER.warning("Can't connect to DnsManager")
except DBusInterfaceError: except DBusInterfaceError:

View File

@ -1,4 +1,7 @@
"""NetworkInterface object for Network Manager.""" """NetworkInterface object for Network Manager."""
from dbus_next.aio.message_bus import MessageBus
from ...utils.dbus import DBus from ...utils.dbus import DBus
from ..const import ( from ..const import (
DBUS_ATTR_ACTIVE_CONNECTION, DBUS_ATTR_ACTIVE_CONNECTION,
@ -74,9 +77,9 @@ class NetworkInterface(DBusInterfaceProxy):
"""Return the wireless data for this interface.""" """Return the wireless data for this interface."""
return self._wireless return self._wireless
async def connect(self) -> None: async def connect(self, bus: MessageBus) -> None:
"""Get device information.""" """Get device information."""
self.dbus = await DBus.connect(DBUS_NAME_NM, self.object_path) self.dbus = await DBus.connect(bus, DBUS_NAME_NM, self.object_path)
self.properties = await self.dbus.get_properties(DBUS_IFACE_DEVICE) self.properties = await self.dbus.get_properties(DBUS_IFACE_DEVICE)
# Abort if device is not managed # Abort if device is not managed
@ -88,14 +91,14 @@ class NetworkInterface(DBusInterfaceProxy):
self._connection = NetworkConnection( self._connection = NetworkConnection(
self.properties[DBUS_ATTR_ACTIVE_CONNECTION] self.properties[DBUS_ATTR_ACTIVE_CONNECTION]
) )
await self._connection.connect() await self._connection.connect(bus)
# Attach settings # Attach settings
if self.connection and self.connection.setting_object != DBUS_OBJECT_BASE: if self.connection and self.connection.setting_object != DBUS_OBJECT_BASE:
self._settings = NetworkSetting(self.connection.setting_object) self._settings = NetworkSetting(self.connection.setting_object)
await self._settings.connect() await self._settings.connect(bus)
# Wireless # Wireless
if self.type == DeviceType.WIRELESS: if self.type == DeviceType.WIRELESS:
self._wireless = NetworkWireless(self.object_path) self._wireless = NetworkWireless(self.object_path)
await self._wireless.connect() await self._wireless.connect(bus)

View File

@ -2,6 +2,8 @@
import logging import logging
from typing import Any from typing import Any
from dbus_next.aio.message_bus import MessageBus
from ....const import ATTR_METHOD, ATTR_MODE, ATTR_PSK, ATTR_SSID from ....const import ATTR_METHOD, ATTR_MODE, ATTR_PSK, ATTR_SSID
from ....utils.dbus import DBus from ....utils.dbus import DBus
from ...const import DBUS_NAME_NM from ...const import DBUS_NAME_NM
@ -158,9 +160,9 @@ class NetworkSetting(DBusInterfaceProxy):
"""Delete connection settings.""" """Delete connection settings."""
await self.dbus.Settings.Connection.Delete() await self.dbus.Settings.Connection.Delete()
async def connect(self) -> None: async def connect(self, bus: MessageBus) -> None:
"""Get connection information.""" """Get connection information."""
self.dbus = await DBus.connect(DBUS_NAME_NM, self.object_path) self.dbus = await DBus.connect(bus, DBUS_NAME_NM, self.object_path)
data = await self.get_settings() data = await self.get_settings()
# Get configuration settings we care about # Get configuration settings we care about

View File

@ -2,12 +2,13 @@
import logging import logging
from typing import Any from typing import Any
from supervisor.dbus.network.setting import NetworkSetting from dbus_next.aio.message_bus import MessageBus
from ...exceptions import DBusError, DBusInterfaceError from ...exceptions import DBusError, DBusInterfaceError
from ...utils.dbus import DBus from ...utils.dbus import DBus
from ..const import DBUS_NAME_NM, DBUS_OBJECT_SETTINGS from ..const import DBUS_NAME_NM, DBUS_OBJECT_SETTINGS
from ..interface import DBusInterface from ..interface import DBusInterface
from ..network.setting import NetworkSetting
from ..utils import dbus_connected from ..utils import dbus_connected
_LOGGER: logging.Logger = logging.getLogger(__name__) _LOGGER: logging.Logger = logging.getLogger(__name__)
@ -19,10 +20,10 @@ class NetworkManagerSettings(DBusInterface):
https://developer.gnome.org/NetworkManager/stable/gdbus-org.freedesktop.NetworkManager.Settings.html https://developer.gnome.org/NetworkManager/stable/gdbus-org.freedesktop.NetworkManager.Settings.html
""" """
async def connect(self) -> None: async def connect(self, bus: MessageBus) -> None:
"""Connect to system's D-Bus.""" """Connect to system's D-Bus."""
try: try:
self.dbus = await DBus.connect(DBUS_NAME_NM, DBUS_OBJECT_SETTINGS) self.dbus = await DBus.connect(bus, DBUS_NAME_NM, DBUS_OBJECT_SETTINGS)
except DBusError: except DBusError:
_LOGGER.warning("Can't connect to Network Manager Settings") _LOGGER.warning("Can't connect to Network Manager Settings")
except DBusInterfaceError: except DBusInterfaceError:
@ -37,7 +38,7 @@ class NetworkManagerSettings(DBusInterface):
await self.dbus.Settings.AddConnection(("a{sa{sv}}", settings)) await self.dbus.Settings.AddConnection(("a{sa{sv}}", settings))
)[0] )[0]
con_setting = NetworkSetting(obj_con_setting) con_setting = NetworkSetting(obj_con_setting)
await con_setting.connect() await con_setting.connect(self.dbus.bus)
return con_setting return con_setting
@dbus_connected @dbus_connected

View File

@ -2,6 +2,8 @@
import asyncio import asyncio
import logging import logging
from dbus_next.aio.message_bus import MessageBus
from ...utils.dbus import DBus from ...utils.dbus import DBus
from ..const import ( from ..const import (
DBUS_ATTR_ACTIVE_ACCESSPOINT, DBUS_ATTR_ACTIVE_ACCESSPOINT,
@ -46,16 +48,16 @@ class NetworkWireless(DBusInterfaceProxy):
accesspoints = [NetworkWirelessAP(ap_obj) for ap_obj in accesspoints_data] accesspoints = [NetworkWirelessAP(ap_obj) for ap_obj in accesspoints_data]
for err in await asyncio.gather( for err in await asyncio.gather(
*[ap.connect() for ap in accesspoints], return_exceptions=True *[ap.connect(self.dbus.bus) for ap in accesspoints], return_exceptions=True
): ):
if err: if err:
_LOGGER.warning("Can't process an AP: %s", err) _LOGGER.warning("Can't process an AP: %s", err)
return accesspoints return accesspoints
async def connect(self) -> None: async def connect(self, bus: MessageBus) -> None:
"""Get connection information.""" """Get connection information."""
self.dbus = await DBus.connect(DBUS_NAME_NM, self.object_path) self.dbus = await DBus.connect(bus, DBUS_NAME_NM, self.object_path)
self.properties = await self.dbus.get_properties(DBUS_IFACE_DEVICE_WIRELESS) self.properties = await self.dbus.get_properties(DBUS_IFACE_DEVICE_WIRELESS)
# Get details from current active # Get details from current active
@ -63,4 +65,4 @@ class NetworkWireless(DBusInterfaceProxy):
self._active = NetworkWirelessAP( self._active = NetworkWirelessAP(
self.properties[DBUS_ATTR_ACTIVE_ACCESSPOINT] self.properties[DBUS_ATTR_ACTIVE_ACCESSPOINT]
) )
await self._active.connect() await self._active.connect(bus)

View File

@ -2,6 +2,8 @@
import logging import logging
from typing import Any from typing import Any
from dbus_next.aio.message_bus import MessageBus
from ..exceptions import DBusError, DBusInterfaceError from ..exceptions import DBusError, DBusInterfaceError
from ..utils.dbus import DBus, DBusSignalWrapper from ..utils.dbus import DBus, DBusSignalWrapper
from .const import ( from .const import (
@ -35,10 +37,10 @@ class Rauc(DBusInterface):
self._variant: str | None = None self._variant: str | None = None
self._boot_slot: str | None = None self._boot_slot: str | None = None
async def connect(self): async def connect(self, bus: MessageBus):
"""Connect to D-Bus.""" """Connect to D-Bus."""
try: try:
self.dbus = await DBus.connect(DBUS_NAME_RAUC, DBUS_OBJECT_BASE) self.dbus = await DBus.connect(bus, DBUS_NAME_RAUC, DBUS_OBJECT_BASE)
except DBusError: except DBusError:
_LOGGER.warning("Can't connect to rauc") _LOGGER.warning("Can't connect to rauc")
except DBusInterfaceError: except DBusInterfaceError:

View File

@ -4,6 +4,8 @@ from __future__ import annotations
import logging import logging
from typing import Any from typing import Any
from dbus_next.aio.message_bus import MessageBus
from ..exceptions import DBusError, DBusInterfaceError from ..exceptions import DBusError, DBusInterfaceError
from ..utils.dbus import DBus from ..utils.dbus import DBus
from .const import ( from .const import (
@ -54,10 +56,12 @@ class Resolved(DBusInterface):
"""Initialize Properties.""" """Initialize Properties."""
self.properties: dict[str, Any] = {} self.properties: dict[str, Any] = {}
async def connect(self): async def connect(self, bus: MessageBus):
"""Connect to D-Bus.""" """Connect to D-Bus."""
try: try:
self.dbus = await DBus.connect(DBUS_NAME_RESOLVED, DBUS_OBJECT_RESOLVED) self.dbus = await DBus.connect(
bus, DBUS_NAME_RESOLVED, DBUS_OBJECT_RESOLVED
)
except DBusError: except DBusError:
_LOGGER.warning("Can't connect to systemd-resolved.") _LOGGER.warning("Can't connect to systemd-resolved.")
except DBusInterfaceError: except DBusInterfaceError:

View File

@ -2,6 +2,8 @@
import logging import logging
from typing import Any from typing import Any
from dbus_next.aio.message_bus import MessageBus
from ..exceptions import DBusError, DBusInterfaceError from ..exceptions import DBusError, DBusInterfaceError
from ..utils.dbus import DBus from ..utils.dbus import DBus
from .const import ( from .const import (
@ -32,10 +34,10 @@ class Systemd(DBusInterface):
"""Initialize Properties.""" """Initialize Properties."""
self.properties: dict[str, Any] = {} self.properties: dict[str, Any] = {}
async def connect(self): async def connect(self, bus: MessageBus):
"""Connect to D-Bus.""" """Connect to D-Bus."""
try: try:
self.dbus = await DBus.connect(DBUS_NAME_SYSTEMD, DBUS_OBJECT_SYSTEMD) self.dbus = await DBus.connect(bus, DBUS_NAME_SYSTEMD, DBUS_OBJECT_SYSTEMD)
except DBusError: except DBusError:
_LOGGER.warning("Can't connect to systemd") _LOGGER.warning("Can't connect to systemd")
except DBusInterfaceError: except DBusInterfaceError:

View File

@ -3,6 +3,8 @@ from datetime import datetime
import logging import logging
from typing import Any from typing import Any
from dbus_next.aio.message_bus import MessageBus
from ..exceptions import DBusError, DBusInterfaceError from ..exceptions import DBusError, DBusInterfaceError
from ..utils.dbus import DBus from ..utils.dbus import DBus
from ..utils.dt import utc_from_timestamp from ..utils.dt import utc_from_timestamp
@ -57,10 +59,12 @@ class TimeDate(DBusInterface):
"""Return the system UTC time.""" """Return the system UTC time."""
return utc_from_timestamp(self.properties[DBUS_ATTR_TIMEUSEC] / 1000000) return utc_from_timestamp(self.properties[DBUS_ATTR_TIMEUSEC] / 1000000)
async def connect(self): async def connect(self, bus: MessageBus):
"""Connect to D-Bus.""" """Connect to D-Bus."""
try: try:
self.dbus = await DBus.connect(DBUS_NAME_TIMEDATE, DBUS_OBJECT_TIMEDATE) self.dbus = await DBus.connect(
bus, DBUS_NAME_TIMEDATE, DBUS_OBJECT_TIMEDATE
)
except DBusError: except DBusError:
_LOGGER.warning("Can't connect to systemd-timedate") _LOGGER.warning("Can't connect to systemd-timedate")
except DBusInterfaceError: except DBusInterfaceError:

View File

@ -5,8 +5,8 @@ import asyncio
import logging import logging
from typing import Any from typing import Any
from dbus_next import BusType, InvalidIntrospectionError, Message, MessageType from dbus_next import InvalidIntrospectionError, Message, MessageType
from dbus_next.aio import MessageBus from dbus_next.aio.message_bus import MessageBus
from dbus_next.introspection import Node from dbus_next.introspection import Node
from dbus_next.signature import Variant from dbus_next.signature import Variant
@ -45,23 +45,18 @@ DBUS_METHOD_SET: str = "org.freedesktop.DBus.Properties.Set"
class DBus: class DBus:
"""DBus handler.""" """DBus handler."""
def __init__(self, bus_name: str, object_path: str) -> None: def __init__(self, bus: MessageBus, bus_name: str, object_path: str) -> None:
"""Initialize dbus object.""" """Initialize dbus object."""
self.bus_name: str = bus_name self.bus_name: str = bus_name
self.object_path: str = object_path self.object_path: str = object_path
self.methods: set[str] = set() self.methods: set[str] = set()
self.signals: set[str] = set() self.signals: set[str] = set()
self._bus: MessageBus | None = None self._bus: MessageBus = bus
def __del__(self):
"""Delete dbus object."""
if self._bus:
self._bus.disconnect()
@staticmethod @staticmethod
async def connect(bus_name: str, object_path: str) -> DBus: async def connect(bus: MessageBus, bus_name: str, object_path: str) -> DBus:
"""Read object data.""" """Read object data."""
self = DBus(bus_name, object_path) self = DBus(bus, bus_name, object_path)
# pylint: disable=protected-access # pylint: disable=protected-access
await self._init_proxy() await self._init_proxy()
@ -69,6 +64,11 @@ class DBus:
_LOGGER.debug("Connect to D-Bus: %s - %s", bus_name, object_path) _LOGGER.debug("Connect to D-Bus: %s - %s", bus_name, object_path)
return self return self
@property
def bus(self) -> MessageBus:
"""Return message bus."""
return self._bus
def _add_interfaces(self, introspection: Any): def _add_interfaces(self, introspection: Any):
# Read available methods # Read available methods
for interface in introspection.interfaces: for interface in introspection.interfaces:
@ -88,10 +88,6 @@ class DBus:
"""Read interface data.""" """Read interface data."""
# Wait for dbus object to be available after restart # Wait for dbus object to be available after restart
introspection: Node | None = None introspection: Node | None = None
try:
self._bus = await MessageBus(bus_type=BusType.SYSTEM).connect()
except Exception as err:
raise DBusFatalError() from err
for _ in range(3): for _ in range(3):
try: try:

View File

@ -29,7 +29,7 @@ async def test_llmnr_mdns_info(api_client, coresys: CoreSys):
assert result["data"]["llmnr"] is False assert result["data"]["llmnr"] is False
assert result["data"]["mdns"] is False assert result["data"]["mdns"] is False
await coresys.dbus.resolved.connect() await coresys.dbus.resolved.connect(coresys.dbus.bus)
await coresys.dbus.resolved.update() await coresys.dbus.resolved.update()
resp = await api_client.get("/dns/info") resp = await api_client.get("/dns/info")

View File

@ -23,7 +23,7 @@ async def test_api_host_info(api_client, coresys_disk_info: CoreSys):
"""Test host info api.""" """Test host info api."""
coresys = coresys_disk_info coresys = coresys_disk_info
await coresys.dbus.agent.connect() await coresys.dbus.agent.connect(coresys.dbus.bus)
await coresys.dbus.agent.update() await coresys.dbus.agent.update()
resp = await api_client.get("/host/info") resp = await api_client.get("/host/info")
@ -106,7 +106,7 @@ async def test_api_llmnr_mdns_info(api_client, coresys_disk_info: CoreSys):
assert result["data"]["llmnr_hostname"] is None assert result["data"]["llmnr_hostname"] is None
coresys.host.sys_dbus.resolved.is_connected = True coresys.host.sys_dbus.resolved.is_connected = True
await coresys.dbus.resolved.connect() await coresys.dbus.resolved.connect(coresys.dbus.bus)
await coresys.dbus.resolved.update() await coresys.dbus.resolved.update()
resp = await api_client.get("/host/info") resp = await api_client.get("/host/info")

View File

@ -29,7 +29,7 @@ async def test_api_os_info(api_client):
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_api_os_info_with_agent(api_client, coresys: CoreSys): async def test_api_os_info_with_agent(api_client, coresys: CoreSys):
"""Test docker info api.""" """Test docker info api."""
await coresys.dbus.agent.connect() await coresys.dbus.agent.connect(coresys.dbus.bus)
await coresys.dbus.agent.update() await coresys.dbus.agent.update()
resp = await api_client.get("/os/info") resp = await api_client.get("/os/info")
@ -41,7 +41,7 @@ async def test_api_os_info_with_agent(api_client, coresys: CoreSys):
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_api_os_datadisk_move(api_client, coresys: CoreSys): async def test_api_os_datadisk_move(api_client, coresys: CoreSys):
"""Test datadisk move without exists disk.""" """Test datadisk move without exists disk."""
await coresys.dbus.agent.connect() await coresys.dbus.agent.connect(coresys.dbus.bus)
await coresys.dbus.agent.update() await coresys.dbus.agent.update()
coresys.os._available = True coresys.os._available = True
@ -54,7 +54,7 @@ async def test_api_os_datadisk_move(api_client, coresys: CoreSys):
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_api_os_datadisk_list(api_client, coresys: CoreSys): async def test_api_os_datadisk_list(api_client, coresys: CoreSys):
"""Test datadisk list function.""" """Test datadisk list function."""
await coresys.dbus.agent.connect() await coresys.dbus.agent.connect(coresys.dbus.bus)
await coresys.dbus.agent.update() await coresys.dbus.agent.update()
coresys.hardware.update_device( coresys.hardware.update_device(

View File

@ -10,6 +10,7 @@ from uuid import uuid4
from aiohttp import web from aiohttp import web
from awesomeversion import AwesomeVersion from awesomeversion import AwesomeVersion
from dbus_next import introspection as intr from dbus_next import introspection as intr
from dbus_next.aio.message_bus import MessageBus
import pytest import pytest
from securetar import SecureTarFile from securetar import SecureTarFile
@ -103,7 +104,13 @@ def docker() -> DockerAPI:
@pytest.fixture @pytest.fixture
def dbus() -> DBus: async def dbus_bus() -> MessageBus:
"""Message bus mock."""
yield AsyncMock(spec=MessageBus)
@pytest.fixture
def dbus(dbus_bus: MessageBus) -> DBus:
"""Mock DBUS.""" """Mock DBUS."""
dbus_commands = [] dbus_commands = []
@ -189,63 +196,67 @@ def dbus() -> DBus:
new=mock_wait_for_signal, new=mock_wait_for_signal,
), patch( ), patch(
"supervisor.utils.dbus.DBus.get_property", new=mock_get_property "supervisor.utils.dbus.DBus.get_property", new=mock_get_property
), patch(
"supervisor.dbus.manager.MessageBus.connect", return_value=dbus_bus
): ):
yield dbus_commands yield dbus_commands
@pytest.fixture @pytest.fixture
async def network_manager(dbus) -> NetworkManager: async def network_manager(dbus, dbus_bus: MessageBus) -> NetworkManager:
"""Mock NetworkManager.""" """Mock NetworkManager."""
nm_obj = NetworkManager() nm_obj = NetworkManager()
nm_obj.dbus = dbus nm_obj.dbus = dbus
# Init # Init
await nm_obj.connect() await nm_obj.connect(dbus_bus)
await nm_obj.update() await nm_obj.update()
yield nm_obj yield nm_obj
async def mock_dbus_interface(dbus: DBus, instance: DBusInterface) -> DBusInterface: async def mock_dbus_interface(
dbus: DBus, dbus_bus: MessageBus, instance: DBusInterface
) -> DBusInterface:
"""Mock dbus for a DBusInterface instance.""" """Mock dbus for a DBusInterface instance."""
instance.dbus = dbus instance.dbus = dbus
await instance.connect() await instance.connect(dbus_bus)
return instance return instance
@pytest.fixture @pytest.fixture
async def hostname(dbus: DBus) -> Hostname: async def hostname(dbus: DBus, dbus_bus: MessageBus) -> Hostname:
"""Mock Hostname.""" """Mock Hostname."""
yield await mock_dbus_interface(dbus, Hostname()) yield await mock_dbus_interface(dbus, dbus_bus, Hostname())
@pytest.fixture @pytest.fixture
async def timedate(dbus: DBus) -> TimeDate: async def timedate(dbus: DBus, dbus_bus: MessageBus) -> TimeDate:
"""Mock Timedate.""" """Mock Timedate."""
yield await mock_dbus_interface(dbus, TimeDate()) yield await mock_dbus_interface(dbus, dbus_bus, TimeDate())
@pytest.fixture @pytest.fixture
async def systemd(dbus: DBus) -> Systemd: async def systemd(dbus: DBus, dbus_bus: MessageBus) -> Systemd:
"""Mock Systemd.""" """Mock Systemd."""
yield await mock_dbus_interface(dbus, Systemd()) yield await mock_dbus_interface(dbus, dbus_bus, Systemd())
@pytest.fixture @pytest.fixture
async def os_agent(dbus: DBus) -> OSAgent: async def os_agent(dbus: DBus, dbus_bus: MessageBus) -> OSAgent:
"""Mock OSAgent.""" """Mock OSAgent."""
yield await mock_dbus_interface(dbus, OSAgent()) yield await mock_dbus_interface(dbus, dbus_bus, OSAgent())
@pytest.fixture @pytest.fixture
async def resolved(dbus: DBus) -> Resolved: async def resolved(dbus: DBus, dbus_bus: MessageBus) -> Resolved:
"""Mock REsolved.""" """Mock REsolved."""
yield await mock_dbus_interface(dbus, Resolved()) yield await mock_dbus_interface(dbus, dbus_bus, Resolved())
@pytest.fixture @pytest.fixture
async def coresys( async def coresys(
event_loop, docker, network_manager, aiohttp_client, run_dir event_loop, docker, network_manager, dbus_bus, aiohttp_client, run_dir
) -> CoreSys: ) -> CoreSys:
"""Create a CoreSys Mock.""" """Create a CoreSys Mock."""
with patch("supervisor.bootstrap.initialize_system"), patch( with patch("supervisor.bootstrap.initialize_system"), patch(
@ -269,6 +280,7 @@ async def coresys(
coresys_obj._machine_id = uuid4() coresys_obj._machine_id = uuid4()
# Mock host communication # Mock host communication
coresys_obj._dbus._bus = dbus_bus
coresys_obj._dbus._network = network_manager coresys_obj._dbus._network = network_manager
# Mock docker # Mock docker

View File

@ -8,7 +8,7 @@ async def test_dbus_osagent(coresys: CoreSys):
assert coresys.dbus.agent.version is None assert coresys.dbus.agent.version is None
assert coresys.dbus.agent.diagnostics is None assert coresys.dbus.agent.diagnostics is None
await coresys.dbus.agent.connect() await coresys.dbus.agent.connect(coresys.dbus.bus)
await coresys.dbus.agent.update() await coresys.dbus.agent.update()
assert coresys.dbus.agent.version == "1.1.0" assert coresys.dbus.agent.version == "1.1.0"

View File

@ -11,7 +11,7 @@ async def test_dbus_osagent_apparmor(coresys: CoreSys):
"""Test coresys dbus connection.""" """Test coresys dbus connection."""
assert coresys.dbus.agent.apparmor.version is None assert coresys.dbus.agent.apparmor.version is None
await coresys.dbus.agent.connect() await coresys.dbus.agent.connect(coresys.dbus.bus)
await coresys.dbus.agent.update() await coresys.dbus.agent.update()
assert coresys.dbus.agent.apparmor.version == "2.13.2" assert coresys.dbus.agent.apparmor.version == "2.13.2"
@ -24,7 +24,7 @@ async def test_dbus_osagent_apparmor_load(coresys: CoreSys, dbus: list[str]):
Path("/data/apparmor/profile"), Path("/data/apparmor/cache") Path("/data/apparmor/profile"), Path("/data/apparmor/cache")
) )
await coresys.dbus.agent.connect() await coresys.dbus.agent.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
assert ( assert (
@ -43,7 +43,7 @@ async def test_dbus_osagent_apparmor_unload(coresys: CoreSys, dbus: list[str]):
Path("/data/apparmor/profile"), Path("/data/apparmor/cache") Path("/data/apparmor/profile"), Path("/data/apparmor/cache")
) )
await coresys.dbus.agent.connect() await coresys.dbus.agent.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
assert ( assert (

View File

@ -8,11 +8,10 @@ from supervisor.exceptions import DBusNotConnectedError
async def test_dbus_osagent_cgroup_add_devices(coresys: CoreSys, dbus: list[str]): async def test_dbus_osagent_cgroup_add_devices(coresys: CoreSys, dbus: list[str]):
"""Test wipe data partition on host.""" """Test wipe data partition on host."""
with pytest.raises(DBusNotConnectedError): with pytest.raises(DBusNotConnectedError):
await coresys.dbus.agent.cgroup.add_devices_allowed("9324kl23j4kl", "*:* rwm") await coresys.dbus.agent.cgroup.add_devices_allowed("9324kl23j4kl", "*:* rwm")
await coresys.dbus.agent.connect() await coresys.dbus.agent.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
assert ( assert (

View File

@ -11,7 +11,7 @@ async def test_dbus_osagent_datadisk(coresys: CoreSys):
"""Test coresys dbus connection.""" """Test coresys dbus connection."""
assert coresys.dbus.agent.datadisk.current_device is None assert coresys.dbus.agent.datadisk.current_device is None
await coresys.dbus.agent.connect() await coresys.dbus.agent.connect(coresys.dbus.bus)
await coresys.dbus.agent.update() await coresys.dbus.agent.update()
assert coresys.dbus.agent.datadisk.current_device.as_posix() == "/dev/sda" assert coresys.dbus.agent.datadisk.current_device.as_posix() == "/dev/sda"
@ -22,7 +22,7 @@ async def test_dbus_osagent_datadisk_change_device(coresys: CoreSys, dbus: list[
with pytest.raises(DBusNotConnectedError): with pytest.raises(DBusNotConnectedError):
await coresys.dbus.agent.datadisk.change_device(Path("/dev/sdb")) await coresys.dbus.agent.datadisk.change_device(Path("/dev/sdb"))
await coresys.dbus.agent.connect() await coresys.dbus.agent.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
assert await coresys.dbus.agent.datadisk.change_device(Path("/dev/sdb")) is None assert await coresys.dbus.agent.datadisk.change_device(Path("/dev/sdb")) is None
@ -34,7 +34,7 @@ async def test_dbus_osagent_datadisk_reload_device(coresys: CoreSys, dbus: list[
with pytest.raises(DBusNotConnectedError): with pytest.raises(DBusNotConnectedError):
await coresys.dbus.agent.datadisk.reload_device() await coresys.dbus.agent.datadisk.reload_device()
await coresys.dbus.agent.connect() await coresys.dbus.agent.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
assert await coresys.dbus.agent.datadisk.reload_device() is None assert await coresys.dbus.agent.datadisk.reload_device() is None

View File

@ -11,7 +11,7 @@ async def test_dbus_osagent_system_wipe(coresys: CoreSys, dbus: list[str]):
with pytest.raises(DBusNotConnectedError): with pytest.raises(DBusNotConnectedError):
await coresys.dbus.agent.system.schedule_wipe_device() await coresys.dbus.agent.system.schedule_wipe_device()
await coresys.dbus.agent.connect() await coresys.dbus.agent.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
assert await coresys.dbus.agent.system.schedule_wipe_device() is None assert await coresys.dbus.agent.system.schedule_wipe_device() is None

View File

@ -134,7 +134,7 @@ async def mock_call_dbus_get_settings_signature(
async def test_update(coresys: CoreSys): async def test_update(coresys: CoreSys):
"""Test network manager update.""" """Test network manager update."""
await coresys.dbus.network.interfaces[TEST_INTERFACE].connect() await coresys.dbus.network.interfaces[TEST_INTERFACE].connect(coresys.dbus.bus)
interface = Interface.from_dbus_interface( interface = Interface.from_dbus_interface(
coresys.dbus.network.interfaces[TEST_INTERFACE] coresys.dbus.network.interfaces[TEST_INTERFACE]
) )
@ -154,7 +154,7 @@ async def test_update(coresys: CoreSys):
async def test_ipv6_disabled_is_link_local(coresys: CoreSys): async def test_ipv6_disabled_is_link_local(coresys: CoreSys):
"""Test disabled equals link local for ipv6.""" """Test disabled equals link local for ipv6."""
await coresys.dbus.network.interfaces[TEST_INTERFACE].connect() await coresys.dbus.network.interfaces[TEST_INTERFACE].connect(coresys.dbus.bus)
interface = Interface.from_dbus_interface( interface = Interface.from_dbus_interface(
coresys.dbus.network.interfaces[TEST_INTERFACE] coresys.dbus.network.interfaces[TEST_INTERFACE]
) )

View File

@ -1,15 +1,17 @@
"""Test NetworkWireless AP object.""" """Test NetworkWireless AP object."""
from dbus_next.aio.message_bus import MessageBus
from supervisor.dbus.network.accesspoint import NetworkWirelessAP from supervisor.dbus.network.accesspoint import NetworkWirelessAP
async def test_accesspoint(dbus: list[str]): async def test_accesspoint(dbus: list[str], dbus_bus: MessageBus):
"""Test accesspoint.""" """Test accesspoint."""
wireless_ap = NetworkWirelessAP("/org/freedesktop/NetworkManager/AccessPoint/43099") wireless_ap = NetworkWirelessAP("/org/freedesktop/NetworkManager/AccessPoint/43099")
assert wireless_ap.mac is None assert wireless_ap.mac is None
assert wireless_ap.mode is None assert wireless_ap.mode is None
await wireless_ap.connect() await wireless_ap.connect(dbus_bus)
assert wireless_ap.mac == "E4:57:40:A9:D7:DE" assert wireless_ap.mac == "E4:57:40:A9:D7:DE"
assert wireless_ap.mode == 2 assert wireless_ap.mode == 2

View File

@ -10,7 +10,7 @@ async def test_dbus_hostname_info(coresys: CoreSys):
"""Test coresys dbus connection.""" """Test coresys dbus connection."""
assert coresys.dbus.hostname.hostname is None assert coresys.dbus.hostname.hostname is None
await coresys.dbus.hostname.connect() await coresys.dbus.hostname.connect(coresys.dbus.bus)
await coresys.dbus.hostname.update() await coresys.dbus.hostname.update()
assert coresys.dbus.hostname.hostname == "homeassistant-n2" assert coresys.dbus.hostname.hostname == "homeassistant-n2"
@ -27,7 +27,7 @@ async def test_dbus_sethostname(coresys: CoreSys, dbus: list[str]):
with pytest.raises(DBusNotConnectedError): with pytest.raises(DBusNotConnectedError):
await coresys.dbus.hostname.set_static_hostname("StarWars") await coresys.dbus.hostname.set_static_hostname("StarWars")
await coresys.dbus.hostname.connect() await coresys.dbus.hostname.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
await coresys.dbus.hostname.set_static_hostname("StarWars") await coresys.dbus.hostname.set_static_hostname("StarWars")

View File

@ -10,7 +10,7 @@ async def test_reboot(coresys: CoreSys, dbus: list[str]):
with pytest.raises(DBusNotConnectedError): with pytest.raises(DBusNotConnectedError):
await coresys.dbus.logind.reboot() await coresys.dbus.logind.reboot()
await coresys.dbus.logind.connect() await coresys.dbus.logind.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
assert await coresys.dbus.logind.reboot() is None assert await coresys.dbus.logind.reboot() is None
@ -22,7 +22,7 @@ async def test_power_off(coresys: CoreSys, dbus: list[str]):
with pytest.raises(DBusNotConnectedError): with pytest.raises(DBusNotConnectedError):
await coresys.dbus.logind.power_off() await coresys.dbus.logind.power_off()
await coresys.dbus.logind.connect() await coresys.dbus.logind.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
assert await coresys.dbus.logind.power_off() is None assert await coresys.dbus.logind.power_off() is None

View File

@ -11,7 +11,7 @@ async def test_rauc(coresys: CoreSys):
assert coresys.dbus.rauc.boot_slot is None assert coresys.dbus.rauc.boot_slot is None
assert coresys.dbus.rauc.operation is None assert coresys.dbus.rauc.operation is None
await coresys.dbus.rauc.connect() await coresys.dbus.rauc.connect(coresys.dbus.bus)
await coresys.dbus.rauc.update() await coresys.dbus.rauc.update()
assert coresys.dbus.rauc.boot_slot == "B" assert coresys.dbus.rauc.boot_slot == "B"
@ -23,7 +23,7 @@ async def test_install(coresys: CoreSys, dbus: list[str]):
with pytest.raises(DBusNotConnectedError): with pytest.raises(DBusNotConnectedError):
await coresys.dbus.rauc.install("rauc_file") await coresys.dbus.rauc.install("rauc_file")
await coresys.dbus.rauc.connect() await coresys.dbus.rauc.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
async with coresys.dbus.rauc.signal_completed() as signal: async with coresys.dbus.rauc.signal_completed() as signal:
@ -38,7 +38,7 @@ async def test_get_slot_status(coresys: CoreSys, dbus: list[str]):
with pytest.raises(DBusNotConnectedError): with pytest.raises(DBusNotConnectedError):
await coresys.dbus.rauc.get_slot_status() await coresys.dbus.rauc.get_slot_status()
await coresys.dbus.rauc.connect() await coresys.dbus.rauc.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
slot_status = await coresys.dbus.rauc.get_slot_status() slot_status = await coresys.dbus.rauc.get_slot_status()
@ -59,7 +59,7 @@ async def test_mark(coresys: CoreSys, dbus: list[str]):
with pytest.raises(DBusNotConnectedError): with pytest.raises(DBusNotConnectedError):
await coresys.dbus.rauc.mark(RaucState.GOOD, "booted") await coresys.dbus.rauc.mark(RaucState.GOOD, "booted")
await coresys.dbus.rauc.connect() await coresys.dbus.rauc.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
mark = await coresys.dbus.rauc.mark(RaucState.GOOD, "booted") mark = await coresys.dbus.rauc.mark(RaucState.GOOD, "booted")

View File

@ -52,7 +52,7 @@ async def test_dbus_resolved_info(coresys_ip_bytes: CoreSys):
assert coresys.dbus.resolved.dns is None assert coresys.dbus.resolved.dns is None
await coresys.dbus.resolved.connect() await coresys.dbus.resolved.connect(coresys.dbus.bus)
await coresys.dbus.resolved.update() await coresys.dbus.resolved.update()
assert coresys.dbus.resolved.llmnr_hostname == "homeassistant" assert coresys.dbus.resolved.llmnr_hostname == "homeassistant"

View File

@ -16,7 +16,7 @@ async def test_dbus_systemd_info(coresys: CoreSys):
assert coresys.dbus.systemd.boot_timestamp is None assert coresys.dbus.systemd.boot_timestamp is None
assert coresys.dbus.systemd.startup_time is None assert coresys.dbus.systemd.startup_time is None
await coresys.dbus.systemd.connect() await coresys.dbus.systemd.connect(coresys.dbus.bus)
async def mock_get_properties(dbus_obj, interface): async def mock_get_properties(dbus_obj, interface):
return load_json_fixture( return load_json_fixture(
@ -35,7 +35,7 @@ async def test_reboot(coresys: CoreSys, dbus: list[str]):
with pytest.raises(DBusNotConnectedError): with pytest.raises(DBusNotConnectedError):
await coresys.dbus.systemd.reboot() await coresys.dbus.systemd.reboot()
await coresys.dbus.systemd.connect() await coresys.dbus.systemd.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
assert await coresys.dbus.systemd.reboot() is None assert await coresys.dbus.systemd.reboot() is None
@ -47,7 +47,7 @@ async def test_power_off(coresys: CoreSys, dbus: list[str]):
with pytest.raises(DBusNotConnectedError): with pytest.raises(DBusNotConnectedError):
await coresys.dbus.systemd.power_off() await coresys.dbus.systemd.power_off()
await coresys.dbus.systemd.connect() await coresys.dbus.systemd.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
assert await coresys.dbus.systemd.power_off() is None assert await coresys.dbus.systemd.power_off() is None
@ -61,7 +61,7 @@ async def test_start_unit(coresys: CoreSys, dbus: list[str]):
with pytest.raises(DBusNotConnectedError): with pytest.raises(DBusNotConnectedError):
await coresys.dbus.systemd.start_unit("test_unit", "replace") await coresys.dbus.systemd.start_unit("test_unit", "replace")
await coresys.dbus.systemd.connect() await coresys.dbus.systemd.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
assert ( assert (
@ -78,7 +78,7 @@ async def test_stop_unit(coresys: CoreSys, dbus: list[str]):
with pytest.raises(DBusNotConnectedError): with pytest.raises(DBusNotConnectedError):
await coresys.dbus.systemd.stop_unit("test_unit", "replace") await coresys.dbus.systemd.stop_unit("test_unit", "replace")
await coresys.dbus.systemd.connect() await coresys.dbus.systemd.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
assert ( assert (
@ -95,7 +95,7 @@ async def test_restart_unit(coresys: CoreSys, dbus: list[str]):
with pytest.raises(DBusNotConnectedError): with pytest.raises(DBusNotConnectedError):
await coresys.dbus.systemd.restart_unit("test_unit", "replace") await coresys.dbus.systemd.restart_unit("test_unit", "replace")
await coresys.dbus.systemd.connect() await coresys.dbus.systemd.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
assert ( assert (
@ -112,7 +112,7 @@ async def test_reload_unit(coresys: CoreSys, dbus: list[str]):
with pytest.raises(DBusNotConnectedError): with pytest.raises(DBusNotConnectedError):
await coresys.dbus.systemd.reload_unit("test_unit", "replace") await coresys.dbus.systemd.reload_unit("test_unit", "replace")
await coresys.dbus.systemd.connect() await coresys.dbus.systemd.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
assert ( assert (
@ -129,7 +129,7 @@ async def test_list_units(coresys: CoreSys, dbus: list[str]):
with pytest.raises(DBusNotConnectedError): with pytest.raises(DBusNotConnectedError):
await coresys.dbus.systemd.list_units() await coresys.dbus.systemd.list_units()
await coresys.dbus.systemd.connect() await coresys.dbus.systemd.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
units = await coresys.dbus.systemd.list_units() units = await coresys.dbus.systemd.list_units()

View File

@ -11,7 +11,7 @@ async def test_dbus_timezone(coresys: CoreSys):
"""Test coresys dbus connection.""" """Test coresys dbus connection."""
assert coresys.dbus.timedate.dt_utc is None assert coresys.dbus.timedate.dt_utc is None
await coresys.dbus.timedate.connect() await coresys.dbus.timedate.connect(coresys.dbus.bus)
await coresys.dbus.timedate.update() await coresys.dbus.timedate.update()
assert coresys.dbus.timedate.dt_utc == datetime( assert coresys.dbus.timedate.dt_utc == datetime(
@ -30,7 +30,7 @@ async def test_dbus_settime(coresys: CoreSys, dbus: list[str]):
with pytest.raises(DBusNotConnectedError): with pytest.raises(DBusNotConnectedError):
await coresys.dbus.timedate.set_time(test_dt) await coresys.dbus.timedate.set_time(test_dt)
await coresys.dbus.timedate.connect() await coresys.dbus.timedate.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
assert await coresys.dbus.timedate.set_time(test_dt) is None assert await coresys.dbus.timedate.set_time(test_dt) is None
@ -42,7 +42,7 @@ async def test_dbus_setntp(coresys: CoreSys, dbus: list[str]):
with pytest.raises(DBusNotConnectedError): with pytest.raises(DBusNotConnectedError):
await coresys.dbus.timedate.set_ntp(False) await coresys.dbus.timedate.set_ntp(False)
await coresys.dbus.timedate.connect() await coresys.dbus.timedate.connect(coresys.dbus.bus)
dbus.clear() dbus.clear()
assert await coresys.dbus.timedate.set_ntp(False) is None assert await coresys.dbus.timedate.set_ntp(False) is None

View File

@ -13,7 +13,7 @@ from supervisor.hardware.data import Device
@pytest.mark.asyncio @pytest.mark.asyncio
async def tests_datadisk_current(coresys: CoreSys): async def tests_datadisk_current(coresys: CoreSys):
"""Test current datadisk.""" """Test current datadisk."""
await coresys.dbus.agent.connect() await coresys.dbus.agent.connect(coresys.dbus.bus)
await coresys.dbus.agent.update() await coresys.dbus.agent.update()
assert coresys.os.datadisk.disk_used == PosixPath("/dev/sda") assert coresys.os.datadisk.disk_used == PosixPath("/dev/sda")
@ -22,7 +22,7 @@ async def tests_datadisk_current(coresys: CoreSys):
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_datadisk_move(coresys: CoreSys): async def test_datadisk_move(coresys: CoreSys):
"""Test datadisk moved without exists device.""" """Test datadisk moved without exists device."""
await coresys.dbus.agent.connect() await coresys.dbus.agent.connect(coresys.dbus.bus)
await coresys.dbus.agent.update() await coresys.dbus.agent.update()
coresys.os._available = True coresys.os._available = True
@ -33,7 +33,7 @@ async def test_datadisk_move(coresys: CoreSys):
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_datadisk_list(coresys: CoreSys): async def test_datadisk_list(coresys: CoreSys):
"""Test docker info api.""" """Test docker info api."""
await coresys.dbus.agent.connect() await coresys.dbus.agent.connect(coresys.dbus.bus)
await coresys.dbus.agent.update() await coresys.dbus.agent.update()
coresys.hardware.update_device( coresys.hardware.update_device(

View File

@ -14,7 +14,7 @@ async def test_timezone(run_dir, coresys: CoreSys):
assert coresys.timezone == "UTC" assert coresys.timezone == "UTC"
assert coresys.config.timezone is None assert coresys.config.timezone is None
await coresys.dbus.timedate.connect() await coresys.dbus.timedate.connect(coresys.dbus.bus)
await coresys.dbus.timedate.update() await coresys.dbus.timedate.update()
assert coresys.timezone == "Etc/UTC" assert coresys.timezone == "Etc/UTC"

View File

@ -22,8 +22,11 @@ def test_remove_dbus_signature():
async def test_dbus_prepare_args(coresys: CoreSys): async def test_dbus_prepare_args(coresys: CoreSys):
"""Check D-Bus dynamic argument builder.""" """Check D-Bus dynamic argument builder."""
dbus = DBus("org.freedesktop.systemd1", "/org/freedesktop/systemd1") dbus = DBus(
signature, args = dbus._prepare_args( coresys.dbus.bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1"
)
# pylint: disable=protected-access
signature, _ = dbus._prepare_args(
True, 1, 1.0, "Value", ("a{sv}", {"Key": "Value"}) True, 1, 1.0, "Value", ("a{sv}", {"Key": "Value"})
) )
assert signature == "bidsa{sv}" assert signature == "bidsa{sv}"