216 lines
5.2 KiB
Plaintext
Raw Permalink Normal View History

# VM Host Preparation System
#
# Prepares hosts for VM management by installing necessary hypervisors.
# Supports three modes: explicit, automatic, and auto-detect.
use ./detector.nu *
export def "prepare-host-for-vms" [
host: string # Host identifier ("local" or remote hostname)
--auto-install # Auto-install missing hypervisors
--check-only # Only check, don't modify
]: record {
"""
Prepare a host for virtual machine management.
Detects available hypervisors and optionally installs missing ones.
Examples:
# Check local host capability
prepare-host-for-vms "local" --check-only
# Prepare local host with auto-install
prepare-host-for-vms "local" --auto-install
# Check remote host
prepare-host-for-vms "upcloud-server-01" --check-only
"""
let capabilities = (check-vm-capability $host)
if $check_only {
return $capabilities
}
if not $auto_install {
return $capabilities
}
# Auto-install hypervisors
prepare-host-install $host $capabilities
}
def prepare-host-install [host: string, capabilities: record]: record {
"""Install hypervisors on host"""
let needs_installation = (
($capabilities.primary_backend == "none")
)
if not $needs_installation {
return {
host: $host
status: "ready"
message: $"Host has ($capabilities.primary_backend) hypervisor available"
}
}
print $"Preparing host ($host) for VM support..."
# Determine what to install
let to_install = [
"kvm",
"libvirt",
"qemu",
]
# Install each hypervisor
let results = (
$to_install
| each {|taskserv|
install-hypervisor-taskserv $host $taskserv
}
)
# Check results
let failures = ($results | where success == false)
if ($failures | length) > 0 {
return {
host: $host
status: "partial"
message: $"Installed successfully but ($failures | length) failed"
failed_taskservs: ($failures | each {|x| $x.taskserv})
}
}
{
host: $host
status: "success"
message: "Host prepared successfully for VM management"
installed_taskservs: $to_install
}
}
def install-hypervisor-taskserv [host: string, taskserv: string]: record {
"""Install a hypervisor taskserv on host"""
print $" Installing ($taskserv)..."
let cmd = (
if $host == "local" {
$"provisioning taskserv create ($taskserv)"
} else {
$"provisioning taskserv create ($taskserv) --on-host ($host)"
}
)
let result = (
try {
(shell-exec-safe $cmd)
} catch {|err|
{
taskserv: $taskserv
success: false
error: $err
}
}
)
if ($result | type) == "record" and ("success" in $result) {
return $result
}
{
taskserv: $taskserv
success: true
message: $"Installed successfully"
}
}
def shell-exec-safe [cmd: string]: record {
"""Execute shell command safely"""
let result = (
try {
(bash -c $cmd | complete)
} catch {|err|
error make {msg: $err}
}
)
if $result.exit_code != 0 {
error make {msg: $result.stderr}
}
$result
}
export def "get-host-hypervisor-status" [host: string]: table {
"""Get detailed hypervisor status for a host"""
let capabilities = (check-vm-capability $host)
$capabilities.available_hypervisors
| map {|h|
{
host: $host
hypervisor: $h.name
status: $h.available
description: $h.description
ready: ($h.available == "ready")
}
}
}
export def "list-vm-capable-hosts" []: table {
"""List all hosts that can run VMs"""
# Get local host capability
let local_status = (check-vm-capability "local")
[
{
name: "local"
can_run_vms: $local_status.can_run_vms
primary_hypervisor: $local_status.primary_backend
}
]
# In future, could add remote hosts from infrastructure config
}
export def "ensure-vm-support" [host: string]: record {
"""
Ensure host has VM support, installing if necessary.
Returns success only when VM support is confirmed ready.
"""
let status1 = (check-vm-capability $host)
if $status1.primary_backend != "none" {
return {
host: $host
status: "ready"
message: $"Host already has VM support via ($status1.primary_backend)"
}
}
# Need to install
print $"Host ($host) needs VM hypervisor installation"
let install_result = (prepare-host-install $host $status1)
if $install_result.status != "success" {
return $install_result
}
# Verify installation
let status2 = (check-vm-capability $host)
{
host: $host
status: "ready"
message: $"VM support installed and verified"
primary_hypervisor: $status2.primary_backend
}
}