diff --git a/app/config.py b/app/config.py index 7897db6..6aa6787 100644 --- a/app/config.py +++ b/app/config.py @@ -54,10 +54,10 @@ class Settings: # Storage paths iso_storage_path: str = os.getenv( - "ISO_STORAGE_PATH", "/var/lib/vz/template/iso" + "ISO_STORAGE_PATH", _creds.get("ISO_STORAGE_PATH", "/opt/sovereign-orchestrator/data/isos") ) build_output_path: str = os.getenv( - "BUILD_OUTPUT_PATH", "/tmp/sovereign-orchestrator/builds" + "BUILD_OUTPUT_PATH", _creds.get("BUILD_OUTPUT_PATH", "/opt/sovereign-orchestrator/data/builds") ) # Defaults diff --git a/app/iso_builder.py b/app/iso_builder.py index 8734417..52ab2eb 100644 --- a/app/iso_builder.py +++ b/app/iso_builder.py @@ -220,10 +220,11 @@ async def _run_build(build: BuildStatus) -> None: f"proxmox-auto-install-assistant exited with code {return_code}" ) - build.iso_filename = output_filename + prepared_filename = output_filename.replace(".iso", "-auto-from-iso.iso") + build.iso_filename = prepared_filename build.state = BuildState.COMPLETED - build.log(f"Build completed: {output_filename}") - logger.info("Build %s completed: %s", build.id, output_path) + build.log(f"Build completed: {prepared_filename}") + logger.info("Build %s completed: %s", build.id, work_dir / prepared_filename) except Exception as exc: build.state = BuildState.FAILED diff --git a/app/main.py b/app/main.py index 54b6a5a..cbd0a83 100644 --- a/app/main.py +++ b/app/main.py @@ -292,13 +292,15 @@ async def deploy_vm(config: DeployConfig) -> DeployResult: "cores": config.cores, "memory": config.memory, "ostype": "l26", - "scsihw": "virtio-scsi-single", - "scsi0": f"{config.storage}:{config.disk_size.rstrip('G')},iothread=1", + "sata0": f"{config.storage}:{config.disk_size.rstrip('G')}", + "sata1": f"{config.storage}:1000", + "sata2": f"{config.storage}:1000", "ide2": f"{iso_volid},media=cdrom", - "boot": "order=ide2;scsi0", - "net0": "virtio,bridge=vmbr0", + "boot": f"order=sata0;ide2", + "net0": f"virtio,bridge={config.bridge}", "serial0": "socket", - "vga": "serial0", + "vga": "std", + "tpmstate0": f"{config.storage}:4", } create_upid = await proxmox.create_vm(node, vmid, vm_config) diff --git a/app/models.py b/app/models.py index 4800dc7..9a696cc 100644 --- a/app/models.py +++ b/app/models.py @@ -93,7 +93,7 @@ class DeployConfig(BaseModel): default=8192, ge=512, description="Memory in MiB" ) disk_size: str = Field( - default="64G", description="Root disk size (e.g. 64G)" + default="128G", description="Root disk size (e.g. 128G)" ) build_id: Optional[str] = Field( default=None, @@ -105,6 +105,9 @@ class DeployConfig(BaseModel): iso_storage: str = Field( default="local", description="Proxmox storage containing ISOs" ) + bridge: str = Field( + default="vmbr1", description="Network bridge to attach the VM to" + ) # --------------------------------------------------------------------------- diff --git a/read_console.py b/read_console.py new file mode 100644 index 0000000..0616b17 --- /dev/null +++ b/read_console.py @@ -0,0 +1,75 @@ +import asyncio +import sys +import os +from pathlib import Path + +# Add app directory to sys.path so we can import from app +sys.path.append(str(Path(__file__).parent)) + +from app.config import settings +from app.proxmox_client import proxmox + +async def main(): + node = "dl380-0" + vmid = 900 + if len(sys.argv) > 1: + vmid = int(sys.argv[1]) + if len(sys.argv) > 2: + node = sys.argv[2] + + print(f"Requesting termproxy ticket for VM {vmid} on node {node}...") + try: + res = await proxmox._request("POST", f"/nodes/{node}/qemu/{vmid}/termproxy") + except Exception as e: + print(f"Error requesting termproxy: {e}") + return + + port = res["port"] + ticket = res["ticket"] + user = res["user"] + + import websockets + from urllib.parse import quote + + # Construct ws url + host_clean = settings.proxmox_host.replace("https://", "").replace("http://", "").split("/")[0] + ws_url = f"wss://{host_clean}/api2/json/nodes/{node}/qemu/{vmid}/vncwebsocket?port={port}&vncticket={quote(ticket)}" + + print(f"Connecting to websocket: {ws_url}") + + import ssl + ssl_context = ssl._create_unverified_context() + + # Proxmox websocket protocol requires sending the ticket to authenticate + try: + async with websockets.connect( + ws_url, + ssl=ssl_context, + subprotocols=["binary"] + ) as ws: + # Handshake format: user:ticket\n + handshake = f"{user}:{ticket}\n" + await ws.send(handshake) + print("Handshake sent, reading console stream (Ctrl+C to exit)...") + + # Proxmox termproxy sends data as frame-wrapped or raw binary + while True: + msg = await ws.recv() + if isinstance(msg, bytes): + # Proxmox termproxy data format: 1 byte channel, then data + # Channel 0 is stdout, channel 1 is stderr + if len(msg) > 1: + sys.stdout.buffer.write(msg[1:]) + sys.stdout.buffer.flush() + else: + sys.stdout.write(msg) + sys.stdout.flush() + except KeyboardInterrupt: + print("\nExiting console reader.") + except websockets.exceptions.ConnectionClosed as e: + print(f"\nConnection closed: {e}") + except Exception as e: + print(f"\nError: {e}") + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/setup.sh b/setup.sh index 8a4819f..8f025b4 100644 --- a/setup.sh +++ b/setup.sh @@ -38,10 +38,14 @@ if ! command -v proxmox-auto-install-assistant &>/dev/null; then echo " -> Installing proxmox-auto-install-assistant from Proxmox repos..." # Add Proxmox repository for the assistant tool if [ ! -f /etc/apt/sources.list.d/proxmox.list ]; then - echo "deb [arch=amd64] http://download.proxmox.com/debian/pve trixie pve-no-subscription" \ + CODENAME=$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2 | tr -d '"') + if [ -z "$CODENAME" ]; then + CODENAME="bookworm" + fi + echo "deb [arch=amd64] http://download.proxmox.com/debian/pve $CODENAME pve-no-subscription" \ > /etc/apt/sources.list.d/proxmox.list - wget -qO /etc/apt/trusted.gpg.d/proxmox-release-trixie.gpg \ - http://download.proxmox.com/debian/proxmox-release-trixie.gpg 2>/dev/null || true + wget -qO "/etc/apt/trusted.gpg.d/proxmox-release-$CODENAME.gpg" \ + "http://download.proxmox.com/debian/proxmox-release-$CODENAME.gpg" 2>/dev/null || true apt-get update -qq fi apt-get install -y -qq proxmox-auto-install-assistant 2>/dev/null || { diff --git a/static/index.html b/static/index.html index 6e70d73..c5c14db 100644 --- a/static/index.html +++ b/static/index.html @@ -14,7 +14,7 @@ - + @@ -347,6 +347,6 @@ - +