Added many tools
This commit is contained in:
155
tools/qemu.py
155
tools/qemu.py
@@ -0,0 +1,155 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
import subprocess
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from core.tools.base import BaseTool, ToolContext
|
||||
from core.tools.registry import registry
|
||||
from core.safety import safety
|
||||
from core.events import bus
|
||||
|
||||
|
||||
VM_STATE_FILE = Path("./vm_state.json")
|
||||
|
||||
|
||||
class QemuTool(BaseTool):
|
||||
name = "qemu"
|
||||
description = "QEMU VM lifecycle management"
|
||||
|
||||
# -------------------------
|
||||
# EXECUTE ROUTER
|
||||
# -------------------------
|
||||
|
||||
def execute(self, payload: dict[str, Any], ctx: ToolContext):
|
||||
action = str(payload.get("action", "")).strip()
|
||||
|
||||
bus.log(
|
||||
"QEMU",
|
||||
"qemu_execute",
|
||||
"INFO",
|
||||
{"action": action}
|
||||
)
|
||||
|
||||
match action:
|
||||
case "start":
|
||||
return self.start_vm(payload, ctx)
|
||||
|
||||
case "stop":
|
||||
return self.stop_vm(payload, ctx)
|
||||
|
||||
case "status":
|
||||
return self.status(payload)
|
||||
|
||||
case "list":
|
||||
return self.list_vms()
|
||||
|
||||
case _:
|
||||
raise ValueError(f"Unknown qemu action: {action}")
|
||||
|
||||
# -------------------------
|
||||
# STATE HELPERS
|
||||
# -------------------------
|
||||
|
||||
def _load_state(self) -> dict[str, Any]:
|
||||
if VM_STATE_FILE.exists():
|
||||
return json.loads(VM_STATE_FILE.read_text())
|
||||
return {}
|
||||
|
||||
def _save_state(self, state: dict[str, Any]):
|
||||
VM_STATE_FILE.write_text(json.dumps(state, indent=2))
|
||||
|
||||
# -------------------------
|
||||
# START VM
|
||||
# -------------------------
|
||||
|
||||
def start_vm(self, payload: dict[str, Any], ctx: ToolContext):
|
||||
name = payload.get("name")
|
||||
image = payload.get("image")
|
||||
|
||||
if not isinstance(name, str):
|
||||
raise ValueError("name must be string")
|
||||
if not isinstance(image, str):
|
||||
raise ValueError("image must be string")
|
||||
|
||||
image_path = safety.validate_path(image)
|
||||
|
||||
state = self._load_state()
|
||||
|
||||
if name in state and state[name].get("running"):
|
||||
return {"status": "already_running", "name": name}
|
||||
|
||||
cmd = [
|
||||
"qemu-system-x86_64",
|
||||
"-m", "2048",
|
||||
"-drive", f"file={image_path},format=qcow2",
|
||||
"-nographic"
|
||||
]
|
||||
|
||||
process = subprocess.Popen(cmd)
|
||||
|
||||
state[name] = {
|
||||
"pid": process.pid,
|
||||
"image": str(image_path),
|
||||
"running": True
|
||||
}
|
||||
|
||||
self._save_state(state)
|
||||
|
||||
return {
|
||||
"status": "started",
|
||||
"name": name,
|
||||
"pid": process.pid
|
||||
}
|
||||
|
||||
# -------------------------
|
||||
# STOP VM
|
||||
# -------------------------
|
||||
|
||||
def stop_vm(self, payload: dict[str, Any], ctx: ToolContext):
|
||||
name = payload.get("name")
|
||||
|
||||
if not isinstance(name, str):
|
||||
raise ValueError("name must be string")
|
||||
|
||||
state = self._load_state()
|
||||
|
||||
vm = state.get(name)
|
||||
if not vm or not vm.get("running"):
|
||||
return {"status": "not_running", "name": name}
|
||||
|
||||
pid = vm["pid"]
|
||||
|
||||
try:
|
||||
subprocess.run(["kill", str(pid)], check=False)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
vm["running"] = False
|
||||
self._save_state(state)
|
||||
|
||||
return {"status": "stopped", "name": name, "pid": pid}
|
||||
|
||||
# -------------------------
|
||||
# STATUS
|
||||
# -------------------------
|
||||
|
||||
def status(self, payload: dict[str, Any]):
|
||||
name = payload.get("name")
|
||||
|
||||
if not isinstance(name, str):
|
||||
raise ValueError("name must be string")
|
||||
|
||||
state = self._load_state()
|
||||
return state.get(name, {"status": "unknown"})
|
||||
|
||||
# -------------------------
|
||||
# LIST
|
||||
# -------------------------
|
||||
|
||||
def list_vms(self):
|
||||
return self._load_state()
|
||||
|
||||
|
||||
registry.register(QemuTool())
|
||||
Reference in New Issue
Block a user
