From cf59a9bb44fa62413cc7c275b921131ac9e95145 Mon Sep 17 00:00:00 2001
From: Thomas Stallinger
Date: Fri, 28 Aug 2026 11:06:37 +0200
Subject: [PATCH] Fix: dd-Anleitung referenzierte den alten festen Dateinamen
Direkte Folge des vorherigen Commits (sprechender Download-Dateiname) -
die Anleitung auf /installationsmedium zeigte weiterhin
'tuxflotte-installationsmedium.iso'. Namensbildung in _iso_dateiname()
extrahiert, von installationsmedium_ansicht() (fuer die Anzeige) UND
installationsmedium_download() (fuer den echten Header) gemeinsam
genutzt, damit beide nie auseinanderlaufen koennen.
Co-Authored-By: Claude Opus 5
---
routers/installationsmedium.py | 41 ++++++++++++++++++++----------
templates/installationsmedium.html | 2 +-
2 files changed, 29 insertions(+), 14 deletions(-)
diff --git a/routers/installationsmedium.py b/routers/installationsmedium.py
index 2f3802c..55fa99c 100644
--- a/routers/installationsmedium.py
+++ b/routers/installationsmedium.py
@@ -148,6 +148,27 @@ def finde_enrollment_session(organization_id: str, session_id: str) -> dict | No
return next((s for s in sessions if s["id"] == session_id), None)
+def _iso_dateiname(vorlage: dict | None, iso_build: dict | None) -> str:
+ """
+ Sprechender Dateiname statt immer 'tuxflotte-installationsmedium.iso' -
+ von installationsmedium_ansicht() (fuer die dd-Anleitung) UND
+ installationsmedium_download() (fuer den tatsaechlichen Content-
+ Disposition-Header) gemeinsam genutzt, damit beide garantiert densel
+ ben Namen zeigen.
+ """
+
+ if vorlage:
+ backend_teil = _dateikomponente(f"{vorlage['backend']['name']}-{vorlage['backend']['version']}")
+ workspace_teil = _dateikomponente(vorlage["workspace"]["name"])
+ else:
+ backend_teil = "unbekannt"
+ workspace_teil = "unbekannt"
+
+ datum_teil = ((iso_build or {}).get("finished_at") or datetime.now(timezone.utc).isoformat())[:10]
+
+ return f"tuxflotte-{backend_teil}-{workspace_teil}-{datum_teil}.iso"
+
+
@router.get("/installationsmedium")
def installationsmedium_ansicht(request: Request, user=Depends(get_current_user)):
organization_id = str(user.organization_id)
@@ -158,6 +179,7 @@ def installationsmedium_ansicht(request: Request, user=Depends(get_current_user)
enrollment_session = None
iso_build = None
+ iso_dateiname = None
if konfiguration and konfiguration["enrollment_session_id"]:
enrollment_session = finde_enrollment_session(organization_id, konfiguration["enrollment_session_id"])
@@ -166,6 +188,10 @@ def installationsmedium_ansicht(request: Request, user=Depends(get_current_user)
build_result = anode_request("GET", f"/api/v1/iso-builds/{konfiguration['iso_build_id']}")
iso_build = build_result.get("iso_build") if build_result.get("success") else None
+ if konfiguration and iso_build and iso_build["status"] == "completed":
+ vorlage = next((v for v in vorlagen if v["id"] == konfiguration["bereitstellungsvorlage_id"]), None)
+ iso_dateiname = _iso_dateiname(vorlage, iso_build)
+
return templates.TemplateResponse(
request,
"installationsmedium.html",
@@ -175,6 +201,7 @@ def installationsmedium_ansicht(request: Request, user=Depends(get_current_user)
"vorlagen": vorlagen,
"enrollment_session": enrollment_session,
"iso_build": iso_build,
+ "iso_dateiname": iso_dateiname,
},
)
@@ -288,22 +315,10 @@ def installationsmedium_download(user=Depends(get_current_user)):
if iso_build["status"] != "completed":
raise HTTPException(status_code=409, detail="Das Installationsmedium ist noch nicht fertig gebaut.")
- # Sprechender Dateiname statt immer desselben generischen Namens (siehe
- # _dateikomponente()) - Backend+Version+Workspace aus der verwendeten
- # Bereitstellungsvorlage, Datum aus dem Bau-Abschluss.
vorlagen_result = anode_request("GET", f"/api/v1/organizations/{organization_id}/bereitstellungsvorlagen")
vorlagen = vorlagen_result.get("bereitstellungsvorlagen", []) if vorlagen_result.get("success") else []
vorlage = next((v for v in vorlagen if v["id"] == konfiguration["bereitstellungsvorlage_id"]), None)
-
- if vorlage:
- backend_teil = _dateikomponente(f"{vorlage['backend']['name']}-{vorlage['backend']['version']}")
- workspace_teil = _dateikomponente(vorlage["workspace"]["name"])
- else:
- backend_teil = "unbekannt"
- workspace_teil = "unbekannt"
-
- datum_teil = (iso_build.get("finished_at") or datetime.now(timezone.utc).isoformat())[:10]
- dateiname = f"tuxflotte-{backend_teil}-{workspace_teil}-{datum_teil}.iso"
+ dateiname = _iso_dateiname(vorlage, iso_build)
def stream_datei():
with anode_stream("GET", f"/api/v1/iso-builds/{build_id}/download") as response:
diff --git a/templates/installationsmedium.html b/templates/installationsmedium.html
index 0725a51..361b0bb 100644
--- a/templates/installationsmedium.html
+++ b/templates/installationsmedium.html
@@ -41,7 +41,7 @@
Unter Linux/macOS:
- sudo dd if=tuxflotte-installationsmedium.iso of=/dev/sdX bs=4M status=progress conv=fsync
+ sudo dd if={{ iso_dateiname }} of=/dev/sdX bs=4M status=progress conv=fsync
(/dev/sdX durch den tatsächlichen USB-Stick ersetzen — alle Daten darauf werden überschrieben).