feat: Implement UVM Dashboard with frontend and backend integration

- Added dashboard.js for frontend functionality, including VM management and system health monitoring.
- Created dashboard route to serve the dashboard HTML.
- Introduced diagnostics route for token-protected host diagnostics.
- Enhanced VMs router with bulk actions, VM log retrieval, and port management.
- Updated lifecycle service to read VM log tails with truncation handling.
- Integrated static file serving for dashboard assets in the FastAPI server.
- Redirect root URL to the dashboard for improved user experience.
This commit is contained in:
2026-09-19 10:50:29 +05:30
parent 3d7af4adb8
commit b3b1b527e1
17 changed files with 2285 additions and 69 deletions
+14 -1
View File
@@ -27,7 +27,8 @@ def create_api(application: Application | None = None, *, host: str | None = Non
try:
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from fastapi.responses import JSONResponse, RedirectResponse
from fastapi.staticfiles import StaticFiles
except ModuleNotFoundError as error:
raise UvmError(
"FastAPI server support is not installed. Install this project with its dependencies."
@@ -36,6 +37,8 @@ def create_api(application: Application | None = None, *, host: str | None = Non
from .routers.health import router as health_router
from .routers.installation import router as installation_router
from .routers.vms import router as vms_router
from .routers.diagnostics import router as diagnostics_router
from .routers.dashboard import router as dashboard_router
api = FastAPI(
title="uvm",
@@ -54,6 +57,16 @@ def create_api(application: Application | None = None, *, host: str | None = Non
api.include_router(health_router)
api.include_router(installation_router)
api.include_router(vms_router)
api.include_router(diagnostics_router)
static_dir = Path(__file__).parent / "dashboard" / "static"
api.mount("/dashboard/static", StaticFiles(directory=static_dir), name="dashboard_static")
api.include_router(dashboard_router, prefix="/dashboard")
@api.get("/")
async def root() -> Any:
return RedirectResponse(url="/dashboard")
return api