Files
wehub-resource-sync 91e75e620b
CI: cua-driver distro-compat matrix / debian:12 (glibc 2.36) (push) Has been cancelled
CI: SPDX Headers / Check SPDX headers (warn-only) (push) Has been cancelled
CD: Docs MCP Server / build (linux/amd64) (push) Has been cancelled
CD: Docs MCP Server / build (linux/arm64) (push) Has been cancelled
CD: Docs MCP Server / merge (push) Has been cancelled
CI: cua-driver distro-compat matrix / Resolve release version (push) Has been cancelled
CI: cua-driver distro-compat matrix / fedora:41 (glibc 2.40) (push) Has been cancelled
CI: cua-driver distro-compat matrix / rockylinux:9 (glibc 2.34) (push) Has been cancelled
CI: cua-driver distro-compat matrix / ubuntu:22.04 (glibc 2.35) (push) Has been cancelled
CI: cua-driver distro-compat matrix / ubuntu:24.04 (glibc 2.39) (push) Has been cancelled
CI: cua-driver distro-compat matrix / Distro compat summary (push) Has been cancelled
CI: Rust Linux unit / Rust Linux unit and compile (push) Has been cancelled
CI: Rust Windows unit / Rust Windows unit and compile (push) Has been cancelled
CI: Nix Linux Rust source / Nix / compositor build (push) Has been cancelled
CI: Nix Linux Rust source / Nix / driver package (push) Has been cancelled
CI: Nix Linux Rust source / Nix / Rust unit tests (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:03:19 +08:00

104 lines
4.1 KiB
Python

"""Abstract runtime — starts a VM or container from an Image spec and returns connection info."""
from __future__ import annotations
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from typing import TYPE_CHECKING, Optional
from cua_sandbox.image import Image
if TYPE_CHECKING:
pass
@dataclass
class CheckpointInfo:
"""Metadata for a saved checkpoint / snapshot of a sandbox."""
name: str
runtime_type: str
created_at: float = 0.0
metadata: dict = field(default_factory=dict)
@dataclass
class RuntimeInfo:
"""Connection info returned after a runtime spins up."""
host: str
api_port: int
vnc_port: Optional[int] = None
api_key: Optional[str] = None
container_id: Optional[str] = None
name: Optional[str] = None
qmp_port: Optional[int] = None # Set when QMP transport should be used
environment: Optional[str] = None # OS type hint for QMP transport
agent_type: Optional[str] = None # e.g. "osworld" for OSWorld Flask server
guest_server_port: int = 8000 # Port the guest server listens on
ssh_port: Optional[int] = None # SSH port on the guest
ssh_username: Optional[str] = None
ssh_password: Optional[str] = None
ssh_key_filename: Optional[str] = None
vnc_host: Optional[str] = None # VNC host (if different from host, e.g. localhost for Tart)
vnc_password: Optional[str] = None
grpc_port: Optional[int] = (
None # Set when gRPC transport should be used (emulator gRPC service)
)
class Runtime(ABC):
"""Base class for local runtimes that create VMs/containers from an Image."""
@abstractmethod
async def start(self, image: Image, name: str, **opts) -> RuntimeInfo:
"""Start a VM/container and return connection info."""
@abstractmethod
async def stop(self, name: str) -> None:
"""Stop and clean up a VM/container."""
@abstractmethod
async def is_ready(self, info: RuntimeInfo, timeout: float = 120) -> bool:
"""Wait until the computer-server inside is reachable."""
async def suspend(self, name: str) -> None:
"""Suspend (pause/save state of) a running VM."""
raise NotImplementedError(f"{type(self).__name__} does not support suspend()")
async def resume(self, image: "Image", name: str, **opts) -> RuntimeInfo:
"""Resume a suspended VM and return its RuntimeInfo."""
raise NotImplementedError(f"{type(self).__name__} does not support resume()")
async def list(self) -> list[dict]:
"""List known VMs managed by this runtime.
Returns a list of dicts with at minimum: name, status.
"""
raise NotImplementedError(f"{type(self).__name__} does not support list()")
# ── Checkpoint / fork primitives ─────────────────────────────────────────
async def ensure_base(self, image: "Image", base_name: str) -> CheckpointInfo:
"""Pull/build image into a stopped base sandbox if not already present.
Idempotent. First call does the full pull; subsequent calls return
immediately. The base sandbox is never started — it only serves as a
fork source for ephemeral VMs.
"""
raise NotImplementedError(f"{type(self).__name__} does not support ensure_base()")
async def fork(self, base_name: str, new_name: str, **opts) -> None:
"""Create a new sandbox from a base/checkpoint using CoW where possible."""
raise NotImplementedError(f"{type(self).__name__} does not support fork()")
async def checkpoint(self, name: str, checkpoint_name: str, **opts) -> CheckpointInfo:
"""Capture the current state of a running sandbox as a named checkpoint."""
raise NotImplementedError(f"{type(self).__name__} does not support checkpoint()")
async def list_checkpoints(self) -> list[CheckpointInfo]:
raise NotImplementedError(f"{type(self).__name__} does not support list_checkpoints()")
async def delete_checkpoint(self, checkpoint_name: str) -> None:
raise NotImplementedError(f"{type(self).__name__} does not support delete_checkpoint()")