Jesús Pérez 85ce530733
feat: update provisioning core CLI, libraries, and plugins
Update core components including CLI, Nushell libraries, plugins system,
and utility scripts for the provisioning system.

CLI Updates:
- Command implementations
- CLI utilities and dispatching
- Help system improvements
- Command validation

Library Updates:
- Configuration management system
- Infrastructure validation
- Extension system improvements
- Secrets management
- Workspace operations
- Cache management system

Plugin System:
- Interactive form plugin (inquire)
- KCL integration plugin
- Performance optimization plugins
- Plugin registration system

Utilities:
- Build and distribution scripts
- Installation procedures
- Testing utilities
- Development tools

Documentation:
- Library module documentation
- Extension API guides
- Plugin usage guides
- Service management documentation

All changes are backward compatible. No breaking changes.
2025-12-11 21:57:05 +00:00

249 lines
6.2 KiB
Plaintext

# VM Lifecycle Management
#
# Higher-level VM operations: create, start, stop, delete with state tracking.
# Rule 1: Single purpose, Rule 4: Pure functions, Rule 5: Atomic operations
use ./backend_libvirt.nu *
use ./persistence.nu *
export def "vm-create" [
vm_config: record # VM configuration (from KCL)
--backend: string = "libvirt" # Backend to use
]: record {
"""
Create a virtual machine.
Creates VM disk, defines in hypervisor, and records state.
Examples:
# Create temporary test VM
vm-create {
name: "test-k8s"
cpu: 4
memory_mb: 8192
temporary: true
auto_cleanup: true
}
# Create permanent dev VM
vm-create {
name: "dev-rust"
cpu: 8
memory_mb: 16384
disk_gb: 50
permanent: true
}
"""
# Validation (Rule 3: Early return)
let validation = (validate-vm-config $vm_config)
if not $validation.valid {
return {
success: false
error: $validation.error
}
}
# Create disk
let disk_result = (libvirt-create-disk $vm_config.name $vm_config.disk_gb)
if not $disk_result.success {
return {
success: false
error: $"Disk creation failed: ($disk_result.error)"
}
}
# Define VM in libvirt
let define_result = (libvirt-create-vm $vm_config)
if not $define_result.success {
# Cleanup disk on failure
bash -c $"rm -f ($disk_result.path)"
return $define_result
}
# Record VM state (Rule 5: Atomic operation)
let state_result = (record-vm-creation $vm_config)
if not $state_result.success {
# Try to cleanup on failure
libvirt-delete-vm $vm_config.name | ignore
return $state_result
}
{
success: true
vm_name: $vm_config.name
vm_id: $define_result.vm_id
message: $"VM ($vm_config.name) created successfully"
disk_path: $disk_result.path
}
}
export def "vm-start" [
vm_name: string # VM name
]: record {
"""Start a virtual machine"""
if ($vm_name | is-empty) {
return {success: false, error: "VM name required"}
}
let start_result = (libvirt-start-vm $vm_name)
if not $start_result.success {
return $start_result
}
# Update state
update-vm-state $vm_name "running" | ignore
$start_result
}
export def "vm-stop" [
vm_name: string # VM name
--force = false # Force shutdown
]: record {
"""Stop a virtual machine"""
if ($vm_name | is-empty) {
return {success: false, error: "VM name required"}
}
let stop_result = (libvirt-stop-vm $vm_name --force=$force)
if not $stop_result.success {
return $stop_result
}
# Update state
update-vm-state $vm_name "stopped" | ignore
$stop_result
}
export def "vm-delete" [
vm_name: string # VM name
--force = false # Force deletion
]: record {
"""Delete a virtual machine"""
if ($vm_name | is-empty) {
return {success: false, error: "VM name required"}
}
# Delete from libvirt
let delete_result = (libvirt-delete-vm $vm_name)
if not $delete_result.success {
return $delete_result
}
# Remove state record
remove-vm-state $vm_name | ignore
$delete_result
}
export def "vm-list" [
--permanent = false # List only permanent VMs
--temporary = false # List only temporary VMs
--running = false # List only running VMs
]: table {
"""List virtual machines"""
let all_vms = (libvirt-list-vms)
let vms = (
$all_vms
| each {|vm|
let state = (get-vm-state $vm.name)
{
name: $vm.name
status: $vm.state
permanent: ($state.permanent 2>/dev/null ?? false)
temporary: ($state.temporary 2>/dev/null ?? false)
cpu: ($state.cpu 2>/dev/null ?? "unknown")
memory_mb: ($state.memory_mb 2>/dev/null ?? "unknown")
}
}
)
# Apply filters
let filtered = (
$vms
| if $permanent {
where permanent == true
} else if $temporary {
where temporary == true
} else {
.
}
| if $running {
where status == "running"
} else {
.
}
)
$filtered
}
export def "vm-info" [
vm_name: string # VM name
]: record {
"""Get detailed VM information"""
if ($vm_name | is-empty) {
return {error: "VM name required"}
}
let libvirt_info = (libvirt-get-vm-info $vm_name)
let state_info = (get-vm-state $vm_name)
let ip_address = (libvirt-get-vm-ip $vm_name)
{
name: $vm_name
status: $libvirt_info.state
id: $libvirt_info.id
cpu_cores: $libvirt_info.cpu_cores
memory_mb: $libvirt_info.memory_mb
ip_address: $ip_address
permanent: ($state_info.permanent 2>/dev/null ?? false)
temporary: ($state_info.temporary 2>/dev/null ?? false)
created_at: ($state_info.created_at 2>/dev/null ?? "unknown")
}
}
def validate-vm-config [config: record]: record {
"""Validate VM configuration"""
# Name validation
if ($config.name | is-empty) {
return {valid: false, error: "VM name required"}
}
if not ($config.name | str match '^[a-z0-9][a-z0-9-]*[a-z0-9]$') {
return {
valid: false
error: "Invalid VM name format"
}
}
# Resource validation
if ($config.cpu // 0) <= 0 or ($config.cpu // 0) > 64 {
return {valid: false, error: "CPU must be 1-64"}
}
if ($config.memory_mb // 0) < 512 {
return {valid: false, error: "Memory must be >= 512MB"}
}
if ($config.disk_gb // 0) < 5 {
return {valid: false, error: "Disk must be >= 5GB"}
}
# Lifecycle validation
if ($config.permanent and $config.temporary) {
return {valid: false, error: "Cannot be both permanent and temporary"}
}
{valid: true}
}