feat: Add storage management for VM creation and resizing

- Introduced storage parameter in VmCreateRequest and VmResizeRequest models.
- Implemented storage validation to ensure minimum and maximum limits.
- Enhanced CLI to support storage options during VM creation and resizing.
- Updated lifecycle management to handle pending resize operations for VM resources.
- Added methods for resizing VM disks and validating storage capacity.
- Updated API endpoints to accommodate new storage functionality.
- Refactored related validation and configuration logic to support storage management.
This commit is contained in:
2026-09-21 19:16:33 +05:30
parent 781ee753ec
commit fb80ce7c8a
38 changed files with 728 additions and 98 deletions
+23
View File
@@ -13,16 +13,19 @@ from ..api_models import (
VmCreateRequest,
VmLogResponse,
VmResponse,
VmResizeRequest,
vm_response,
)
from ..app import Application
from ..domain import PortRule, VmRecord, VmSpec
from ..errors import ValidationError
from ..validation import (
parse_cpu,
parse_name,
parse_password,
parse_ports,
parse_ram,
parse_storage,
parse_timeout,
parse_username,
)
@@ -71,6 +74,7 @@ def create_vm(
VmSpec(
cpu=parse_cpu(str(request.cpu)),
ram_mib=parse_ram(str(request.ram)),
storage_mib=parse_storage(str(request.storage)),
guest_ip=request.guest_ip,
username=parse_username(request.username),
password=parse_password(request.password.get_secret_value()),
@@ -141,6 +145,25 @@ def stop_vm(
return vm_response(vm, policy_status=_mutation_policy_status(vm))
@router.post("/{vm_id}/resize", response_model=VmResponse)
def resize_vm(
vm_id: str,
request: VmResizeRequest,
timeout: float | None = None,
application: Application = Depends(get_authorized_application),
) -> VmResponse:
if request.cpu is None and request.ram is None and request.storage is None:
raise ValidationError("resize requires at least one of CPU, RAM, or storage")
vm = application.lifecycle.resize(
vm_id,
cpu=parse_cpu(str(request.cpu)) if request.cpu is not None else None,
ram_mib=parse_ram(str(request.ram)) if request.ram is not None else None,
storage_mib=parse_storage(str(request.storage)) if request.storage is not None else None,
timeout=parse_timeout(str(timeout)) if timeout is not None else None,
)
return vm_response(vm, policy_status=_mutation_policy_status(vm))
@router.delete("/{vm_id}", response_model=DestroyResponse)
def destroy_vm(
vm_id: str,