59 lines
1.9 KiB
Python
59 lines
1.9 KiB
Python
import logging
|
|
from typing import Annotated, Iterator
|
|
from uuid import UUID
|
|
|
|
from fastapi import APIRouter, Body, status
|
|
from fastapi.exceptions import HTTPException
|
|
from fastapi.responses import StreamingResponse
|
|
|
|
from clan_cli.webui.routers.flake import get_attrs
|
|
|
|
from ...task_manager import get_task
|
|
from ...vms import create, inspect
|
|
from ..schemas import VmConfig, VmCreateResponse, VmInspectResponse, VmStatusResponse
|
|
|
|
log = logging.getLogger(__name__)
|
|
router = APIRouter()
|
|
|
|
|
|
@router.post("/api/vms/inspect")
|
|
async def inspect_vm(
|
|
flake_url: Annotated[str, Body()], flake_attr: Annotated[str, Body()]
|
|
) -> VmInspectResponse:
|
|
config = await inspect.inspect_vm(flake_url, flake_attr)
|
|
return VmInspectResponse(config=config)
|
|
|
|
|
|
@router.get("/api/vms/{uuid}/status")
|
|
async def get_vm_status(uuid: UUID) -> VmStatusResponse:
|
|
task = get_task(uuid)
|
|
status: list[int | None] = list(map(lambda x: x.returncode, task.procs))
|
|
log.debug(msg=f"returncodes: {status}. task.finished: {task.finished}")
|
|
return VmStatusResponse(running=not task.finished, returncode=status)
|
|
|
|
|
|
@router.get("/api/vms/{uuid}/logs")
|
|
async def get_vm_logs(uuid: UUID) -> StreamingResponse:
|
|
# Generator function that yields log lines as they are available
|
|
def stream_logs() -> Iterator[str]:
|
|
task = get_task(uuid)
|
|
|
|
yield from task.logs_iter()
|
|
|
|
return StreamingResponse(
|
|
content=stream_logs(),
|
|
media_type="text/plain",
|
|
)
|
|
|
|
|
|
@router.post("/api/vms/create")
|
|
async def create_vm(vm: Annotated[VmConfig, Body()]) -> VmCreateResponse:
|
|
flake_attrs = await get_attrs(vm.flake_url)
|
|
if vm.flake_attr not in flake_attrs:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail=f"Provided attribute '{vm.flake_attr}' does not exist.",
|
|
)
|
|
task = create.create_vm(vm)
|
|
return VmCreateResponse(uuid=str(task.uuid))
|