Refactor documentation structure and improve validation checks; update VM state handling and error management.
This commit is contained in:
+14
-2
@@ -7,6 +7,7 @@ import shutil
|
||||
import time
|
||||
from collections.abc import Callable, Sequence
|
||||
from dataclasses import dataclass, replace
|
||||
from ipaddress import IPv4Network
|
||||
from pathlib import Path
|
||||
|
||||
from .config import Settings
|
||||
@@ -99,6 +100,9 @@ class LifecycleService:
|
||||
raise UvmError(message) from error
|
||||
|
||||
def _check_boot(self) -> None:
|
||||
if not any(self._settings.network.subnet_of(IPv4Network(network))
|
||||
for network in ("10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16")):
|
||||
raise ValidationError("private ports require a network inside an RFC 1918 IPv4 range")
|
||||
check_kvm()
|
||||
manifest = load_manifest(self._settings.integrity_manifest_path)
|
||||
checksum = self._settings.firecracker_binary_sha256
|
||||
@@ -258,12 +262,13 @@ class LifecycleService:
|
||||
self._network.firewall.remove(vm)
|
||||
|
||||
def set_ports(self, identifier: str, ports: tuple[PortRule, ...], *, mode: str = "set") -> VmRecord:
|
||||
"""Mutate a frozen registry ID; the CLI resolves names before confirmation."""
|
||||
require_root()
|
||||
ports = self._validated_ports(ports)
|
||||
if mode not in {"open", "close", "set"}:
|
||||
raise ValidationError(f"invalid port operation: {mode}")
|
||||
with self._state_store.operation_lock():
|
||||
vm = self._load_for_operation(identifier)
|
||||
vm = self._load_for_operation(identifier, exact_id=True)
|
||||
self._not_deleting(vm)
|
||||
observation = self._process.observe(vm)
|
||||
if observation == "unknown":
|
||||
@@ -321,7 +326,8 @@ class LifecycleService:
|
||||
containment_errors = []
|
||||
for contain in (
|
||||
lambda: self._network.deactivate_tap(vm),
|
||||
lambda: self._network.firewall.apply(vm, quarantine=True),
|
||||
lambda: (self._network.firewall.apply(vm, quarantine=True)
|
||||
if self._network.has_tap(vm) else None),
|
||||
):
|
||||
try:
|
||||
contain()
|
||||
@@ -457,6 +463,12 @@ class LifecycleService:
|
||||
|
||||
def _reserve_vm(self, spec: VmSpec) -> VmRecord:
|
||||
with self._state_store.transaction() as state:
|
||||
for existing in state.vms.values():
|
||||
if (existing.guest_ip == str(self._settings.gateway)
|
||||
or existing.gateway != str(self._settings.gateway)
|
||||
or existing.network not in {None, str(self._settings.network)}
|
||||
or existing.bridge not in {None, self._settings.bridge}):
|
||||
raise ConflictError("configured topology conflicts with retained VMs; keep their network settings")
|
||||
if spec.name is not None and any(spec.name in {vm.name, vm.id} for vm in state.vms.values()):
|
||||
raise ConflictError(f"VM name already exists: {spec.name}")
|
||||
vm_id = new_vm_id()
|
||||
|
||||
Reference in New Issue
Block a user