feat: implement resource resizing for VMs with storage management
- Added KnownHostsManager to handle cleanup of SSH known_hosts entries upon VM deletion. - Introduced disk_size_bytes method in ImageStore to read logical disk capacity. - Enhanced LifecycleService to manage VM resource resizing, including CPU, RAM, and storage. - Updated application configuration to support known_hosts_files for SSH management. - Modified dashboard to include resource resizing options in the UI. - Improved error handling and validation for resource inputs in the dashboard. - Removed obsolete .pyc files from the repository.
This commit is contained in:
+10
-2
@@ -19,6 +19,7 @@ from .firecracker.config import build_config, write_config
|
||||
from .firecracker.process import FirecrackerProcessManager, ProcessInfo
|
||||
from .images import ImageStore
|
||||
from .integrity import load_manifest, verify_file
|
||||
from .known_hosts import KnownHostsManager
|
||||
from .network import NetworkManager
|
||||
from .state import StateStore
|
||||
from .system import check_kvm, ensure_data_directories, require_root
|
||||
@@ -55,6 +56,7 @@ class LifecycleService:
|
||||
def __init__(
|
||||
self, settings: Settings, state_store: StateStore, images: ImageStore,
|
||||
network: NetworkManager, process: FirecrackerProcessManager, *,
|
||||
known_hosts: KnownHostsManager,
|
||||
client_factory: Callable[[Path, float], FirecrackerClient] = FirecrackerClient,
|
||||
clock: Callable[[], float] = time.time,
|
||||
) -> None:
|
||||
@@ -63,6 +65,7 @@ class LifecycleService:
|
||||
self._images = images
|
||||
self._network = network
|
||||
self._process = process
|
||||
self._known_hosts = known_hosts
|
||||
self._client_factory = client_factory
|
||||
self._clock = clock
|
||||
|
||||
@@ -251,7 +254,7 @@ class LifecycleService:
|
||||
previous = vm.pending_resize
|
||||
capacity = previous.storage_mib if previous is not None else vm.storage_mib
|
||||
if capacity is None:
|
||||
capacity = max(MIN_STORAGE_MIB, (Path(vm.disk).stat().st_size + 1024 * 1024 - 1) // (1024 * 1024))
|
||||
capacity = max(MIN_STORAGE_MIB, (self._images.disk_size_bytes(Path(vm.disk)) + 1024 * 1024 - 1) // (1024 * 1024))
|
||||
vm.pending_resize = VmResources(
|
||||
cpu=cpu if cpu is not None else previous.cpu if previous is not None else vm.cpu,
|
||||
ram_mib=ram_mib if ram_mib is not None else previous.ram_mib if previous is not None else vm.ram_mib,
|
||||
@@ -284,7 +287,11 @@ class LifecycleService:
|
||||
return
|
||||
if self._process.observe(vm) != "gone":
|
||||
raise ConflictError("cannot resize a disk without confirmed process exit")
|
||||
if target.storage_mib != vm.storage_mib:
|
||||
# A prior attempt may have published a resized image without saving
|
||||
# its allocation. Check the disk too, including when a retry changes
|
||||
# the target back to the previously recorded capacity.
|
||||
if (target.storage_mib != vm.storage_mib
|
||||
or self._images.disk_size_bytes(Path(vm.disk)) != target.storage_mib * 1024 * 1024):
|
||||
self._images.resize_vm_disk(Path(vm.disk), target.storage_mib)
|
||||
vm.cpu, vm.ram_mib, vm.storage_mib = target.cpu, target.ram_mib, target.storage_mib
|
||||
vm.pending_resize = None
|
||||
@@ -301,6 +308,7 @@ class LifecycleService:
|
||||
try:
|
||||
self._cleanup_runtime(vm, timeout=timeout)
|
||||
self._remove_runtime(vm)
|
||||
self._known_hosts.remove(vm)
|
||||
self._remove_record(vm.id)
|
||||
return vm
|
||||
except BaseException as error:
|
||||
|
||||
Reference in New Issue
Block a user