From 437acf69bdee86220d2997f402dee22b578b91df Mon Sep 17 00:00:00 2001 From: kiarn Date: Sun, 11 Oct 2026 12:40:34 +0200 Subject: [PATCH] feat(import_devices): check devices.csv with linuxmuster-tools instead of sophomorix-device --dry-run Co-Authored-By: Claude Opus 5.5 --- debian/control | 2 +- src/linuxmuster_base7/cli/import_devices.py | 54 ++++++++++++++++----- 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/debian/control b/debian/control index ce9a091..f033be7 100644 --- a/debian/control +++ b/debian/control @@ -33,6 +33,6 @@ Depends: ${python3:Depends}, ${misc:Depends}, python3-paramiko, python3-requests, python3-setproctitle, python3-urllib3, openssl, samba, samba-ad-dc, samba-dsdb-modules, smbclient, ldb-tools, krb5-user, linuxmuster-prepare, linuxmuster-linbo7, linuxmuster-webui7, - ntpsec, sophomorix-samba, tmux + ntpsec, sophomorix-samba, tmux, linuxmuster-tools7 (>= 7.4.19) Description: linuxmuster.net configuration scripts This package provides configuration scripts for linuxmuster.net diff --git a/src/linuxmuster_base7/cli/import_devices.py b/src/linuxmuster_base7/cli/import_devices.py index fb383e0..ca666e2 100755 --- a/src/linuxmuster_base7/cli/import_devices.py +++ b/src/linuxmuster_base7/cli/import_devices.py @@ -523,7 +523,7 @@ def runSophomorixCommand(action): """Run a single sophomorix-device command, logging its output. Args: - action: sophomorix-device subcommand, e.g. '--dry-run' or '--sync' + action: sophomorix-device subcommand, e.g. '--sync' Returns: CompletedProcess instance from subprocess.run() @@ -538,27 +538,54 @@ def runSophomorixCommand(action): shell=False, check=False) -def runSophomorixDeviceSync(): - """Run sophomorix-device dry-run first, then sync if the dry-run succeeds. +def checkDevices(): + """Check the devices.csv of all schools with linuxmuster-tools. + + Every problem is reported at once, with its file and line, where + sophomorix-device --dry-run stops at the first one and does not say + where it is. - Exits the process with status 1 if either step fails or raises an error. + Exits the process with status 1 if the check finds an error or can not + run at all. """ - msg = 'Starting sophomorix-device dry-run:' + msg = 'Checking devices.csv:' printScript(msg) logToFile(msg) try: - result = runSophomorixCommand('--dry-run') + # Imported here so that a linuxmuster-tools which can not be loaded + # is reported like any other failure of the check. + from linuxmusterTools.devices import check_all_schools + result = check_all_schools() + except Exception as error: + msg = f'Could not check devices.csv with linuxmuster-tools: {error}' + printScript(msg) + logToFile(msg) + sys.exit(1) - if result.returncode != 0: - msg = f'sophomorix-device --dry-run failed with return code {result.returncode}!' - printScript(msg) - logToFile(msg) - sys.exit(1) + for line in result['report']: + print(line) + logToFile(line) - msg = 'sophomorix-device dry-run OK, starting sync:' + if not result['valid']: + msg = f"devices.csv check failed with {result['counts']['errors']} error(s)!" printScript(msg) logToFile(msg) + sys.exit(1) + msg = 'devices.csv check OK.' + printScript(msg) + logToFile(msg) + + +def runSophomorixDeviceSync(): + """Run sophomorix-device --sync. + + Exits the process with status 1 if it fails or raises an error. + """ + msg = 'Starting sophomorix-device sync:' + printScript(msg) + logToFile(msg) + try: result = runSophomorixCommand('--sync') if result.returncode == 0: @@ -654,7 +681,7 @@ def main(): This function orchestrates the complete device import workflow: 1. Parses command-line arguments - 2. Runs sophomorix-device syntax check and sync + 2. Checks devices.csv with linuxmuster-tools, then runs sophomorix-device sync 3. Generates DHCP configuration for all devices 4. Creates LINBO/GRUB boot configurations 5. Executes post-import hooks @@ -668,6 +695,7 @@ def main(): logToFile('linuxmuster-import-devices started') logToFile('School: ' + school) + checkDevices() runSophomorixDeviceSync() writeDhcpDevicesConfig(school=school) generateGrubConfigsForGroups(school)