Unify public UX around pyro CLI and Pyro facade

This commit is contained in:
Thales Maciel 2026-03-07 16:28:28 -03:00
parent d16aadd03f
commit 23a2dfb330
19 changed files with 936 additions and 407 deletions

View file

@ -40,6 +40,7 @@ class VmInstance:
expires_at: float
workdir: Path
state: VmState = "created"
network_requested: bool = False
firecracker_pid: int | None = None
last_error: str | None = None
metadata: dict[str, str] = field(default_factory=dict)
@ -165,7 +166,7 @@ class FirecrackerBackend(VmBackend): # pragma: no cover
rootfs_copy = instance.workdir / "rootfs.ext4"
shutil.copy2(artifacts.rootfs_image, rootfs_copy)
instance.metadata["rootfs_image"] = str(rootfs_copy)
if self._network_manager.enabled:
if instance.network_requested:
network = self._network_manager.allocate(instance.vm_id)
instance.network = network
instance.metadata.update(self._network_manager.to_metadata(network))
@ -342,7 +343,12 @@ class VmManager:
reason="mock backend does not boot a guest",
)
self._max_active_vms = max_active_vms
self._network_manager = network_manager or TapNetworkManager()
if network_manager is not None:
self._network_manager = network_manager
elif self._backend_name == "firecracker":
self._network_manager = TapNetworkManager(enabled=True)
else:
self._network_manager = TapNetworkManager(enabled=False)
self._lock = threading.Lock()
self._instances: dict[str, VmInstance] = {}
self._base_dir.mkdir(parents=True, exist_ok=True)
@ -367,7 +373,13 @@ class VmManager:
return list_profiles()
def create_vm(
self, *, profile: str, vcpu_count: int, mem_mib: int, ttl_seconds: int
self,
*,
profile: str,
vcpu_count: int,
mem_mib: int,
ttl_seconds: int,
network: bool = False,
) -> dict[str, Any]:
self._validate_limits(vcpu_count=vcpu_count, mem_mib=mem_mib, ttl_seconds=ttl_seconds)
get_profile(profile)
@ -389,11 +401,41 @@ class VmManager:
created_at=now,
expires_at=now + ttl_seconds,
workdir=self._base_dir / vm_id,
network_requested=network,
)
self._backend.create(instance)
self._instances[vm_id] = instance
return self._serialize(instance)
def run_vm(
self,
*,
profile: str,
command: str,
vcpu_count: int,
mem_mib: int,
timeout_seconds: int = 30,
ttl_seconds: int = 600,
network: bool = False,
) -> dict[str, Any]:
created = self.create_vm(
profile=profile,
vcpu_count=vcpu_count,
mem_mib=mem_mib,
ttl_seconds=ttl_seconds,
network=network,
)
vm_id = str(created["vm_id"])
try:
self.start_vm(vm_id)
return self.exec_vm(vm_id, command=command, timeout_seconds=timeout_seconds)
except Exception:
try:
self.delete_vm(vm_id, reason="run_vm_error_cleanup")
except ValueError:
pass
raise
def start_vm(self, vm_id: str) -> dict[str, Any]:
with self._lock:
instance = self._get_instance_locked(vm_id)