From b88a934082a42ec5d540ca426f05e0dc47530022 Mon Sep 17 00:00:00 2001 From: Thomas Stallinger Date: Wed, 2 Sep 2026 08:04:40 +0200 Subject: [PATCH] activate: previously_installed-Flag fuer Re-Install-Schutz MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Neue has_completed_installation() prueft device_installation_events auf ein 'installation_completed'-Ereignis - device_created=False allein reicht nicht (ein bekanntes Geraet koennte auch an einem frueheren Commit-Gate abgebrochen sein). Wird jetzt im /api/v1/activate-Antwortobjekt mitgeliefert (.device.previously_installed). Nutzer-Wunsch (02.09.2026): "Was ist eigentlich, wenn der Stick bei einem bereits installierten System erneut ausgeführt wird?" - bisher gar nichts, der Auto-Modus haette die Zielplatte stillschweigend erneut komplett geloescht. tuxflotte-installer liest dieses Feld jetzt in 25_installation_confirm.sh und erzwingt eine echte Rueckfrage, auch im Auto-Modus (siehe dortigen Commit). --- app.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/app.py b/app.py index b9c5d2a..31ba0e2 100644 --- a/app.py +++ b/app.py @@ -1691,6 +1691,28 @@ def fetch_installation_events(device_id: str): for occurred_at, event_type, detail in cur.fetchall() ] +def has_completed_installation(device_id: str) -> bool: + """ + Fuer /api/v1/activate: hat dieses Geraet jemals einen erfolgreichen + Installationsdurchlauf gemeldet (installation_completed, siehe + device_installation_events)? Grundlage fuer den Re-Install-Schutz in + 25_installation_confirm.sh - ein erneut gestecktes Boot-Medium soll die + Zielplatte eines BEREITS fertig installierten Geraets nicht mehr + stillschweigend im Auto-Modus ueberschreiben. + """ + + with get_database_connection() as conn: + with conn.cursor() as cur: + cur.execute( + """ + SELECT 1 FROM device_installation_events + WHERE device_id = %s AND event_type = 'installation_completed' + LIMIT 1 + """, + (device_id,), + ) + return cur.fetchone() is not None + def deprovision_device(device_id: str) -> bool: """ Serverseitiger Entzug (siehe Kundenportal-Geräteaktionen-Plan): macht das @@ -2575,6 +2597,14 @@ def activate(payload: ActivationRequest, request: Request): else "existing" ), "hardware_snapshot_id": hardware_snapshot_id, + # Re-Install-Schutz (02.09.2026, Nutzer-Wunsch nach dem zweiten + # echten Hardware-Test): device_created=False bedeutet nur "das + # Geraet ist schon bekannt", NICHT "es ist schon fertig + # installiert" (koennte auch an einem frueheren Commit-Gate + # abgebrochen sein) - deshalb eigene Pruefung. + "previously_installed": ( + False if device_created else has_completed_installation(device["id"]) + ), }, "customer": {