Feat: System-Wartung-Rework + Hermes-Update-Button

Wartungs-Tab im SystemDrawer neu strukturiert:
- UPDATES: eine einheitliche Liste (OS, Engine, Hermes-Agent, Modell-Upgrades) mit
  Status + Aktion-Button, der nur aktiv ist wenn ein Update ansteht (statt Klick-Karten,
  die sofort updaten). Konsistent mit der Dashboard-UpdatesCard.
- DIENSTE: neue Sektion, alle systemd-Units mit Status-Punkt (aus /api/system/services,
  jetzt inkl. mem0-service) + Restart + Logs-Sprung.
- BACKUP: kompakt (letztes Backup + Snapshot-Button + Restore-Hinweis).
- GEFAHRENZONE: Reboot abgetrennt. Jobs nur wenn vorhanden.

Hermes-Update-Button: POST /api/maintenance/hermes-update -> Job (Backup -> `hermes update
--yes` (git pull + deps) -> hermes-gateway restart). Backend: hermes_update_job + USER_SERVICES
um mem0-service/hermes-terminal ergaenzt (Restart ging vorher nicht), mem0 in services-API.

Live verifiziert: Button hat Hermes d470ed0 -> 3b44a3c aktualisiert, Integration intakt
(memory.provider, Plugin laedt), Pre-Update-Backup angelegt, Drawer rendert fehlerfrei.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-06-27 21:59:04 +02:00
parent b38e3360c5
commit 58dda66f84
10 changed files with 681 additions and 611 deletions
+11 -1
View File
@@ -12,7 +12,9 @@ import subprocess
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from config import GATEWAY_URL, HERMES_API_URL, LLAMA_SWAP_URL
import httpx
from config import GATEWAY_URL, HERMES_API_URL, LLAMA_SWAP_URL, MEM0_SERVICE_URL
from services import backup as backup_svc
from services.agent import agent_status
from services.gateway import gateway_reachable
@@ -36,6 +38,13 @@ def status() -> dict:
return system_status()
def _mem0_reachable() -> bool:
try:
return httpx.get(f"{MEM0_SERVICE_URL}/health", timeout=2).status_code == 200
except Exception:
return False
@router.get("/system/services")
def services() -> dict:
"""Aggregierte Erreichbarkeit aller Stack-Dienste (für die Health-Anzeige)."""
@@ -47,6 +56,7 @@ def services() -> dict:
{"name": "Gateway (integriert)", "url": gw_url, "ok": gateway_reachable()},
{"name": "Hermes-Gateway", "url": HERMES_API_URL, "ok": a["gateway_reachable"]},
{"name": "Hermes-Terminal", "url": a["terminal_url"], "ok": a["terminal_reachable"]},
{"name": "Mem0 (Gedächtnis)", "url": MEM0_SERVICE_URL, "ok": _mem0_reachable()},
],
"links": {
"engine_ui": f"{LLAMA_SWAP_URL}/ui",