#!/usr/bin/env nu # Info: Script to run Provisioning Orchestrator Lifecycle Management # Author: JesusPerezLorenzo # Release: 1.0.0 # Date: 29-09-2025 use std log use lib_provisioning * use env.nu * # - > Help on Orchestrator export def "main help" [ --src: string = "" --notitles # not titles --out: string # Print Output format: json, yaml, text (default) ]: nothing -> nothing { print " ╭─────────────────────────────────────────────────────────────╮ │ Orchestrator Lifecycle Management │ ╰─────────────────────────────────────────────────────────────╯ Available Commands: start [--background] [--provisioning-path ] [--port ] Start orchestrator (default: foreground, port 8080) stop Stop orchestrator status [--out json|yaml|text] Check if orchestrator is running health [--out json|yaml|text] Health check via HTTP endpoint migrate --to surrealdb|filesystem --yes [--check] Migrate storage backend logs [--follow] [--lines 50] Show orchestrator logs Examples: provisioning orchestrator start --background provisioning orchestrator status provisioning orchestrator health --out json provisioning orchestrator migrate --to surrealdb --yes provisioning orchestrator logs --follow About: The orchestrator is a high-performance Rust coordination layer that provides: - Task queue management with priority scheduling - REST API for workflow submission and monitoring - Deep call stack limitation resolution - State persistence with multiple backend options - Real-time workflow monitoring and health checks " } # > Orchestrator Lifecycle Management # # The orchestrator is a high-performance Rust coordination layer that provides: # - Task queue management with priority scheduling # - REST API for workflow submission and monitoring # - Deep call stack limitation resolution # - State persistence with multiple backend options # - Real-time workflow monitoring and health checks # # The orchestrator acts as the central coordination hub, receiving workflow # requests and delegating execution to Nushell business logic scripts while # maintaining state and providing monitoring capabilities. def main [ ...args: string # Other options, use help to get info -v # Show version -i # Show Info --version (-V) # Show version with title --info (-I) # Show Info with title --about (-a) # Show About --background (-b) # Run orchestrator in background --provisioning-path: string = "" # Path to provisioning script --port: int = 8080 # HTTP server port --follow (-f) # Follow logs in real-time --lines: int = 50 # Number of log lines to show --to: string # Migration target: surrealdb or filesystem --check (-c) # Only check mode, no actual changes --yes (-y) # Confirm task --debug (-x) # Use Debug mode --xm # Debug with PROVISIONING_METADATA --xld # Log level with DEBUG PROVISIONING_LOG_LEVEL=debug --metadata # Error with metadata (-xm) --notitles # Do not show banner titles --helpinfo (-h) # For more details use options "help" (no dashes) --out: string # Print Output format: json, yaml, text (default) ]: nothing -> nothing { if ($out | is-not-empty) { $env.PROVISIONING_OUT = $out $env.PROVISIONING_NO_TERMINAL = true } provisioning_init $helpinfo "orchestrator" $args if $version or $v { ^$env.PROVISIONING_NAME -v ; exit } if $info or $i { ^$env.PROVISIONING_NAME -i ; exit } if $about { _print (get_about_info) exit } if $debug { $env.PROVISIONING_DEBUG = true } if $metadata { $env.PROVISIONING_METADATA = true } let task = if ($args | length) > 0 { ($args | get 0) } else { "" } $env.PROVISIONING_MODULE = "orchestrator" match $task { "h" | "help" => { # Redirect to main categorized help system exec $"($env.PROVISIONING_NAME)" help orchestration --notitles }, "start" => { print "🚀 Starting orchestrator..." if $background { orchestrator_start --background --provisioning-path $provisioning_path --port $port } else { orchestrator_start --provisioning-path $provisioning_path --port $port } }, "stop" => { print "🛑 Stopping orchestrator..." orchestrator_stop }, "status" => { orchestrator_status --out $out }, "health" => { orchestrator_health --out $out }, "migrate" => { if ($to | is-empty) { print "❌ Migration target required. Use --to surrealdb or --to filesystem" exit 1 } if not $yes { print "⚠️ This will migrate storage backend. Use --yes to confirm." exit 1 } print $"🔄 Migrating storage to ($to)..." if $check { orchestrator_migrate $to --check } else { orchestrator_migrate $to } }, "logs" => { if $follow { orchestrator_logs --follow --lines $lines } else { orchestrator_logs --lines $lines } }, _ => { print $"❌ Unknown task: ($task)" print "Use 'provisioning orchestrator help' for available commands" exit 1 } } } # Start orchestrator def orchestrator_start [ --background --provisioning-path: string --port: int ]: nothing -> nothing { let provisioning_root = $env.PROVISIONING? | default "/usr/local/provisioning" let orchestrator_script = ($provisioning_root | path join "platform" "orchestrator" "scripts" "start-orchestrator.nu") if not ($orchestrator_script | path exists) { print $"❌ Orchestrator start script not found: ($orchestrator_script)" exit 1 } mut flags = ["--port" ($port | into string)] if $background { $flags = ($flags | append ["--background"]) } if ($provisioning_path | is-not-empty) { $flags = ($flags | append ["--provisioning-path" $provisioning_path]) } ^nu $orchestrator_script ...$flags } # Stop orchestrator def orchestrator_stop []: nothing -> nothing { let provisioning_root = $env.PROVISIONING? | default "/usr/local/provisioning" let orchestrator_script = ($provisioning_root | path join "platform" "orchestrator" "scripts" "start-orchestrator.nu") if not ($orchestrator_script | path exists) { print $"❌ Orchestrator start script not found: ($orchestrator_script)" exit 1 } ^nu $orchestrator_script --stop } # Check orchestrator status def orchestrator_status [--out: string]: nothing -> nothing { let provisioning_root = $env.PROVISIONING? | default "/usr/local/provisioning" let orchestrator_script = ($provisioning_root | path join "platform" "orchestrator" "scripts" "start-orchestrator.nu") if not ($orchestrator_script | path exists) { print $"❌ Orchestrator start script not found: ($orchestrator_script)" exit 1 } ^nu $orchestrator_script --check if ($out | is-not-empty) { let health_result = (do { ^curl -s -f "http://localhost:8080/health" } | complete) if $health_result.exit_code == 0 { let health = ($health_result.stdout | from json) if $out == "json" { print ($health | to json) } else if $out == "yaml" { print ($health | to yaml) } else { print ($health | table) } } else { print "Could not retrieve detailed status" } } } # Check orchestrator health via HTTP endpoint def orchestrator_health [--out: string]: nothing -> nothing { let health_result = (do { ^curl -s -f "http://localhost:8080/health" } | complete) if $health_result.exit_code != 0 { print "❌ Orchestrator is not running" print " Start with: provisioning orchestrator start" exit 1 } let health = ($health_result.stdout | from json) if ($health | get success) { print "✅ Orchestrator is healthy" print $"📊 Status: (($health | get data))" if ($out | is-not-empty) { if $out == "json" { print ($health | to json) } else if $out == "yaml" { print ($health | to yaml) } else { print ($health | table) } } } else { print "⚠️ Orchestrator health check failed" if ($out | is-not-empty) { if $out == "json" { print ($health | to json) } else if $out == "yaml" { print ($health | to yaml) } } exit 1 } } # Migrate storage backend def orchestrator_migrate [ target: string --check ]: nothing -> nothing { let provisioning_root = $env.PROVISIONING? | default "/usr/local/provisioning" let migrate_script = ($provisioning_root | path join "platform" "orchestrator" "scripts" "migrate-storage.nu") if not ($migrate_script | path exists) { print $"❌ Migration script not found: ($migrate_script)" exit 1 } match $target { "surrealdb" => { if $check { print "🔍 Checking migration to SurrealDB (dry-run)..." ^nu $migrate_script --from filesystem --to surrealdb-embedded --source-dir "./data" --target-dir "./data-surrealdb" --dry-run } else { print "🔄 Migrating to SurrealDB..." ^nu $migrate_script --from filesystem --to surrealdb-embedded --source-dir "./data" --target-dir "./data-surrealdb" } }, "filesystem" => { if $check { print "🔍 Checking migration to filesystem (dry-run)..." ^nu $migrate_script --from surrealdb-embedded --to filesystem --source-dir "./data-surrealdb" --target-dir "./data" --dry-run } else { print "🔄 Migrating to filesystem..." ^nu $migrate_script --from surrealdb-embedded --to filesystem --source-dir "./data-surrealdb" --target-dir "./data" } }, _ => { print $"❌ Unknown migration target: ($target)" print " Valid targets: surrealdb, filesystem" exit 1 } } } # Show orchestrator logs def orchestrator_logs [ --follow --lines: int ]: nothing -> nothing { let provisioning_root = $env.PROVISIONING? | default "/usr/local/provisioning" let log_file = ($provisioning_root | path join "platform" "orchestrator" "data" "orchestrator.log") if not ($log_file | path exists) { print $"⚠️ Log file not found: ($log_file)" print " Orchestrator may not have been started yet." exit 1 } if $follow { print $"📋 Following orchestrator logs (($log_file))..." print " Press Ctrl+C to stop" ^tail -f $log_file } else { print $"📋 Last ($lines) lines from orchestrator logs:" ^tail -n ($lines | into string) $log_file } }