diff --git a/src/revpi_middleware/dbus_middleware1/system_config/revpi_config.py b/src/revpi_middleware/dbus_middleware1/system_config/revpi_config.py index b61ae20..afd8a03 100644 --- a/src/revpi_middleware/dbus_middleware1/system_config/revpi_config.py +++ b/src/revpi_middleware/dbus_middleware1/system_config/revpi_config.py @@ -25,6 +25,7 @@ ConfigVariable = namedtuple("ConfigVariable", ["name", "value", "line_index"]) LINUX_BT_CLASS_PATH = "/sys/class/bluetooth" LINUX_WLAN_CLASS_PATH = "/sys/class/ieee80211" CONFIG_TXT_LOCATIONS = ("/boot/firmware/config.txt", "/boot/config.txt") +CMDLINE_TXT_LOCK = Lock() CONFIG_TXT_LOCK = Lock() @@ -221,6 +222,61 @@ class RevPiConfig: return bool(self._wlan_class_path) +class CmdLineTxt: + + # Value is optional, "?:=" non-capturing the "=" + re_name_value = re.compile(r"(?P[^\s=]+)(?:=(?P\S+))?") + + def __init__(self): + self._cmdline_txt_path = "" + for path in CONFIG_TXT_LOCATIONS: + if exists(path): + self._cmdline_txt_path = path + break + + if not self._cmdline_txt_path: + raise FileNotFoundError("no config.txt found") + + def _get_cmdline_dict(self) -> dict: + with CMDLINE_TXT_LOCK: + with open(self._cmdline_txt_path, "r") as file: + cmdline = file.read() + + return { + match.group("key"): match.group("value") + for match in self.re_name_value.finditer(cmdline) + } + + def _write_cmdline_dict(self, cmdline_dict: dict) -> None: + with CMDLINE_TXT_LOCK: + + tmp_path = f"{self._cmdline_txt_path}.tmp" + with open(tmp_path, "w") as file: + str_cmdline = "" + for key, value in cmdline_dict.items(): + if value is None: + str_cmdline += f"{key} " + else: + str_cmdline += f"{key}={value} " + + str_cmdline = str_cmdline.strip() + file.write(str_cmdline + "\n") + + shutil.move(tmp_path, self._cmdline_txt_path) + + def remove_key(self, key: str) -> None: + dc_cmdline = self._get_cmdline_dict() + if key in dc_cmdline: + del dc_cmdline[key] + self._write_cmdline_dict(dc_cmdline) + + def set_key_value(self, key: str, value: Optional[str] = None) -> None: + dc_cmdline = self._get_cmdline_dict() + if key not in dc_cmdline or dc_cmdline.get(key, value) != value: + dc_cmdline[key] = value + self._write_cmdline_dict(dc_cmdline) + + class ConfigTxt: """ Configuration file handler for managing 'config.txt'.