Hermes-Terminal same-origin + Passwort-Login; Engine/OS-Update-Fixes

Terminals (wie die Box-Konsole):
- hermes-terminal bindet jetzt NUR Loopback (--interface lo --base-path /hermes-terminal)
  und wird von MC2 same-origin durchgereicht (routers/console.py generalisiert auf beide
  ttyd-Instanzen). Kein eigener Firewall-Port mehr noetig.
- Beide Terminals starten die Shell/CLI ueber `su - hitonabi` → fragen beim Oeffnen das
  Box-Passwort ab (PAM gegen das echte Konto, nichts gespeichert). „Login mit sudo-PW".
- agent_status.terminal_url = /hermes-terminal/ (+ reachable via Loopback-Check).

Engine-Update (llama.cpp) — Fix „nicht moeglich":
- update-engine.sh/update-swap.sh sind per sudoers NOPASSWD freigegeben → das fruehere
  `sudo true`-Passwort-Gate hat sie faelschlich blockiert (wenn kein/falsches Box-PW). Gate
  entfernt → Engine-/Router-Update laufen jetzt passwortlos.

OS-Update (apt) — Fix „nicht moeglich":
- DEBIAN_FRONTEND wird jetzt INNERHALB `sudo bash -c '…'` gesetzt statt `sudo VAR=… cmd`
  (sonst lehnt sudos env-Policy die Variable ab und das Upgrade bricht ab).
- Frontend verschluckt password_required/incorrect_password nicht mehr still, sondern zeigt
  einen klaren Hinweis (Box-Passwort in „Box-Zugang" setzen/pruefen).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-07-04 21:18:55 +02:00
parent 00fc7d6d81
commit eff23643e6
11 changed files with 215 additions and 185 deletions
+10 -7
View File
@@ -625,7 +625,10 @@ def os_update_job(sudo_password: str | None = None) -> dict:
if err := check_sudo_needs_password(sudo_password):
return err
# Nach dem apt-Upgrade den Stack funktional prüfen (Job wird rot, wenn etwas kaputt ging).
cmd = ("sudo apt-get update && sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y "
# DEBIAN_FRONTEND wird INNERHALB von `sudo bash -c` gesetzt (nicht als `sudo VAR=… cmd`) —
# sonst lehnt sudos env-Policy die Variable ggf. ab und das Upgrade bricht ab.
cmd = ("sudo apt-get update && "
"sudo bash -c 'DEBIAN_FRONTEND=noninteractive apt-get upgrade -y' "
f"&& bash {STACK_POSTCHECK}")
job_id = jobengine.start_job(["bash", "-c", cmd], "OS-Update (apt)",
group="maintenance", sudo_password=sudo_password)
@@ -637,8 +640,9 @@ def engine_update_job(sudo_password: str | None = None) -> dict | None:
return None
if busy := _maintenance_busy():
return busy
if err := check_sudo_needs_password(sudo_password):
return err
# KEIN sudo-Passwort-Gate: update-engine.sh ist per sudoers NOPASSWD freigegeben
# (sudoers-mc2-autonomie) und läuft passwortlos. Das frühere `sudo true`-Gate hat das
# Update fälschlich blockiert, wenn (noch) kein Box-Passwort hinterlegt war.
def on_done():
_engine_cache.update(ts=0.0, avail=False) # Cache leeren → frischer Build-Vergleich
@@ -648,7 +652,7 @@ def engine_update_job(sudo_password: str | None = None) -> dict | None:
# neuen Build → on_done (Cache leeren) läuft nur dann; bei Rollback (Exit 1/2) bleibt das Badge.
job_id = jobengine.start_job(["bash", "-c", ENGINE_UPDATE_CMD],
"Engine-Update (llama.cpp Vulkan)",
group="maintenance", on_done=on_done, sudo_password=sudo_password)
group="maintenance", on_done=on_done)
return {"ok": True, "job_id": job_id}
@@ -657,8 +661,7 @@ def swap_update_job(sudo_password: str | None = None) -> dict | None:
return None
if busy := _maintenance_busy():
return busy
if err := check_sudo_needs_password(sudo_password):
return err
# KEIN sudo-Passwort-Gate: update-swap.sh ist per sudoers NOPASSWD freigegeben (wie die Engine).
def on_done():
_swap_cache.update(ts=0.0, avail=False) # Cache leeren → frischer Versions-Vergleich
@@ -668,7 +671,7 @@ def swap_update_job(sudo_password: str | None = None) -> dict | None:
# Version → on_done (Cache leeren) läuft nur dann; bei Rollback (Exit 1/2) bleibt das Badge.
job_id = jobengine.start_job(["bash", "-c", SWAP_UPDATE_CMD],
"Router-Update (llama-swap)",
group="maintenance", on_done=on_done, sudo_password=sudo_password)
group="maintenance", on_done=on_done)
return {"ok": True, "job_id": job_id}