prvng_core/nulib/provisioning orchestrator
2025-10-07 10:32:04 +01:00

335 lines
11 KiB
Plaintext
Executable File

#!/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 <path>] [--port <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
}
}