#!/usr/bin/env nu # provctl-services.nu - Service management utilities for provctl integration # Usage: nu scripts/provisioning/provctl-services.nu [command] [args...] # # Commands: # list [preset] - List services for a preset # deploy [preset] - Deploy services for a preset via provctl # start [service] - Start a service # stop [service] - Stop a service # status [service] - Check service status # validate - Validate service definitions def main [command: string = "list", ...args] { match $command { "list" => { list_services ($args | first) } "deploy" => { deploy_services ($args | first) } "start" => { start_service ($args | first) } "stop" => { stop_service ($args | first) } "status" => { check_service_status ($args | first) } "validate" => { validate_services } _ => { print "Unknown command: $command" print "" print "Available commands:" print " list [preset] - List services for a preset" print " deploy [preset] - Deploy services for a preset via provctl" print " start [service] - Start a service" print " stop [service] - Stop a service" print " status [service] - Check service status" print " validate - Validate service definitions" } } } # List services available for a preset def list_services [preset: string = "local"] { let services = (get_services_for_preset $preset) print $"Services for preset: ($preset)" print "" for service in ($services | from json) { print $" • ($service.name)" if ($service.enabled) { print $" Status: enabled" } else { print $" Status: disabled" } } } # Deploy services for a preset via provctl def deploy_services [preset: string = "local"] { if (check_provctl_available) == false { print "✗ provctl is not available" print "Install provctl from: https://github.com/Akasha/provctl" return } let services = (get_services_for_preset $preset | from json) mut deployed = [] mut failed = [] print $"Deploying services for preset: ($preset)" print "" for service in $services { if ($service.enabled == false) { print $" • ($service.name) - skipped (disabled)" continue } try { let config_path = $"configs/provisioning/services/($service.name).toml" if not ($config_path | path exists) { print $" ✗ ($service.name) - config not found: ($config_path)" $failed = ($failed | append $service.name) continue } # Validate service definition try { provctl validate --config $config_path } catch { print $" ✗ ($service.name) - invalid configuration" $failed = ($failed | append $service.name) continue } # Deploy service try { provctl deploy --config $config_path print $" ✓ ($service.name) - deployed" $deployed = ($deployed | append $service.name) } catch { print $" ✗ ($service.name) - deployment failed" $failed = ($failed | append $service.name) } } catch { print $" ✗ ($service.name) - error" $failed = ($failed | append $service.name) } } print "" print $"Deployment summary:" print $" Deployed: ($deployed | length)" print $" Failed: ($failed | length)" if ($failed | length) > 0 { print "" print "Failed services:" for svc in $failed { print $" • ($svc)" } } } # Start a service def start_service [service: string] { if ($service == null) { print "Please specify a service name" return } if (check_provctl_available) == false { print "✗ provctl is not available" return } print $"Starting service: ($service)" try { provctl start $service print $"✓ ($service) started" } catch { print $"✗ Failed to start ($service)" } } # Stop a service def stop_service [service: string] { if ($service == null) { print "Please specify a service name" return } if (check_provctl_available) == false { print "✗ provctl is not available" return } print $"Stopping service: ($service)" try { provctl stop $service print $"✓ ($service) stopped" } catch { print $"✗ Failed to stop ($service)" } } # Check service status def check_service_status [service: string = null] { if (check_provctl_available) == false { print "✗ provctl is not available" return } if ($service == null) { # Show all services print "Service status:" try { provctl status } catch { print "✗ Failed to get service status" } } else { # Show specific service print $"Checking status of: ($service)" try { provctl status $service } catch { print $"✗ Failed to get status for ($service)" } } } # Validate all service definitions def validate_services [] { print "Validating service definitions..." print "" let service_dir = "configs/provisioning/services" if not ($service_dir | path exists) { print $"✗ Service directory not found: ($service_dir)" return } mut valid = [] mut invalid = [] let service_files = (ls $service_dir --full | where name ends-with .toml) for file in $service_files { let file_name = ($file.name | split row "/" | last) try { if (check_provctl_available) { provctl validate --config $file.name print $" ✓ ($file_name)" $valid = ($valid | append $file_name) } else { # Just check if file is valid TOML open $file.name print $" ✓ ($file_name)" $valid = ($valid | append $file_name) } } catch { print $" ✗ ($file_name) - invalid" $invalid = ($invalid | append $file_name) } } print "" print $"Validation summary:" print $" Valid: ($valid | length)" print $" Invalid: ($invalid | length)" if ($invalid | length) > 0 { print "" print "Invalid services:" for svc in $invalid { print $" • ($svc)" } } } # Get services for a preset from installation.toml def get_services_for_preset [preset: string = "local"]: nothing -> string { let config_path = "configs/installation.toml" if not ($config_path | path exists) { print $"✗ Configuration file not found: ($config_path)" return "[]" } try { let config = (open $config_path) # Extract services from the preset if ($config.preset | get -i $preset | get -i services) != null { let services = ($config.preset | get $preset | get services) # Convert to array format let service_list = [ {name: "surrealdb", enabled: ($services.surrealdb.enabled?)} {name: "nats", enabled: ($services.nats.enabled?)} {name: "syntaxis-api", enabled: ($services.syntaxis_api.enabled?)} {name: "dashboard", enabled: ($services.dashboard.enabled?)} ] ($service_list | to json) } else { print $"✗ Preset not found: ($preset)" "[]" } } catch { print $"✗ Error reading configuration: ($config_path)" "[]" } } # Check if provctl is available def check_provctl_available []: nothing -> bool { try { which provctl 2>/dev/null | null true } catch { false } } # Run main if executed directly if ($nu.invocation-dir == (pwd)) { main ...$nu.env.ARGS }