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:
@@ -11,7 +11,8 @@ import re
|
||||
import httpx
|
||||
import psutil
|
||||
|
||||
from config import HERMES_TERMINAL_URL, BOX_CONSOLE_UPSTREAM, BOX_CONSOLE_PATH, HERMES_API_URL, HERMES_HOME, PC_EXECUTOR_URL
|
||||
from config import (HERMES_TERMINAL_UPSTREAM, HERMES_TERMINAL_PATH, BOX_CONSOLE_UPSTREAM,
|
||||
BOX_CONSOLE_PATH, HERMES_API_URL, HERMES_HOME, PC_EXECUTOR_URL)
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -139,13 +140,13 @@ def agent_status() -> dict:
|
||||
|
||||
return {
|
||||
"gateway_url": HERMES_API_URL,
|
||||
# Interaktives Web-Terminal (ttyd → `hermes chat`), eingebettet in MC2.
|
||||
"terminal_url": HERMES_TERMINAL_URL,
|
||||
# Interaktives Web-Terminal (ttyd → `hermes chat`): same-origin über MC2 geproxyt.
|
||||
"terminal_url": HERMES_TERMINAL_PATH,
|
||||
# Box-Konsole (ttyd → Login-Shell): same-origin über MC2 geproxyt (/console/).
|
||||
"box_console_url": BOX_CONSOLE_PATH,
|
||||
"gateway_reachable": _reach(HERMES_API_URL, "/health"),
|
||||
"terminal_reachable": _reach(HERMES_TERMINAL_URL, "/"),
|
||||
# Erreichbarkeit des lokalen ttyd-Upstreams (Loopback, base-path /console).
|
||||
# Erreichbarkeit der lokalen ttyd-Upstreams (Loopback, je base-path).
|
||||
"terminal_reachable": _reach(HERMES_TERMINAL_UPSTREAM, "/hermes-terminal/"),
|
||||
"box_console_reachable": _reach(BOX_CONSOLE_UPSTREAM, "/console/"),
|
||||
"home_exists": home.exists(),
|
||||
"brain_model": brain_model,
|
||||
|
||||
@@ -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}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user