68 строки
4.8 KiB
Python
68 строки
4.8 KiB
Python
#!/usr/bin/env python3
|
|
from pathlib import Path
|
|
import sys
|
|
|
|
app_path = Path(sys.argv[1]) if len(sys.argv) > 1 else Path('/opt/virtuality/web/app.py')
|
|
if not app_path.exists():
|
|
raise SystemExit(f'app.py not found: {app_path}')
|
|
|
|
text = app_path.read_text()
|
|
changed = []
|
|
|
|
helper = r'''
|
|
|
|
def vm_autostart_status(name: str) -> dict[str, str | bool]:
|
|
result = run_cmd(["virsh", "dominfo", name], timeout=8)
|
|
output = result.get("stdout", "") or ""
|
|
match = re.search(r"^Autostart:\s*(.+)$", output, re.MULTILINE | re.IGNORECASE)
|
|
raw = match.group(1).strip() if match else "unknown"
|
|
enabled = raw.lower() in ("enable", "enabled", "yes", "on")
|
|
label = "enabled" if enabled else "disabled" if raw != "unknown" else "unknown"
|
|
css = "ok" if enabled else "warn"
|
|
return {"enabled": enabled, "label": label, "css": css, "raw": raw}
|
|
'''
|
|
|
|
if 'def vm_autostart_status(' not in text:
|
|
marker = '\n\ndef parse_virsh_list() -> list[dict[str, str]]:'
|
|
if marker not in text:
|
|
raise SystemExit('parse_virsh_list marker not found')
|
|
text = text.replace(marker, helper + marker, 1)
|
|
changed.append('vm_autostart_status helper added')
|
|
else:
|
|
changed.append('vm_autostart_status helper already present')
|
|
|
|
old_rows = ''' if len(parts) == 3:\n rows.append({"id": parts[0], "name": parts[1], "state": parts[2]})\n elif len(parts) == 2:\n rows.append({"id": "-", "name": parts[0], "state": parts[1]})'''
|
|
new_rows = ''' if len(parts) == 3:\n autostart = vm_autostart_status(parts[1])\n rows.append({"id": parts[0], "name": parts[1], "state": parts[2], "autostart_enabled": autostart["enabled"], "autostart_label": autostart["label"], "autostart_css": autostart["css"]})\n elif len(parts) == 2:\n autostart = vm_autostart_status(parts[0])\n rows.append({"id": "-", "name": parts[0], "state": parts[1], "autostart_enabled": autostart["enabled"], "autostart_label": autostart["label"], "autostart_css": autostart["css"]})'''
|
|
if old_rows in text:
|
|
text = text.replace(old_rows, new_rows, 1)
|
|
changed.append('parse_virsh_list enriched with autostart')
|
|
elif 'autostart_enabled' in text and 'autostart_label' in text:
|
|
changed.append('parse_virsh_list already has autostart')
|
|
else:
|
|
raise SystemExit('parse_virsh_list row marker not found')
|
|
|
|
old_details = '''def vm_details(name: str) -> dict[str, Any]:\n return {\n "name": name,\n "dominfo": run_cmd(["virsh", "dominfo", name], timeout=10)["stdout"],\n "vnc": run_cmd(["virsh", "vncdisplay", name], timeout=8)["stdout"] or "not available",\n "ip": vm_ip(name),\n "disks": run_cmd(["virsh", "domblklist", name, "--details"], timeout=10)["stdout"],\n "interfaces": run_cmd(["virsh", "domiflist", name], timeout=10)["stdout"],\n "autostart": run_cmd(["virsh", "dominfo", name], timeout=10)["stdout"],\n }'''
|
|
new_details = '''def vm_details(name: str) -> dict[str, Any]:\n dominfo = run_cmd(["virsh", "dominfo", name], timeout=10)["stdout"]\n autostart = vm_autostart_status(name)\n return {\n "name": name,\n "dominfo": dominfo,\n "vnc": run_cmd(["virsh", "vncdisplay", name], timeout=8)["stdout"] or "not available",\n "ip": vm_ip(name),\n "disks": run_cmd(["virsh", "domblklist", name, "--details"], timeout=10)["stdout"],\n "interfaces": run_cmd(["virsh", "domiflist", name], timeout=10)["stdout"],\n "autostart": dominfo,\n "autostart_enabled": autostart["enabled"],\n "autostart_label": autostart["label"],\n "autostart_css": autostart["css"],\n }'''
|
|
if old_details in text:
|
|
text = text.replace(old_details, new_details, 1)
|
|
changed.append('vm_details enriched with autostart')
|
|
elif '"autostart_enabled": autostart["enabled"]' in text:
|
|
changed.append('vm_details already has autostart')
|
|
else:
|
|
raise SystemExit('vm_details marker not found')
|
|
|
|
old_live = ''' vms.append({"id": vm.get("id", "-"), "name": name, "state": state, "state_css": css, "ip": ip if ip and ip != "not available" else "—"})'''
|
|
new_live = ''' vms.append({"id": vm.get("id", "-"), "name": name, "state": state, "state_css": css, "ip": ip if ip and ip != "not available" else "—", "autostart_enabled": vm.get("autostart_enabled", False), "autostart_label": vm.get("autostart_label", "unknown"), "autostart_css": vm.get("autostart_css", "warn")})'''
|
|
if old_live in text:
|
|
text = text.replace(old_live, new_live, 1)
|
|
changed.append('live status enriched with autostart')
|
|
elif '"autostart_label": vm.get("autostart_label", "unknown")' in text:
|
|
changed.append('live status already has autostart')
|
|
else:
|
|
changed.append('live status marker not found, skipped')
|
|
|
|
app_path.write_text(text)
|
|
print('vm autostart patch applied:')
|
|
for item in changed:
|
|
print(f'- {item}')
|