1 Commits

Author SHA1 Message Date
Sven Sager
1172954ad7 feat(revpiconfig): Add CmdLineTxt class for managing cmdline.txt
Introduced the `CmdLineTxt` class to handle parsing, modifying, and
writing operations on the `cmdline.txt` file with thread safety.
Implemented methods for setting, removing keys, and ensuring safe file
operations.

Signed-off-by: Sven Sager <s.sager@kunbus.com>
2025-06-26 08:41:49 +02:00
5 changed files with 3 additions and 119 deletions

View File

@@ -10,7 +10,7 @@ from pydbus import SessionBus, SystemBus
from . import REVPI_DBUS_NAME from . import REVPI_DBUS_NAME
from .process_image import InterfacePiControl from .process_image import InterfacePiControl
from .system_config import InterfaceRevpiConfig, InterfaceSoftwareServices, InterfaceWlan from .system_config import InterfaceRevpiConfig, InterfaceSoftwareServices
log = getLogger(__name__) log = getLogger(__name__)
@@ -44,7 +44,6 @@ class BusProvider(Thread):
InterfacePiControl(self._bus, self.picontrol_device, self.config_rsc), InterfacePiControl(self._bus, self.picontrol_device, self.config_rsc),
InterfaceRevpiConfig(self._bus), InterfaceRevpiConfig(self._bus),
InterfaceSoftwareServices(self._bus), InterfaceSoftwareServices(self._bus),
InterfaceWlan(self._bus),
] ]
try: try:

View File

@@ -4,4 +4,3 @@
"""D-Bus interfaces for system configuration.""" """D-Bus interfaces for system configuration."""
from .interface_config import InterfaceRevpiConfig from .interface_config import InterfaceRevpiConfig
from .interface_services import InterfaceSoftwareServices from .interface_services import InterfaceSoftwareServices
from .interface_wlan import InterfaceWlan

View File

@@ -14,6 +14,7 @@ from .revpi_config import (
configure_dphys_swapfile, configure_dphys_swapfile,
configure_external_antenna, configure_external_antenna,
configure_gui, configure_gui,
configure_wlan,
) )
from ..dbus_helper import DbusInterface from ..dbus_helper import DbusInterface
@@ -97,5 +98,6 @@ AVAILABLE_FEATURES = {
"revpi-con-can": FeatureFunction(configure_con_can, []), "revpi-con-can": FeatureFunction(configure_con_can, []),
"swapfile": FeatureFunction(configure_dphys_swapfile, []), "swapfile": FeatureFunction(configure_dphys_swapfile, []),
"bluetooth": FeatureFunction(configure_bluetooth, []), "bluetooth": FeatureFunction(configure_bluetooth, []),
"wlan": FeatureFunction(configure_wlan, []),
"external-antenna": FeatureFunction(configure_external_antenna, []), "external-antenna": FeatureFunction(configure_external_antenna, []),
} }

View File

@@ -1,90 +0,0 @@
# -*- coding: utf-8 -*-
# SPDX-FileCopyrightText: 2025 KUNBUS GmbH
# SPDX-License-Identifier: GPL-2.0-or-later
"""D-Bus interfaces for wlan configuration."""
from logging import getLogger
from threading import Event, Thread
from pydbus.generic import signal
from .revpi_config import configure_wlan, ConfigActions
from ..dbus_helper import DbusInterface
log = getLogger(__name__)
class InterfaceWlan(DbusInterface):
"""
<node>
<interface name="com.revolutionpi.middleware1.WlanConfiguration">
<method name="Enable">
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
</method>
<method name="Disable">
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
</method>
<property name="available" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="status" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="true"/>
</property>
</interface>
</node>
"""
PropertiesChanged = signal()
def __init__(self, bus):
super().__init__(bus)
self._status = ""
# NetworkManager-Objekt abrufen
self.bus_nm = self.bus.get(
"org.freedesktop.NetworkManager",
"/org/freedesktop/NetworkManager",
)
# Prepare status value and thread
self.evt_stop_threading = Event()
self._update_status(suppress_signal=True)
self.th_run_status_update = Thread(
target=self._run_status_update,
daemon=True,
).start()
def _run_status_update(self, *args, **kwargs):
while not self.evt_stop_threading.wait(1.0):
self._update_status()
def _update_status(self, suppress_signal=False) -> None:
str_status = "enabled" if configure_wlan(ConfigActions.STATUS) else "disabled"
if self._status != str_status:
self._status = str_status
if not suppress_signal:
self.PropertiesChanged(
"com.revolutionpi.middleware1.WlanConfiguration",
{"status": str_status},
[],
)
def cleanup(self):
self.evt_stop_threading.set()
def Disable(self) -> None:
"""Disable integrated WLAN hardware."""
configure_wlan(ConfigActions.DISABLE)
def Enable(self) -> None:
"""Enable integrated WLAN hardware."""
configure_wlan(ConfigActions.ENABLE)
@property
def available(self) -> bool:
"""Check if WLAN hardware is available."""
return configure_wlan(ConfigActions.AVAILABLE)
@property
def status(self) -> str:
return self._status

View File

@@ -223,14 +223,6 @@ class RevPiConfig:
class CmdLineTxt: class CmdLineTxt:
"""
Represents operations on a `cmdline.txt` configuration file.
This class provides functionality to read, modify, and save the
`cmdline.txt` file commonly used for system configurations. It allows
setting key-value pairs, removing keys, and manages file locking to ensure
thread-safe modifications.
"""
# Value is optional, "?:=" non-capturing the "=" # Value is optional, "?:=" non-capturing the "="
re_name_value = re.compile(r"(?P<key>[^\s=]+)(?:=(?P<value>\S+))?") re_name_value = re.compile(r"(?P<key>[^\s=]+)(?:=(?P<value>\S+))?")
@@ -273,30 +265,12 @@ class CmdLineTxt:
shutil.move(tmp_path, self._cmdline_txt_path) shutil.move(tmp_path, self._cmdline_txt_path)
def remove_key(self, key: str) -> None: def remove_key(self, key: str) -> None:
"""
Removes a specified key from the config.txt file.
Parameters:
key: str
The key to be removed from the config.txt file.
"""
dc_cmdline = self._get_cmdline_dict() dc_cmdline = self._get_cmdline_dict()
if key in dc_cmdline: if key in dc_cmdline:
del dc_cmdline[key] del dc_cmdline[key]
self._write_cmdline_dict(dc_cmdline) self._write_cmdline_dict(dc_cmdline)
def set_key_value(self, key: str, value: Optional[str] = None) -> None: def set_key_value(self, key: str, value: Optional[str] = None) -> None:
"""
Sets a given key-value pair in the config.txt file. If the key does not
exist or the value differs from the current one, the pair is updated.
If the value is None, just the key is set without a value.
Parameters:
key: str
The key to set in the config.txt file.
value: Optional[str], default = None
The value to associate with the key, defaulting to None.
"""
dc_cmdline = self._get_cmdline_dict() dc_cmdline = self._get_cmdline_dict()
if key not in dc_cmdline or dc_cmdline.get(key, value) != value: if key not in dc_cmdline or dc_cmdline.get(key, value) != value:
dc_cmdline[key] = value dc_cmdline[key] = value