prvng_platform/orchestrator/scripts/start-orchestrator.nu
2025-10-07 10:59:52 +01:00

189 lines
5.9 KiB
Plaintext
Executable File

#!/usr/bin/env nu
# Start the provisioning orchestrator
def main [
--port (-p): int = 8080 # HTTP server port
--data-dir (-d): string = "./data" # Data directory for persistence
--nu-path: string = "nu" # Path to Nushell executable
--provisioning-path: string = "../../core/nulib/provisioning" # Path to provisioning script
--background (-b) # Run in background
--pid-file: string = "./data/orchestrator.pid" # PID file location
--log-file: string = "./data/orchestrator.log" # Log file location
--check # Check if orchestrator is running
--stop # Stop the orchestrator
] {
if $check {
check_orchestrator_status $pid_file
return
}
if $stop {
stop_orchestrator $pid_file
return
}
# Always stop any running orchestrator instances before starting
print "🔍 Checking for existing orchestrator processes..."
let existing_processes = (ps | where name =~ "provisioning-orchestrator" | length)
if $existing_processes > 0 {
print $"🛑 Found ($existing_processes) existing orchestrator processes. Stopping them..."
try {
bash -c 'pkill -f "provisioning-orchestrator" && echo "✅ Existing orchestrator stopped" || echo "⚠️ No orchestrator process found"'
sleep 2sec
} catch {
print "⚠️ Could not stop existing orchestrator processes"
}
} else {
print "✅ No existing orchestrator processes found"
}
# Clean up stale PID file if it exists
if ($pid_file | path exists) {
print "🧹 Removing stale PID file"
rm -f $pid_file
}
let orchestrator_bin = "../target/release/provisioning-orchestrator"
if not ($orchestrator_bin | path exists) {
print "🛑 Orchestrator binary not found. Building..."
cd ..; cargo build --release --bin provisioning-orchestrator; cd orchestrator
if not ($orchestrator_bin | path exists) {
print "❌ Failed to build orchestrator"
exit 1
}
}
if $background {
start_orchestrator_background $orchestrator_bin $port $data_dir $nu_path $provisioning_path $pid_file $log_file
} else {
start_orchestrator_foreground $orchestrator_bin $port $data_dir $nu_path $provisioning_path
}
}
def start_orchestrator_foreground [
bin_path: string
port: int
data_dir: string
nu_path: string
provisioning_path: string
] {
print $"🚀 Starting orchestrator on port ($port)..."
print $"📁 Data directory: ($data_dir)"
print $"🐚 Nushell path: ($nu_path)"
print $"📜 Provisioning script: ($provisioning_path)"
print ""
^$bin_path --port $port --data-dir $data_dir --nu-path $nu_path --provisioning-path $provisioning_path
}
def start_orchestrator_background [
bin_path: string
port: int
data_dir: string
nu_path: string
provisioning_path: string
pid_file: string
log_file: string
] {
# PID file cleanup and process termination already handled in main function
mkdir ($data_dir | path dirname)
mkdir ($log_file | path dirname)
print $"🚀 Starting orchestrator in background..."
print $"📁 Data directory: ($data_dir)"
print $"📄 Log file: ($log_file)"
print $"🆔 PID file: ($pid_file)"
# Start in background and capture PID
let cmd = $"($bin_path) --port ($port) --data-dir '($data_dir)' --nu-path '($nu_path)' --provisioning-path '($provisioning_path)' >> '($log_file)' 2>&1 & echo $!"
let pid = (bash -c $cmd | str trim)
$pid | save $pid_file
sleep 1sec
# Verify it started
if (ps | where pid == ($pid | into int) | length) > 0 {
print $"✅ Orchestrator started successfully with PID ($pid)"
print $"🌐 Health check: http://localhost:($port)/health"
print $"📊 API docs: http://localhost:($port)/tasks"
print ""
print $"To stop: ($env.CURRENT_FILE) --stop"
print $"To check status: ($env.CURRENT_FILE) --check"
print $"To view logs: tail -f ($log_file)"
} else {
print "❌ Failed to start orchestrator"
if ($log_file | path exists) {
print "📋 Last few log lines:"
tail $log_file
}
exit 1
}
}
def stop_orchestrator [pid_file: string] {
if not ($pid_file | path exists) {
print "⚠️ No PID file found - orchestrator may not be running"
return
}
let pid = (open $pid_file | str trim)
if (ps | where pid == ($pid | into int) | length) == 0 {
print $"⚠️ Process with PID ($pid) not found"
rm -f $pid_file
return
}
print $"🛑 Stopping orchestrator (PID: ($pid))..."
try {
kill $pid
sleep 2sec
if (ps | where pid == ($pid | into int) | length) > 0 {
print "🔨 Force killing..."
kill -9 $pid
sleep 1sec
}
rm -f $pid_file
print "✅ Orchestrator stopped successfully"
} catch {
print $"❌ Failed to stop process ($pid)"
exit 1
}
}
def check_orchestrator_status [pid_file: string] {
if not ($pid_file | path exists) {
print "❌ Orchestrator is not running (no PID file)"
return
}
let pid = (open $pid_file | str trim)
if (ps | where pid == ($pid | into int) | length) == 0 {
print $"❌ Orchestrator is not running (PID ($pid) not found)"
rm -f $pid_file
return
}
print $"✅ Orchestrator is running with PID ($pid)"
# Try health check
try {
let health = (http get "http://localhost:8080/health")
if ($health | get success) {
print "🌐 Health check: OK"
print $"📊 Status: (($health | get data))"
} else {
print "⚠️ Health check failed"
}
} catch {
print "⚠️ Could not connect to orchestrator API"
}
}