provisioning-core/nulib/cli/handlers/vm_lifecycle.nu

373 lines
9.1 KiB
Text
Raw Normal View History

# 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
}