Fred808 commited on
Commit
ae15fcc
·
verified ·
1 Parent(s): ccba896

Update qemu/web_interface.py

Browse files
Files changed (1) hide show
  1. qemu/web_interface.py +125 -125
qemu/web_interface.py CHANGED
@@ -1,125 +1,125 @@
1
- """
2
- Web Interface for QEMU VM
3
- Provides browser-based access to VM display
4
- """
5
-
6
- from fastapi import FastAPI, WebSocket, WebSocketDisconnect
7
- from fastapi.staticfiles import StaticFiles
8
- from fastapi.responses import HTMLResponse
9
- import asyncio
10
- import logging
11
- from pathlib import Path
12
- from typing import Optional, Dict
13
- import json
14
-
15
- from .qemu_manager import QEMUManager
16
-
17
- # Configure logging
18
- logging.basicConfig(level=logging.DEBUG)
19
- logger = logging.getLogger(__name__)
20
-
21
- app = FastAPI()
22
-
23
- # Mount static files
24
- static_path = Path(__file__).parent / "static"
25
- app.mount("/static", StaticFiles(directory=str(static_path)), name="static")
26
-
27
- # Global QEMU manager instance
28
- qemu: Optional[QEMUManager] = None
29
-
30
- class VMConnection:
31
-
32
- # ... rest of the code ...
33
-
34
- def main():
35
- """Entry point for the FServe application"""
36
- import uvicorn
37
- uvicorn.run(app, host="0.0.0.0", port=8080)
38
-
39
- if __name__ == "__main__":
40
- main()
41
- def __init__(self):
42
- self.active_connections: Dict[int, WebSocket] = {}
43
-
44
- async def connect(self, websocket: WebSocket):
45
- await websocket.accept()
46
- client_id = id(websocket)
47
- self.active_connections[client_id] = websocket
48
- return client_id
49
-
50
- def disconnect(self, client_id: int):
51
- self.active_connections.pop(client_id, None)
52
-
53
- async def broadcast(self, message: str):
54
- for ws in self.active_connections.values():
55
- try:
56
- await ws.send_text(message)
57
- except:
58
- continue
59
-
60
- vm_connection = VMConnection()
61
-
62
- @app.get("/")
63
- async def get_index():
64
- """Serve main HTML interface"""
65
- html_path = static_path / "index.html"
66
- return HTMLResponse(content=html_path.read_text())
67
-
68
- @app.websocket("/ws/vm")
69
- async def vm_websocket(websocket: WebSocket):
70
- """Handle VM display and control WebSocket"""
71
- client_id = await vm_connection.connect(websocket)
72
-
73
- try:
74
- while True:
75
- message = await websocket.receive_json()
76
-
77
- if message["type"] == "install":
78
- # Start fresh OS installation
79
- if qemu:
80
- vnc_port = await qemu.install_os(message["iso_url"])
81
- await websocket.send_json({
82
- "type": "vnc_info",
83
- "port": vnc_port
84
- })
85
-
86
- elif message["type"] == "boot":
87
- # Boot existing OS
88
- if qemu:
89
- try:
90
- vnc_port = await qemu.boot_os()
91
- await websocket.send_json({
92
- "type": "vnc_info",
93
- "port": vnc_port
94
- })
95
- except FileNotFoundError:
96
- await websocket.send_json({
97
- "type": "error",
98
- "message": "No OS installation found"
99
- })
100
-
101
- elif message["type"] == "shutdown":
102
- # Shutdown VM
103
- if qemu:
104
- await qemu.shutdown()
105
- await websocket.send_json({
106
- "type": "status",
107
- "message": "VM shut down"
108
- })
109
-
110
- except WebSocketDisconnect:
111
- vm_connection.disconnect(client_id)
112
-
113
- @app.on_event("startup")
114
- async def startup_event():
115
- """Initialize QEMU manager on startup"""
116
- global qemu
117
- qemu = QEMUManager()
118
- logger.info("QEMU manager initialized")
119
-
120
- @app.on_event("shutdown")
121
- async def shutdown_event():
122
- """Cleanup on shutdown"""
123
- if qemu:
124
- await qemu.shutdown()
125
- logger.info("QEMU manager shut down")
 
1
+ """
2
+ Web Interface for QEMU VM
3
+ Provides browser-based access to VM display
4
+ """
5
+
6
+ from fastapi import FastAPI, WebSocket, WebSocketDisconnect
7
+ from fastapi.staticfiles import StaticFiles
8
+ from fastapi.responses import HTMLResponse
9
+ import asyncio
10
+ import logging
11
+ from pathlib import Path
12
+ from typing import Optional, Dict
13
+ import json
14
+
15
+ from .qemu_manager import QEMUManager
16
+
17
+ # Configure logging
18
+ logging.basicConfig(level=logging.DEBUG)
19
+ logger = logging.getLogger(__name__)
20
+
21
+ app = FastAPI()
22
+
23
+ # Mount static files
24
+ static_path = Path(__file__).parent / "static"
25
+ app.mount("/static", StaticFiles(directory=str(static_path)), name="static")
26
+
27
+ # Global QEMU manager instance
28
+ qemu: Optional[QEMUManager] = None
29
+
30
+ class VMConnection:
31
+
32
+ def __init__(self):
33
+ self.active_connections: Dict[int, WebSocket] = {}
34
+
35
+ async def connect(self, websocket: WebSocket):
36
+ await websocket.accept()
37
+ client_id = id(websocket)
38
+ self.active_connections[client_id] = websocket
39
+ return client_id
40
+
41
+ def disconnect(self, client_id: int):
42
+ self.active_connections.pop(client_id, None)
43
+
44
+ async def broadcast(self, message: str):
45
+ for ws in self.active_connections.values():
46
+ try:
47
+ await ws.send_text(message)
48
+ except:
49
+ continue
50
+
51
+ vm_connection = VMConnection()
52
+
53
+ @app.get("/")
54
+ async def get_index():
55
+ """Serve main HTML interface"""
56
+ html_path = static_path / "index.html"
57
+ return HTMLResponse(content=html_path.read_text())
58
+
59
+ @app.websocket("/ws/vm")
60
+ async def vm_websocket(websocket: WebSocket):
61
+ """Handle VM display and control WebSocket"""
62
+ client_id = await vm_connection.connect(websocket)
63
+
64
+ try:
65
+ while True:
66
+ message = await websocket.receive_json()
67
+
68
+ if message["type"] == "install":
69
+ # Start fresh OS installation
70
+ if qemu:
71
+ vnc_port = await qemu.install_os(message["iso_url"])
72
+ await websocket.send_json({
73
+ "type": "vnc_info",
74
+ "port": vnc_port
75
+ })
76
+
77
+ elif message["type"] == "boot":
78
+ # Boot existing OS
79
+ if qemu:
80
+ try:
81
+ vnc_port = await qemu.boot_os()
82
+ await websocket.send_json({
83
+ "type": "vnc_info",
84
+ "port": vnc_port
85
+ })
86
+ except FileNotFoundError:
87
+ await websocket.send_json({
88
+ "type": "error",
89
+ "message": "No OS installation found"
90
+ })
91
+
92
+ elif message["type"] == "shutdown":
93
+ # Shutdown VM
94
+ if qemu:
95
+ await qemu.shutdown()
96
+ await websocket.send_json({
97
+ "type": "status",
98
+ "message": "VM shut down"
99
+ })
100
+
101
+ except WebSocketDisconnect:
102
+ vm_connection.disconnect(client_id)
103
+
104
+ @app.on_event("startup")
105
+ async def startup_event():
106
+ """Initialize QEMU manager on startup"""
107
+ global qemu
108
+ qemu = QEMUManager()
109
+ logger.info("QEMU manager initialized")
110
+
111
+ @app.on_event("shutdown")
112
+ async def shutdown_event():
113
+ """Cleanup on shutdown"""
114
+ if qemu:
115
+ await qemu.shutdown()
116
+ logger.info("QEMU manager shut down")
117
+
118
+
119
+ def main():
120
+ """Entry point for the FServe application"""
121
+ import uvicorn
122
+ uvicorn.run(app, host="0.0.0.0", port=8080)
123
+
124
+ if __name__ == "__main__":
125
+ main()