# VM State Persistence # # File-based VM state tracking. Stores metadata in JSON files. # Rule 1: Single purpose, Rule 4: Pure functions, Rule 10: Stream large data export def "record-vm-creation" [ vm_config: record # VM configuration ]: record { """Record a new VM in state tracking""" let state_dir = (get-vm-state-dir) bash -c $"mkdir -p ($state_dir)" let state_file = $"($state_dir)/($vm_config.name).json" let state = { name: $vm_config.name state: "stopped" permanent: ($vm_config.permanent // false) temporary: ($vm_config.temporary // false) auto_cleanup: ($vm_config.auto_cleanup // false) auto_cleanup_hours: ($vm_config.auto_cleanup_hours // 24) cpu: $vm_config.cpu memory_mb: $vm_config.memory_mb disk_gb: $vm_config.disk_gb base_image: $vm_config.base_image backend: ($vm_config.backend // "libvirt") taskservs: ($vm_config.taskservs // []) created_at: (date now | date to-record | debug) ip_address: "" mac_address: "" } try { bash -c $"cat > ($state_file) << 'EOF'\n($state | to json)\nEOF" {success: true} } catch {|err| {success: false, error: $err} } } export def "get-vm-state" [ vm_name: string # VM name ]: record { """Get VM state from file""" let state_dir = (get-vm-state-dir) let state_file = $"($state_dir)/($vm_name).json" try { open $state_file | from json } catch { {} } } export def "update-vm-state" [ vm_name: string # VM name new_state: string # New state (running, stopped, etc.) ]: record { """Update VM state""" let current = (get-vm-state $vm_name) if ($current | is-empty) { return {success: false, error: "VM not found"} } let updated = ( $current | upsert state $new_state | upsert last_action (date now | date to-record | debug) ) let state_dir = (get-vm-state-dir) let state_file = $"($state_dir)/($vm_name).json" try { bash -c $"cat > ($state_file) << 'EOF'\n($updated | to json)\nEOF" {success: true} } catch {|err| {success: false, error: $err} } } export def "remove-vm-state" [ vm_name: string # VM name ]: record { """Remove VM from state tracking""" let state_dir = (get-vm-state-dir) let state_file = $"($state_dir)/($vm_name).json" try { bash -c $"rm -f ($state_file)" {success: true} } catch {|err| {success: false, error: $err} } } export def "list-all-vms" []: table { """List all VMs from state tracking""" let state_dir = (get-vm-state-dir) if not ($state_dir | path exists) { return [] } try { bash -c $"ls -1 ($state_dir)/*.json 2>/dev/null" | lines | where {|f| ($f | length) > 0} | map {|f| try { open $f | from json } catch { {} } } | where {|v| ($v | length) > 0} } catch { [] } } def get-vm-state-dir []: string { """Get VM state directory""" $"{{paths.workspace}}/vms/state" } export def "get-vm-stats" []: record { """Get VM statistics""" let all_vms = (list-all-vms) let permanent = ($all_vms | where permanent == true | length) let temporary = ($all_vms | where temporary == true | length) let total = ($all_vms | length) { total_vms: $total permanent_vms: $permanent temporary_vms: $temporary running_vms: ($all_vms | where state == "running" | length) stopped_vms: ($all_vms | where state == "stopped" | length) } } export def "cleanup-temporary-vms" [ --older-than: int = 24 # Hours ]: record { """Cleanup temporary VMs older than specified hours""" let all_vms = (list-all-vms) let now = (date now | date to-record | debug) let to_cleanup = ( $all_vms | filter {|vm| ($vm.temporary // false) and \ ($vm.auto_cleanup // false) } ) let results = ( $to_cleanup | map {|vm| { name: $vm.name result: "skipped" # Placeholder for Phase 2 } } ) { total_checked: ($to_cleanup | length) cleaned_up: 0 skipped: ($to_cleanup | length) results: $results } }