Update qemu/web_interface.py
Browse files- qemu/web_interface.py +34 -3
qemu/web_interface.py
CHANGED
|
@@ -13,6 +13,7 @@ from typing import Optional, Dict
|
|
| 13 |
import json
|
| 14 |
import os
|
| 15 |
import sys
|
|
|
|
| 16 |
|
| 17 |
# Add parent directory to path for imports
|
| 18 |
current_dir = Path(__file__).parent
|
|
@@ -34,6 +35,7 @@ app.mount("/static", StaticFiles(directory=str(static_path)), name="static")
|
|
| 34 |
|
| 35 |
# Global QEMU manager instance
|
| 36 |
qemu: Optional[QEMUManager] = None
|
|
|
|
| 37 |
|
| 38 |
class VMConnection:
|
| 39 |
|
|
@@ -58,6 +60,24 @@ class VMConnection:
|
|
| 58 |
|
| 59 |
vm_connection = VMConnection()
|
| 60 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
@app.get("/")
|
| 62 |
async def get_index():
|
| 63 |
"""Serve main HTML interface"""
|
|
@@ -77,9 +97,10 @@ async def vm_websocket(websocket: WebSocket):
|
|
| 77 |
# Start fresh OS installation
|
| 78 |
if qemu:
|
| 79 |
vnc_port = await qemu.install_os(message["iso_url"])
|
|
|
|
| 80 |
await websocket.send_json({
|
| 81 |
"type": "vnc_info",
|
| 82 |
-
"port":
|
| 83 |
})
|
| 84 |
|
| 85 |
elif message["type"] == "boot":
|
|
@@ -87,9 +108,10 @@ async def vm_websocket(websocket: WebSocket):
|
|
| 87 |
if qemu:
|
| 88 |
try:
|
| 89 |
vnc_port = await qemu.boot_os()
|
|
|
|
| 90 |
await websocket.send_json({
|
| 91 |
"type": "vnc_info",
|
| 92 |
-
"port":
|
| 93 |
})
|
| 94 |
except FileNotFoundError:
|
| 95 |
await websocket.send_json({
|
|
@@ -119,9 +141,16 @@ async def startup_event():
|
|
| 119 |
@app.on_event("shutdown")
|
| 120 |
async def shutdown_event():
|
| 121 |
"""Cleanup on shutdown"""
|
|
|
|
|
|
|
| 122 |
if qemu:
|
| 123 |
await qemu.shutdown()
|
| 124 |
logger.info("QEMU manager shut down")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
|
| 126 |
|
| 127 |
def main():
|
|
@@ -130,4 +159,6 @@ def main():
|
|
| 130 |
uvicorn.run(app, host="0.0.0.0", port=8080)
|
| 131 |
|
| 132 |
if __name__ == "__main__":
|
| 133 |
-
main()
|
|
|
|
|
|
|
|
|
| 13 |
import json
|
| 14 |
import os
|
| 15 |
import sys
|
| 16 |
+
import subprocess
|
| 17 |
|
| 18 |
# Add parent directory to path for imports
|
| 19 |
current_dir = Path(__file__).parent
|
|
|
|
| 35 |
|
| 36 |
# Global QEMU manager instance
|
| 37 |
qemu: Optional[QEMUManager] = None
|
| 38 |
+
websockify_process: Optional[subprocess.Popen] = None
|
| 39 |
|
| 40 |
class VMConnection:
|
| 41 |
|
|
|
|
| 60 |
|
| 61 |
vm_connection = VMConnection()
|
| 62 |
|
| 63 |
+
def start_websockify(vnc_port: int, websocket_port: int = 6080):
|
| 64 |
+
"""Start websockify proxy for VNC"""
|
| 65 |
+
global websockify_process
|
| 66 |
+
|
| 67 |
+
if websockify_process:
|
| 68 |
+
websockify_process.terminate()
|
| 69 |
+
websockify_process.wait()
|
| 70 |
+
|
| 71 |
+
cmd = [
|
| 72 |
+
"websockify",
|
| 73 |
+
f"{websocket_port}",
|
| 74 |
+
f"localhost:{vnc_port}"
|
| 75 |
+
]
|
| 76 |
+
|
| 77 |
+
websockify_process = subprocess.Popen(cmd)
|
| 78 |
+
logger.info(f"Started websockify proxy on port {websocket_port} for VNC port {vnc_port}")
|
| 79 |
+
return websocket_port
|
| 80 |
+
|
| 81 |
@app.get("/")
|
| 82 |
async def get_index():
|
| 83 |
"""Serve main HTML interface"""
|
|
|
|
| 97 |
# Start fresh OS installation
|
| 98 |
if qemu:
|
| 99 |
vnc_port = await qemu.install_os(message["iso_url"])
|
| 100 |
+
websocket_port = start_websockify(vnc_port)
|
| 101 |
await websocket.send_json({
|
| 102 |
"type": "vnc_info",
|
| 103 |
+
"port": websocket_port
|
| 104 |
})
|
| 105 |
|
| 106 |
elif message["type"] == "boot":
|
|
|
|
| 108 |
if qemu:
|
| 109 |
try:
|
| 110 |
vnc_port = await qemu.boot_os()
|
| 111 |
+
websocket_port = start_websockify(vnc_port)
|
| 112 |
await websocket.send_json({
|
| 113 |
"type": "vnc_info",
|
| 114 |
+
"port": websocket_port
|
| 115 |
})
|
| 116 |
except FileNotFoundError:
|
| 117 |
await websocket.send_json({
|
|
|
|
| 141 |
@app.on_event("shutdown")
|
| 142 |
async def shutdown_event():
|
| 143 |
"""Cleanup on shutdown"""
|
| 144 |
+
global websockify_process
|
| 145 |
+
|
| 146 |
if qemu:
|
| 147 |
await qemu.shutdown()
|
| 148 |
logger.info("QEMU manager shut down")
|
| 149 |
+
|
| 150 |
+
if websockify_process:
|
| 151 |
+
websockify_process.terminate()
|
| 152 |
+
websockify_process.wait()
|
| 153 |
+
logger.info("Websockify proxy shut down")
|
| 154 |
|
| 155 |
|
| 156 |
def main():
|
|
|
|
| 159 |
uvicorn.run(app, host="0.0.0.0", port=8080)
|
| 160 |
|
| 161 |
if __name__ == "__main__":
|
| 162 |
+
main()
|
| 163 |
+
|
| 164 |
+
|