# VM Lifecycle Commands (Phase 2) # # User-facing commands for permanent/temporary VM management with cleanup. # Error handling: Result pattern (hybrid, no try-catch) use primitives/result.nu * use platform/vm/ { "register-permanent-vm" "register-temporary-vm" "list-permanent-vms" "list-temporary-vms" "find-expired-vms" "cleanup-expired-vms" "get-vm-uptime" "get-vm-time-to-cleanup" "extend-vm-ttl" "recover-vms-on-boot" "start-cleanup-scheduler" "stop-cleanup-scheduler" "get-cleanup-scheduler-status" "get-cleanup-queue" "create-vm-recovery-script" } export def "vm list-permanent" []: table { """ List all permanent VMs. Permanent VMs persist across reboots and host shutdowns. Examples: provisioning vm list-permanent """ let permanent = (list-permanent-vms) if ($permanent | length) == 0 { print "No permanent VMs registered" return [] } $permanent | map {|vm| { name: $vm.vm_name created: $vm.created_at auto_start: ($vm.auto_start // false) restart_policy: ($vm.restart_policy // "always") } } } export def "vm list-temporary" []: table { """ List all temporary VMs. Temporary VMs are automatically cleaned up after TTL expires. Examples: provisioning vm list-temporary """ let temporary = (list-temporary-vms) if ($temporary | length) == 0 { print "No temporary VMs registered" return [] } $temporary | map {|vm| let time_info = (get-vm-time-to-cleanup $vm.vm_name) { name: $vm.vm_name ttl_hours: $vm.ttl_hours created: $vm.created_at scheduled_cleanup: $vm.scheduled_cleanup_at status: $vm.cleanup_status time_remaining: ($time_info.time_remaining_formatted // "expired") } } } export def "vm make-permanent" [ name: string # VM name --auto-start = true # Auto-start on boot ]: table { """ Convert temporary VM to permanent. Cancels scheduled cleanup and registers for autostart. Examples: provisioning vm make-permanent test-vm """ let result = (register-permanent-vm {name: $name, permanent: true}) if $result.success { print $"✓ VM '($name)' registered as permanent" print $" Auto-start: ($auto_start)" } else { print $"✗ Failed: ($result.error)" } [$result] } export def "vm make-temporary" [ name: string # VM name --ttl-hours: int = 24 # Time to live ]: table { """ Convert permanent VM to temporary. Schedules automatic cleanup after TTL. Examples: provisioning vm make-temporary dev-vm --ttl-hours 48 """ let result = (register-temporary-vm {name: $name, temporary: true} $ttl_hours) if $result.success { print $"✓ VM '($name)' registered as temporary" print $" TTL: ($ttl_hours) hours" print $" Cleanup scheduled at: ($result.cleanup_scheduled_at)" } else { print $"✗ Failed: ($result.error)" } [$result] } export def "vm info-lifecycle" [ name: string # VM name ]: record { """ Get lifecycle information for a VM. Shows persistence mode, uptime, cleanup schedule, etc. Examples: provisioning vm info-lifecycle dev-rust """ # Guard: Input validation if ($name | is-empty) { print "Error: VM name is required" return {} } let uptime = (get-vm-uptime $name) # Guard: Optional cleanup info (may not exist for permanent VMs) # Using optional operator instead of try-catch let time_to_cleanup = (try-wrap { get-vm-time-to-cleanup $name } | unwrap-or {error: "Not a temporary VM"}) { vm_name: $name uptime: $uptime cleanup_info: $time_to_cleanup } } export def "vm cleanup-now" [ --dry-run = false # Simulate without deleting --force = false # Force shutdown before cleanup ]: table { """ Cleanup expired temporary VMs now. Immediately deletes VMs that have exceeded their TTL. Examples: # Dry-run (show what would be deleted) provisioning vm cleanup-now --dry-run # Force cleanup provisioning vm cleanup-now --force """ let result = (cleanup-expired-vms --dry-run=$dry_run --force=$force) if $result.cleaned_up > 0 { print $"✓ Cleaned up ($result.cleaned_up) VMs" } else if $dry_run { print "No VMs pending cleanup" } print $"Total processed: ($result.total_expired)" print $"Successful: ($result.cleaned_up)" print $"Failed: ($result.failed)" $result.details } export def "vm extend-ttl" [ name: string # VM name hours: int # Hours to add ]: table { """ Extend TTL for a temporary VM. Delays cleanup by adding more hours to the original TTL. Examples: provisioning vm extend-ttl test-vm 24 # Add 24 hours provisioning vm extend-ttl test-vm 72 # Add 3 days """ # Guards: Input validation if ($name | is-empty) { print "Error: VM name is required" return [{success: false, error: "VM name is required"}] } if $hours <= 0 { print "Error: Hours must be positive" return [{success: false, error: "Hours must be positive"}] } # Main operation: Use try-wrap to convert exceptions to Result let result = ( use platform/vm/vm_persistence.nu extend-vm-ttl try-wrap { extend-vm-ttl $name $hours } ) # Handle result explicitly if (is-ok $result) { let extended = $result.ok print $"✓ Extended TTL for '($name)' by ($hours) hours" let new_cleanup = (try-wrap { get-vm-time-to-cleanup $name } | unwrap-or {time_remaining_formatted: "unknown"}) print $" New cleanup time: ($new_cleanup.time_remaining_formatted)" [{success: true, error: null} | merge $extended] } else { print $"✗ Failed: ($result.err)" [{success: false, error: $result.err}] } } export def "vm scheduler start" [ --interval-minutes: int = 60 # Check interval ]: table { """ Start automatic cleanup scheduler. Runs in background and periodically cleans up expired VMs. Examples: provisioning vm scheduler start provisioning vm scheduler start --interval-minutes 30 """ let result = (start-cleanup-scheduler --check-interval-minutes=$interval_minutes --background) if $result.success { print $"✓ Cleanup scheduler started (PID: ($result.pid))" print $" Check interval: ($interval_minutes) minutes" } else { print $"✗ Failed: ($result.error)" } [$result] } export def "vm scheduler stop" []: table { """ Stop automatic cleanup scheduler. Examples: provisioning vm scheduler stop """ # Main operation: Use try-wrap to convert exceptions to Result let result = ( use platform/vm/cleanup_scheduler.nu stop-cleanup-scheduler try-wrap { stop-cleanup-scheduler } ) # Handle result explicitly if (is-ok $result) { print $"✓ Cleanup scheduler stopped" [{success: true, error: null}] } else { print $"✗ Failed: ($result.err)" [{success: false, error: $result.err}] } [$result] } export def "vm scheduler status" []: record { """ Check cleanup scheduler status. Examples: provisioning vm scheduler status """ get-cleanup-scheduler-status } export def "vm cleanup-queue" []: table { """ Show VMs pending cleanup. Examples: provisioning vm cleanup-queue """ let queue = (get-cleanup-queue) if ($queue | length) == 0 { print "No VMs pending cleanup" return [] } print $"($queue | length) VMs pending cleanup:" $queue } export def "vm recovery-enable" []: table { """ Enable VM recovery on system reboot. Creates systemd service for automatic VM recovery. Examples: provisioning vm recovery-enable """ let result = (create-vm-recovery-script) if $result.success { print $"✓ VM recovery service created" print $" Script: ($result.script_path)" print $" Service: ($result.service_path)" print " Run 'systemctl status vm-recovery' to check status" } else { print $"✗ Failed: ($result.error)" } [$result] } export def "vm lifecycle-stats" []: record { """ Show VM lifecycle statistics. Examples: provisioning vm lifecycle-stats """ use platform/vm/vm_persistence.nu get-vm-persistence-stats let stats = (get-vm-persistence-stats) print $"Total VMs: ($stats.total_vms)" print $" Permanent: ($stats.permanent_vms)" print $" Temporary: ($stats.temporary_vms)" print $" Expired: ($stats.expired_vms)" print $" Auto-cleanup enabled: ($stats.auto_cleanup_enabled)" $stats }