diff --git a/src/revpi_middleware/daemon.py b/src/revpi_middleware/daemon.py index 06e3dc8..9eced95 100644 --- a/src/revpi_middleware/daemon.py +++ b/src/revpi_middleware/daemon.py @@ -4,16 +4,16 @@ """Main daemon of revpi-middleware.""" from logging import getLogger +from os import getuid, environ from threading import Event from time import perf_counter -from typing import Union, List +from typing import List -from dbus import SystemBus, SessionBus +from gi.repository import Gio from . import proginit as pi from .dbus_ios1 import BusProviderIos1 from .dbus_middleware1 import BusProviderMiddleware1 -from .helper import get_new_session_dbus_connection, get_new_system_dbus_connection log = getLogger(__name__) @@ -43,19 +43,23 @@ class MiddlewareDaemon: log.debug("leave MiddlewareDaemon._configure") - def _get_bus(self) -> Union[SystemBus, SessionBus]: - return ( - get_new_session_dbus_connection() - if pi.pargs.use_session_bus - else get_new_system_dbus_connection() - ) + @staticmethod + def _get_bus_address() -> str: + if pi.pargs.use_session_bus: + environ_name = "DBUS_SESSION_BUS_ADDRESS" + bus_address = Gio.dbus_address_get_for_bus_sync(Gio.BusType.SESSION) + else: + environ_name = "DBUS_SYSTEM_BUS_ADDRESS" + bus_address = Gio.dbus_address_get_for_bus_sync(Gio.BusType.SYSTEM) + + return environ.get(environ_name, bus_address) def dbus_start(self): log.debug("enter MiddlewareDaemon.dbus_start") dbus_middleware1_running = self.bp_middleware1 and self.bp_middleware1.is_alive() if not dbus_middleware1_running: - self.bp_middleware1 = BusProviderMiddleware1(self._get_bus()) + self.bp_middleware1 = BusProviderMiddleware1(self._get_bus_address()) self.bp_middleware1.start() dbus_ios1_running = self.bp_ios1 and self.bp_ios1.is_alive() @@ -79,14 +83,12 @@ class MiddlewareDaemon: self.bp_middleware1.join(timeout=10.0) if self.bp_middleware1.is_alive(): log.warning("dbus middleware1 provider thread is still alive") - self.bp_middleware1.bus.con.close() if self.bp_ios1 and self.bp_ios1 in bus_filter: self.bp_ios1.stop() self.bp_ios1.join(timeout=10.0) if self.bp_ios1.is_alive(): log.warning("dbus ios1 provider thread is still alive") - self.bp_ios1.bus.con.close() log.debug("leave MiddlewareDaemon.dbus_stop") diff --git a/src/revpi_middleware/dbus_ios1/bus_provider_ios1.py b/src/revpi_middleware/dbus_ios1/bus_provider_ios1.py index c6c475f..4098019 100644 --- a/src/revpi_middleware/dbus_ios1/bus_provider_ios1.py +++ b/src/revpi_middleware/dbus_ios1/bus_provider_ios1.py @@ -5,11 +5,10 @@ from logging import getLogger from threading import Thread, Event -from typing import Union import revpimodio2 from gi.repository import GLib -from pydbus import SessionBus, SystemBus +from pydbus import connect from . import REVPI_DBUS_NAME from .interface_devices import ( @@ -29,14 +28,14 @@ class BusProviderIos1(Thread): def __init__( self, - dbus: Union[SystemBus, SessionBus], + dbus_address: str, picontrol_device="/dev/piControl0", config_rsc="/etc/revpi/config.rsc", ): log.debug("enter BusProviderIos1.__init__") super().__init__() - self._bus = dbus + self._bus_address = dbus_address self._loop = GLib.MainLoop() self._lst_device_interfaces = [] self._lst_io_interfaces = [] @@ -52,22 +51,23 @@ class BusProviderIos1(Thread): def run(self): log.debug("enter BusProviderIos1.run") + bus = connect(self._bus_address) self._lst_device_interfaces.clear() self._lst_io_interfaces.clear() for device in self._modio.device: self._lst_device_interfaces.append( - InterfaceDevice(self._bus, device), + InterfaceDevice(bus, device), ) for io in self._modio.io: interface = None try: if io.type == revpimodio2.INP: - interface = InterfaceInput(self._bus, io) + interface = InterfaceInput(bus, io) elif io.type == revpimodio2.OUT: - interface = InterfaceOutput(self._bus, io) + interface = InterfaceOutput(bus, io) elif io.type == revpimodio2.MEM: # todo: Implement memory pass @@ -85,7 +85,7 @@ class BusProviderIos1(Thread): (interface.object_path, interface) for interface in self._lst_io_interfaces ] try: - self._bus.publish( + bus.publish( REVPI_DBUS_NAME, InterfaceDeviceManager(self._lst_device_interfaces), InterfaceIoManager(self._lst_io_interfaces, self._modio), @@ -100,6 +100,7 @@ class BusProviderIos1(Thread): except Exception as e: log.error(f"can not run dbus mainloop: {e}") + bus.con.close() self._modio.cleanup() log.debug("leave BusProviderIos1.run") @@ -109,10 +110,6 @@ class BusProviderIos1(Thread): self._loop.quit() log.debug("leave BusProviderIos1.stop") - @property - def bus(self) -> Union[SystemBus, SessionBus]: - return self._bus - @property def running(self): return self._loop.is_running() diff --git a/src/revpi_middleware/dbus_middleware1/bus_provider_middleware1.py b/src/revpi_middleware/dbus_middleware1/bus_provider_middleware1.py index 17d640d..c321709 100644 --- a/src/revpi_middleware/dbus_middleware1/bus_provider_middleware1.py +++ b/src/revpi_middleware/dbus_middleware1/bus_provider_middleware1.py @@ -5,10 +5,9 @@ from logging import getLogger from threading import Thread, Event -from typing import Union from gi.repository import GLib -from pydbus import SessionBus, SystemBus +from pydbus import connect from . import REVPI_DBUS_NAME from .process_image import InterfacePiControl @@ -21,14 +20,14 @@ class BusProviderMiddleware1(Thread): def __init__( self, - dbus: Union[SystemBus, SessionBus], + dbus_address: str, picontrol_device="/dev/piControl0", config_rsc="/etc/revpi/config.rsc", ): log.debug("enter BusProviderMiddleware1.__init__") super().__init__() - self._bus = dbus + self._bus_address = dbus_address self._loop = GLib.MainLoop() self.picontrol_device = picontrol_device @@ -37,6 +36,7 @@ class BusProviderMiddleware1(Thread): def run(self): log.debug("enter BusProviderMiddleware1.run") + bus = connect(self._bus_address) # The 2nd, 3rd, ... arguments can be objects or tuples of a path and an object # Example(), @@ -44,13 +44,13 @@ class BusProviderMiddleware1(Thread): # ("Subdir2", Example()), # ("Subdir2/Whatever", Example()) lst_interfaces = [ - InterfacePiControl(self._bus, self.picontrol_device, self.config_rsc), - InterfaceRevpiConfig(self._bus), - InterfaceSoftwareServices(self._bus), + InterfacePiControl(bus, self.picontrol_device, self.config_rsc), + InterfaceRevpiConfig(bus), + InterfaceSoftwareServices(bus), ] try: - self._bus.publish( + bus.publish( REVPI_DBUS_NAME, *lst_interfaces, ) @@ -63,6 +63,8 @@ class BusProviderMiddleware1(Thread): except Exception as e: log.error(f"can not run dbus mainloop: {e}") + bus.con.close() + # Clean up all interfaces for interface in lst_interfaces: if type(interface) is tuple: @@ -76,10 +78,6 @@ class BusProviderMiddleware1(Thread): self._loop.quit() log.debug("leave BusProviderMiddleware1.stop") - @property - def bus(self) -> Union[SystemBus, SessionBus]: - return self._bus - @property def running(self): return self._loop.is_running() diff --git a/src/revpi_middleware/helper.py b/src/revpi_middleware/helper.py deleted file mode 100644 index 514623c..0000000 --- a/src/revpi_middleware/helper.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -# SPDX-FileCopyrightText: 2025 KUNBUS GmbH -# SPDX-License-Identifier: GPL-2.0-or-later -"""Helper functions for the root project.""" - -from os import environ, getuid - -from pydbus import connect - - -def get_new_system_dbus_connection(): - """ - Establishes a new connection to the system D-Bus. - - This function retrieves the system D-Bus address from the environment - variable `DBUS_SYSTEM_BUS_ADDRESS`, defaulting to - `unix:path=/run/dbus/system_bus_socket` if the variable is not set. - It then establishes and returns a connection to the D-Bus at that - address. - - Raises: - An error may be raised if establishing the connection fails. - - Returns: - The established system D-Bus connection. - """ - address = environ.get("DBUS_SYSTEM_BUS_ADDRESS", "unix:path=/run/dbus/system_bus_socket") - return connect(address) - - -def get_new_session_dbus_connection(): - """ - Establishes a new connection to the session D-Bus. - - This function retrieves the session D-Bus address from the environment - variable `DBUS_SESSION_BUS_ADDRESS`, defaulting to - `unix:path=/run/user/{UID}/bus` if the variable is not set. - It then establishes and returns a connection to the D-Bus at that - address. - - Raises: - An error may be raised if establishing the connection fails. - - Returns: - The established session D-Bus connection. - """ - address = environ.get("DBUS_SESSION_BUS_ADDRESS", f"unix:path=/run/user/{getuid()}/bus") - return connect(address)