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

503 lines
13 KiB
Text

# Golden Image CLI Commands (Phase 3)
#
# User-facing commands for building, managing, and using golden images.
use platform/vm/golden_image_builder {
"build-golden-image"
"list-golden-images"
"get-image-info"
"delete-golden-image"
"create-vm-from-golden-image"
"build-image-from-vm"
}
use platform/vm/golden_image_cache {
"cache-initialize"
"cache-add"
"cache-get"
"cache-list"
"cache-cleanup"
"cache-stats"
"version-create"
"version-list"
"version-get"
"version-deprecate"
"version-delete"
"version-rollback"
}
export def "image build" [
name: string # Image name
--base-os: string = "ubuntu" # Base OS
--os-version: string = "22.04" # OS version
--taskservs: list<string> = [] # Taskservs to install
--disk-size: int = 30 # Disk size in GB
--optimize = false # Optimize image
--no-cache = false # Don't cache result
--check = false # Dry-run
]: table {
"""
Build a golden image with pre-installed taskservs.
Creates a disk image with base OS + pre-installed taskservs
for 5x faster VM startup.
Examples:
# Build web server image with Nginx + PostgreSQL
provisioning image build web-server \
--taskservs nginx postgresql redis --disk-size 50
# Build Kubernetes node image
provisioning image build k8s-node \
--taskservs containerd kubernetes cilium --disk-size 100 --optimize
# Dry-run without building
provisioning image build my-image --check
"""
print "🏗️ Building golden image: '$name'"
print " Base OS: $base_os $os_version"
print $" Taskservs: ($taskservs | str join ', ')"
print " Disk size: $($disk_size)GB"
if $check {
print ""
print "✓ Configuration validated"
return []
}
let result = (
build-golden-image $name $base_os $os_version \
--taskservs $taskservs \
--disk-size $disk_size \
--optimize=$optimize \
--cache=(not $no_cache)
)
if $result.success {
print ""
print "✅ Image built successfully"
print $" Job ID: ($result.job_id)"
print $" Path: ($result.image_path)"
print $" Size: ($result.image_size_gb)GB"
print $" Checksum: ($result.checksum)"
} else {
print $"❌ Build failed: ($result.error)"
}
[$result]
}
export def "image list" [
--detailed = false # Show detailed info
]: table {
"""
List all available golden images.
Examples:
provisioning image list
provisioning image list --detailed
"""
let images = (list-golden-images)
if ($images | length) == 0 {
print "No golden images found"
return []
}
print $"Available golden images: ($images | length)"
print ""
$images
}
export def "image info" [
name: string # Image name
]: record {
"""
Get detailed information about a golden image.
Shows size, versions, and usage information.
Examples:
provisioning image info web-server
"""
let info = (get-image-info $name)
if ("error" in $info) {
print $"❌ Error: ($info.error)"
return $info
}
print $"Image: ($info.name)"
print $" Path: ($info.path)"
print $" Size: ($info.size)"
print $" Created: ($info.created_at)"
print $" Checksum: ($info.checksum)"
print $" Versions: ($info.versions)"
print $" VMs using: ($info.vms_using)"
print ""
if ($info.version_list | length) > 0 {
print " Versions:"
$info.version_list | each {|v| print " - $v"}
}
if ($info.vm_list | length) > 0 {
print " Used by VMs:"
$info.vm_list | each {|vm| print " - $vm"}
}
$info
}
export def "image delete" [
name: string # Image name
--force = false # Force delete if in use
]: table {
"""
Delete a golden image.
Checks if image is in use before deletion.
Examples:
provisioning image delete old-image
provisioning image delete old-image --force
"""
let result = (delete-golden-image $name --force=$force)
if $result.success {
print $"✓ Image '($name)' deleted"
} else {
print $"✗ Failed: ($result.error)"
if ("vms_using" in $result) {
print $" VMs using this image: ($result.vms_using | length)"
$result.vms_using | each {|vm| print $" - ($vm)"}
}
}
[$result]
}
export def "vm create-from-image" [
vm_name: string # VM name
image_name: string # Golden image name
--cpu: int = 2 # CPU cores
--memory: int = 4096 # Memory in MB
--disk: int = 0 # Additional disk (0=default)
--permanent = false # Permanent VM
--taskservs: list<string> = [] # Additional taskservs
--check = false # Dry-run
]: table {
"""
Create a VM from a golden image.
Much faster than building VM from scratch (~45s vs 5+ minutes).
Examples:
# Create web server from image
provisioning vm create-from-image web-01 web-server --cpu 4 --memory 8192
# Create Kubernetes node from image
provisioning vm create-from-image k8s-node-01 k8s-node --permanent
# Dry-run
provisioning vm create-from-image test-vm my-image --check
"""
if $check {
print "✓ VM creation validated"
return []
}
print "🚀 Creating VM from golden image..."
print $" VM: ($vm_name)"
print $" Image: ($image_name)"
print " Estimated startup: ~45 seconds"
let result = (
create-vm-from-golden-image $vm_name $image_name \
--cpu=$cpu \
--memory=$memory \
--disk=$disk \
--permanent=$permanent \
--taskservs=$taskservs
)
if $result.success {
print ""
print "✅ VM created successfully"
print $" VM: ($result.vm_name)"
print $" Startup time: ($result.startup_time_seconds)s"
} else {
print $"❌ Failed: ($result.error)"
}
[$result]
}
export def "image from-vm" [
vm_name: string # VM name
image_name: string # New image name
--description: string = "" # Image description
]: table {
"""
Create a golden image from an existing VM.
Useful for creating images from manually configured VMs.
Examples:
provisioning image from-vm web-01 web-server --description "Web server with Nginx and PHP"
"""
print "📸 Creating image from VM..."
print $" VM: ($vm_name)"
print $" Image: ($image_name)"
let result = (build-image-from-vm $vm_name $image_name --description=$description)
if $result.success {
print ""
print "✅ Image created successfully"
print $" Image: ($result.image_name)"
print $" Path: ($result.image_path)"
print $" Checksum: ($result.checksum)"
} else {
print $"❌ Failed: ($result.error)"
}
[$result]
}
export def "cache init" []: record {
"""
Initialize golden image cache system.
Creates cache directories and metadata structures.
"""
print "Initializing cache system..."
let result = (cache-initialize)
if $result.success {
print "✓ Cache initialized"
print $" Directories created: ($result.cache_dirs | length)"
}
$result
}
export def "cache list" [
--include-expired = false # Include expired caches
]: table {
"""
List all cached images.
Examples:
provisioning cache list
provisioning cache list --include-expired
"""
let caches = (cache-list --include-expired=$include_expired)
if ($caches | length) == 0 {
print "No cached images"
return []
}
print $"Cached images: ($caches | length)"
print ""
$caches
}
export def "cache stats" []: record {
"""
Show cache statistics.
Examples:
provisioning cache stats
"""
let stats = (cache-stats)
print "Cache Statistics"
print $" Total images: ($stats.total_cached_images)"
print $" Valid caches: ($stats.valid_caches)"
print $" Expired: ($stats.expired_caches)"
print $" Total size: ($stats.total_size_gb)GB"
print $" Cache hits: ($stats.total_hits)"
print $" Total accesses: ($stats.total_accesses)"
print $" Hit rate: ($stats.hit_rate_percent)%"
print ""
$stats
}
export def "cache cleanup" [
--auto = false # Auto-cleanup expired
--max-size-gb: int = 0 # Max cache size
--min-free-percent: int = 10 # Min free space
]: table {
"""
Cleanup expired or excess cached images.
Examples:
# Auto-cleanup expired
provisioning cache cleanup --auto
# Enforce size limit
provisioning cache cleanup --max-size-gb 500
# Maintain minimum free space
provisioning cache cleanup --min-free-percent 20
"""
print "Cleaning up cache..."
let result = (
cache-cleanup \
--auto=$auto \
--max-size-gb=$max_size_gb \
--min-free-percent=$min_free_percent
)
if $result.success {
print $"✓ Cleaned ($result.cleaned_count) images"
print $" Freed: ($result.cleaned_size_gb)GB"
}
[$result]
}
export def "version create" [
image_name: string # Image name
version: string # Version (e.g., 1.0.0)
image_path: string # Path to image
--description: string = "" # Description
--build-id: string = "" # Build job ID
]: table {
"""
Create a new version of an image.
Examples:
provisioning version create web-server 1.0.0 /path/to/image.qcow2 \
--description "Initial release"
"""
let result = (
version-create $image_name $version $image_path \
--description=$description \
--build-id=$build_id
)
if $result.success {
print $"✓ Version created: ($image_name):($version)"
} else {
print $"✗ Failed: ($result.error)"
}
[$result]
}
export def "version list" [
image_name: string # Image name
]: table {
"""
List all versions of an image.
Examples:
provisioning version list web-server
"""
let versions = (version-list $image_name)
if ($versions | length) == 0 {
print $"No versions found for image '($image_name)'"
return []
}
print $"Versions for '$image_name': ($versions | length)"
print ""
$versions
}
export def "version rollback" [
image_name: string # Image name
from_version: string # Current version
to_version: string # Target version
]: table {
"""
Rollback to a previous image version.
Examples:
provisioning version rollback web-server 1.1.0 1.0.0
"""
let result = (version-rollback $image_name $from_version $to_version)
if $result.success {
print $"✓ Rolled back from ($from_version) to ($to_version)"
} else {
print $"✗ Failed: ($result.error)"
}
[$result]
}
export def "version deprecate" [
image_name: string # Image name
version: string # Version to deprecate
--replacement: string = "" # Replacement version
]: table {
"""
Mark a version as deprecated.
Examples:
provisioning version deprecate web-server 1.0.0 --replacement 1.1.0
"""
let result = (
version-deprecate $image_name $version \
--replacement=$replacement
)
if $result.success {
print $"✓ Version ($version) marked as deprecated"
if ($replacement | is-empty | not) {
print $" Replacement: ($replacement)"
}
} else {
print $"✗ Failed: ($result.error)"
}
[$result]
}
export def "golden-image-stats" []: record {
"""
Show golden image system statistics.
Shows build history, cache status, and performance metrics.
"""
let cache_stats = (cache-stats)
print "Golden Image System Statistics"
print ""
print "Cache Status:"
print $" Total cached images: ($cache_stats.total_cached_images)"
print $" Valid: ($cache_stats.valid_caches)"
print $" Expired: ($cache_stats.expired_caches)"
print $" Total size: ($cache_stats.total_size_gb)GB"
print $" Cache hit rate: ($cache_stats.hit_rate_percent)%"
print ""
{
cache_stats: $cache_stats
}
}