diff --git a/burst-compute/w44-dispatcher-step4-2026-07-23.md b/burst-compute/w44-dispatcher-step4-2026-07-23.md new file mode 100644 index 0000000..35dfeab --- /dev/null +++ b/burst-compute/w44-dispatcher-step4-2026-07-23.md @@ -0,0 +1,33 @@ +# W44 Burst-Compute: Auto-Burst-Dispatcher, Schritt 4 (2026-07-23) + +**Datei:** `/opt/gpu1-status/app.py`. Default AUS -- Toggle wurde NICHT live scharf geschaltet, Bär bestaetigt Live-Aktivierung separat. + +## Gebaut (Design von Koordinator/Baer 2026-07-23 freigegeben) +- **State:** `/opt/gpu1-status/auto_burst_state.json` (existiert noch nicht -> Defaults greifen: `enabled=False`, `idle_timeout_min=30`, `monster_desired=off`, `shadow_desired=off`) +- **Endpoints (alle auth-gated):** + - `GET /api/burst/dispatcher/status` -- aktueller State + - `POST /api/burst/dispatcher/toggle` -- `{enabled, idle_timeout_min}` setzen (Portal-Toggle in Schritt 5 nutzt das) + - `POST /api/burst/dispatcher/touch` -- Idle-Timer resetten (bei jedem neuen Burst-Job aufzurufen) + - `POST /api/burst/dispatcher/ensure/{monster|shadow}` -- bewusster Boot, setzt `desired=on`, **liefert 409 wenn `enabled=False`** (zusaetzliche Sicherheitsbremse -- kein automatischer Boot ohne aktives Auto-Burst) + - `POST /api/burst/dispatcher/tick` -- die eigentliche Teardown-Entscheidung, optional `{dry_run:true}` + +## Sicherheitsmechanik (mehrfach abgesichert) +1. `real_run = enabled AND NOT dry_run` -- solange `enabled=False` (Default) ist `real_run` IMMER `False`, unabhaengig vom `dry_run`-Parameter -- der Toggle ist die einzige Tuer. +2. **Monster-Ollama-Guard:** `_monster_ollama_busy()` fragt `http://100.120.234.106:11434/api/ps` (Ollama "geladene Modelle"-Liste) ab. Ist die Liste nicht leer -> `skip_ollama_busy`, kein Powerdown, Dispatcher pollt beim naechsten Tick einfach weiter. +3. **GPU-Shadow-Stop nutzt den bestehenden token-sicheren Weg** (`_jump_shadow_call("shadow.php","stop","POST")` -> `monster-api /monster/shadow/stop` -> WinRM-Hibernate im Gast-OS, ruehrt `gpu-token.json` nicht an) -- kein neuer Stop-Mechanismus gebaut, nur der vorhandene wiederverwendet. +4. **desired-Flag-Disziplin:** `monster_desired`/`shadow_desired` werden NUR von `ensure()` auf `"on"` gesetzt (bewusster Dispatcher-Boot) und von `tick()` nach erfolgreichem Teardown wieder auf `"off"`. Der bestehende `gpu-shadow-watchdog.timer` (alle 2min, bootet nach wenn `desired=on`) bleibt dadurch korrekt inaktiv, solange der Dispatcher nichts gebucht hat. +5. **Orchester-Mode-Monster-Wake wird NICHT unterdrueckt** -- dieser Dispatcher greift nur in `monster_desired`/`shadow_desired`-Zustand ein, den ausschliesslich er selbst setzt. Ein Orchester-Start, der Monster ueber `monster-lifecycle.sh amt-start` weckt, aendert diese Dispatcher-eigenen Felder nicht -- keine Kollision, kein Unterdruecken einer fremden, autorisierten Nutzung. + +## Trockentest (echt, ohne echten Powerdown) waehrend GO-Nachricht ausgefuehrt +- `_monster_ollama_busy()`-Logik live gegen Monster getestet: `GET http://100.120.234.106:11434/api/ps` -> `models: []` -> `busy=False` (Ollama-Dienst laeuft, aber aktuell kein Modell geladen -- Guard unterscheidet das korrekt). +- GPU-Shadow-Status live gepruefte Baseline: `vm_online:false`, `desired:"off"`, **`token_valid:true`** (Token unberuehrt, obwohl VM bereits laenger offline ist -- bestaetigt die Entkopplung Token/VM-Power, die die Teardown-Logik voraussetzt). +- Kein echter `tick()`-Realrun ausgefuehrt (haette wegen `enabled=False` ohnehin `real_run=False` erzwungen) -- Entscheidungslogik stattdessen durch Nachvollzug der einzelnen Bausteine (Ollama-Guard, Shadow-Status/Token) gegen die echte Infrastruktur verifiziert. + +## Ablauf (Portal-Skill) +1. Fresh-Read+Backup: `app.py.bak-w44-step4-20260723_183719`, md5 identisch mit Live-Stand +2. Unique-String-Replace (1 Anker, `assert count==1`) +3. `py_compile` OK +4. Testinstanz `:9092`: `/`=200, `/api/burst/dispatcher/status`=401 -- gestoppt +5. `systemctl restart` -- PID-Gegenprobe: alte PID 203542 -> neue PID 207132 (Start 18:39:58, nach Edit), diesmal ohne Gateway-Fehler +6. Live: `:9090/`=200, `:9090/api/burst/dispatcher/status`=401, `cp.go-ki.eu`=200 +7. `auto_burst_state.json` existiert nach diesem Schritt weiterhin NICHT -> Default `enabled=False` aktiv, kein Live-Scharfschalten erfolgt