feat: VM-Liste pro Projekt (Desktop-Panel) — Start/Stop/Verbinden
- Brain: project_vms.py (Registry /shared/config/project_vms.json pro Projekt) + Endpoints GET/POST/DELETE /projects/<id>/vms + boot/stop (via SSH aria-wohnung aria-vm auf dem Host; Status aus `aria-vm list`). - ARIA-Tools vm_register/vm_list (aufs Request-Projekt) + Seed-Regel: nach dem VM-Bau registrieren, damit sie in Stefans Desktop-Panel auftaucht. - App: brainApi VM-Methoden + ProjectVm-Typ. Neues DesktopTile — pro Projekt die VM-Liste (leer bis registriert), Start/Stop/Verbinden; Verbinden oeffnet noVNC (VncTile mit dem VNC-Port der VM). Deck rendert DesktopTile statt VncTile. py/tsc clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -37,6 +37,7 @@ import triggers as triggers_mod
|
||||
import watcher as watcher_mod
|
||||
import oauth as oauth_mod
|
||||
import projects as projects_mod
|
||||
import project_vms as project_vms_mod
|
||||
|
||||
BRIDGE_URL = os.environ.get("BRIDGE_URL", "http://aria-bridge:8090")
|
||||
# SearXNG (self-hosted Meta-Suche) — Backend fuers web_search-Tool (B1b).
|
||||
@@ -1161,6 +1162,38 @@ META_TOOLS = [
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "vm_register",
|
||||
"description": (
|
||||
"Traegt eine QEMU-VM in die VM-Liste des AKTUELLEN Projekts ein, "
|
||||
"damit sie in Stefans Desktop-Panel (Cockpit) erscheint und er sie "
|
||||
"starten/stoppen/verbinden kann. Rufe das auf, NACHDEM Du mit aria-vm "
|
||||
"eine VM gebaut/gebootet hast (z.B. bei einem OS-Bau-Projekt). "
|
||||
"vnc_display bestimmt den VNC-Port (Port = 5900+display)."
|
||||
),
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string", "description": "VM-Name wie bei aria-vm (a-z0-9_-)."},
|
||||
"arch": {"type": "string", "description": "z.B. i386, x86_64, aarch64, mips."},
|
||||
"iso": {"type": "string", "description": "optional: Boot-ISO-Pfad auf dem Host."},
|
||||
"vnc_display": {"type": "integer", "description": "VNC-Display (Default 1 → Port 5901)."},
|
||||
"mem": {"type": "integer", "description": "RAM in MB (Default 1024)."},
|
||||
},
|
||||
"required": ["name", "arch"],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "vm_list",
|
||||
"description": "Listet die registrierten QEMU-VMs des aktuellen Projekts (mit Lauf-Status).",
|
||||
"parameters": {"type": "object", "properties": {}},
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -2797,6 +2830,29 @@ class Agent:
|
||||
return f"OK — Projekt '{updated['name']}' ist wieder ein normaler Chat."
|
||||
if name in ("satellite_list", "satellite_devices", "satellite_command"):
|
||||
return self._dispatch_satellite(name, arguments)
|
||||
if name == "vm_register":
|
||||
pid = (project_id or "").strip()
|
||||
if not pid:
|
||||
return "Kein aktives Projekt — VMs werden pro Projekt gefuehrt. Erst ein Projekt betreten."
|
||||
try:
|
||||
vm = project_vms_mod.add_vm(
|
||||
pid, (arguments.get("name") or "").strip(),
|
||||
(arguments.get("arch") or "i386").strip(),
|
||||
(arguments.get("iso") or "").strip(),
|
||||
int(arguments.get("vnc_display") or 1),
|
||||
int(arguments.get("mem") or 1024),
|
||||
)
|
||||
except (ValueError, TypeError) as exc:
|
||||
return f"FEHLER: {exc}"
|
||||
return (f"OK — VM '{vm['name']}' ({vm['arch']}, Display :{vm['vnc_display']}) "
|
||||
f"in Projekt '{pid}' registriert. Erscheint in Stefans Desktop-Panel.")
|
||||
if name == "vm_list":
|
||||
pid = (project_id or "").strip()
|
||||
vms = project_vms_mod.list_vms(pid)
|
||||
if not vms:
|
||||
return f"Projekt '{pid or 'Hauptchat'}' hat noch keine registrierten VMs."
|
||||
return "VMs:\n" + "\n".join(
|
||||
f"- {v['name']} ({v.get('arch')}, Display :{v.get('vnc_display', 1)})" for v in vms)
|
||||
return f"Unbekanntes Tool: {name}"
|
||||
except Exception as exc:
|
||||
logger.exception("Tool '%s' fehlgeschlagen", name)
|
||||
|
||||
Reference in New Issue
Block a user