422 lines
11 KiB
Plaintext
422 lines
11 KiB
Plaintext
#!/usr/bin/env nu
|
|
|
|
# Service CLI Commands
|
|
# User-facing commands for service management
|
|
|
|
use manager.nu *
|
|
use health.nu *
|
|
use preflight.nu *
|
|
use dependencies.nu *
|
|
|
|
# Platform management commands (manage all services)
|
|
|
|
# Start platform services
|
|
export def "platform start" [
|
|
...services: string # Specific services to start (empty = all auto-start)
|
|
] {
|
|
init-service-state
|
|
|
|
if ($services | is-empty) {
|
|
# Start all auto-start services
|
|
let registry = (load-service-registry)
|
|
|
|
let auto_start_services = (
|
|
$registry
|
|
| transpose name config
|
|
| where { |row| $row.config.startup.auto_start }
|
|
| get name
|
|
)
|
|
|
|
if ($auto_start_services | is-empty) {
|
|
print "No services configured for auto-start"
|
|
return
|
|
}
|
|
|
|
print $"Starting auto-start services: ($auto_start_services | str join ', ')"
|
|
|
|
let result = (start-services-with-deps $auto_start_services)
|
|
|
|
if $result.success {
|
|
print $"\n✅ Platform started successfully"
|
|
print $"Started ($result.started | length) services: ($result.started | str join ', ')"
|
|
} else {
|
|
print $"\n❌ Platform start failed"
|
|
print $"Failed at: ($result.failed | str join ', ')"
|
|
}
|
|
} else {
|
|
# Start specific services
|
|
let result = (start-services-with-deps $services)
|
|
|
|
if $result.success {
|
|
print $"\n✅ Services started successfully"
|
|
print $"Started: ($result.started | str join ', ')"
|
|
} else {
|
|
print $"\n❌ Failed to start services"
|
|
print $"Failed at: ($result.failed | str join ', ')"
|
|
}
|
|
}
|
|
}
|
|
|
|
# Stop platform services
|
|
export def "platform stop" [
|
|
...services: string # Specific services to stop (empty = all running)
|
|
] {
|
|
if ($services | is-empty) {
|
|
# Stop all running services
|
|
let running = (list-running-services | get name)
|
|
|
|
if ($running | is-empty) {
|
|
print "No services are running"
|
|
return
|
|
}
|
|
|
|
print $"Stopping all running services: ($running | str join ', ')"
|
|
|
|
# Stop in reverse dependency order
|
|
let startup_order = (get-startup-order $running)
|
|
let stop_order = ($startup_order | reverse)
|
|
|
|
for service in $stop_order {
|
|
print $"Stopping ($service)..."
|
|
stop-service $service --force
|
|
}
|
|
|
|
print "\n✅ Platform stopped"
|
|
} else {
|
|
# Stop specific services
|
|
for service in $services {
|
|
let can_stop = (can-stop-service $service)
|
|
|
|
if not $can_stop.can_stop {
|
|
print $"⚠️ Warning: ($service) has running dependents:"
|
|
print ($can_stop.running_dependents | to text)
|
|
print "Use --force to stop anyway (may break dependent services)"
|
|
continue
|
|
}
|
|
|
|
stop-service $service
|
|
}
|
|
}
|
|
}
|
|
|
|
# Restart platform services
|
|
export def "platform restart" [
|
|
...services: string # Specific services to restart (empty = all running)
|
|
] {
|
|
if ($services | is-empty) {
|
|
let running = (list-running-services | get name)
|
|
|
|
if ($running | is-empty) {
|
|
print "No services are running"
|
|
return
|
|
}
|
|
|
|
print "Restarting all running services..."
|
|
|
|
for service in $running {
|
|
restart-service $service
|
|
}
|
|
} else {
|
|
for service in $services {
|
|
restart-service $service
|
|
}
|
|
}
|
|
}
|
|
|
|
# Show platform status
|
|
export def "platform status" [] {
|
|
let all_services = (list-all-services)
|
|
|
|
print "Platform Services Status\n"
|
|
|
|
let running = ($all_services | where status == "running")
|
|
let stopped = ($all_services | where status == "stopped")
|
|
|
|
print $"Running: ($running | length)/($all_services | length)"
|
|
print ""
|
|
|
|
# Group by category
|
|
let categories = ($all_services | get category | uniq)
|
|
|
|
for category in $categories {
|
|
let category_services = ($all_services | where category == $category)
|
|
|
|
print $"=== ($category | str upcase) ==="
|
|
|
|
for service in $category_services {
|
|
let status_icon = if $service.status == "running" { "🟢" } else { "⚪" }
|
|
let health_icon = match $service.health_status {
|
|
"healthy" => "✅"
|
|
"unhealthy" => "❌"
|
|
_ => "❓"
|
|
}
|
|
|
|
let uptime = if $service.uptime > 0 {
|
|
$" \(uptime: ($service.uptime)s\)"
|
|
} else {
|
|
""
|
|
}
|
|
|
|
print $" ($status_icon) ($service.name) - ($service.status)($uptime) ($health_icon)"
|
|
}
|
|
|
|
print ""
|
|
}
|
|
}
|
|
|
|
# Show platform logs
|
|
export def "platform logs" [
|
|
service: string # Service name
|
|
--lines: int = 50 # Number of lines
|
|
--follow (-f) # Follow logs
|
|
] {
|
|
get-service-logs $service --lines $lines --follow=$follow
|
|
}
|
|
|
|
# Check platform health
|
|
export def "platform health" [] {
|
|
let all_services = (list-all-services)
|
|
|
|
print "Platform Health Check\n"
|
|
|
|
let mut healthy = 0
|
|
let mut unhealthy = 0
|
|
let mut unknown = 0
|
|
|
|
for service in $all_services {
|
|
if $service.status != "running" {
|
|
print $"⚪ ($service.name): Not running"
|
|
$unknown = $unknown + 1
|
|
continue
|
|
}
|
|
|
|
let health = (get-health-status $service.name)
|
|
|
|
if $health.healthy {
|
|
print $"✅ ($service.name): Healthy - ($health.message)"
|
|
$healthy = $healthy + 1
|
|
} else {
|
|
print $"❌ ($service.name): Unhealthy - ($health.message)"
|
|
$unhealthy = $unhealthy + 1
|
|
}
|
|
}
|
|
|
|
print $"\nSummary: ($healthy) healthy, ($unhealthy) unhealthy, ($unknown) not running"
|
|
}
|
|
|
|
# Update platform services
|
|
export def "platform update" [] {
|
|
print "Platform update functionality not yet implemented"
|
|
print "This would update all platform service binaries/images"
|
|
}
|
|
|
|
# Service-specific commands
|
|
|
|
# List services
|
|
export def "services list" [
|
|
--running (-r) # Show only running services
|
|
--category: string # Filter by category
|
|
] {
|
|
let all_services = (list-all-services)
|
|
|
|
let filtered = if $running {
|
|
$all_services | where status == "running"
|
|
} else if ($category | is-not-empty) {
|
|
$all_services | where category == $category
|
|
} else {
|
|
$all_services
|
|
}
|
|
|
|
$filtered | select name type category status deployment_mode auto_start
|
|
}
|
|
|
|
# Show service status
|
|
export def "services status" [
|
|
service: string
|
|
] {
|
|
let status = (get-service-status $service)
|
|
|
|
print $"Service: ($service)"
|
|
print $"Type: ($status.type)"
|
|
print $"Category: ($status.category)"
|
|
print $"Status: ($status.status)"
|
|
print $"Deployment: ($status.deployment_mode)"
|
|
print $"Health: ($status.health_status)"
|
|
print $"Auto-start: ($status.auto_start)"
|
|
|
|
if $status.pid > 0 {
|
|
print $"PID: ($status.pid)"
|
|
}
|
|
|
|
if $status.uptime > 0 {
|
|
print $"Uptime: ($status.uptime)s"
|
|
}
|
|
|
|
if not ($status.dependencies | is-empty) {
|
|
print $"Dependencies: ($status.dependencies | str join ', ')"
|
|
}
|
|
}
|
|
|
|
# Start service
|
|
export def "services start" [
|
|
service: string
|
|
--force (-f)
|
|
] {
|
|
# Run pre-flight checks
|
|
let preflight = (preflight-start-service $service)
|
|
|
|
if not $preflight.can_start {
|
|
print $"❌ Pre-flight check failed: ($preflight.reason)"
|
|
print ($preflight.details | to yaml)
|
|
return
|
|
}
|
|
|
|
if $force {
|
|
start-service $service --force
|
|
} else {
|
|
start-service $service
|
|
}
|
|
}
|
|
|
|
# Stop service
|
|
export def "services stop" [
|
|
service: string
|
|
--force (-f)
|
|
] {
|
|
let can_stop = (can-stop-service $service)
|
|
|
|
if not $can_stop.can_stop and not $force {
|
|
print $"❌ Cannot stop ($service):"
|
|
print $" Dependent services running: ($can_stop.running_dependents | str join ', ')"
|
|
print " Use --force to stop anyway"
|
|
return
|
|
}
|
|
|
|
stop-service $service --force=$force
|
|
}
|
|
|
|
# Restart service
|
|
export def "services restart" [
|
|
service: string
|
|
] {
|
|
restart-service $service
|
|
}
|
|
|
|
# Check service health
|
|
export def "services health" [
|
|
service: string
|
|
] {
|
|
let health = (get-health-status $service)
|
|
|
|
print $"Service: ($service)"
|
|
print $"Status: ($health.status)"
|
|
print $"Healthy: ($health.healthy)"
|
|
print $"Message: ($health.message)"
|
|
|
|
if "check_type" in $health {
|
|
print $"Check type: ($health.check_type)"
|
|
}
|
|
|
|
if "duration_ms" in $health {
|
|
print $"Check duration: ($health.duration_ms)ms"
|
|
}
|
|
}
|
|
|
|
# Show service logs
|
|
export def "services logs" [
|
|
service: string
|
|
--follow (-f)
|
|
--lines: int = 50
|
|
] {
|
|
get-service-logs $service --lines $lines --follow=$follow
|
|
}
|
|
|
|
# Check required services for operation
|
|
export def "services check" [
|
|
operation: string
|
|
] {
|
|
let check = (check-required-services $operation)
|
|
|
|
print $"Operation: ($operation)"
|
|
print $"Required services: ($check.required_services | str join ', ')"
|
|
print $"All running: ($check.all_running)"
|
|
|
|
if not $check.all_running {
|
|
print $"\nMissing services: ($check.missing_services | str join ', ')"
|
|
print $"Can auto-start: ($check.can_auto_start)"
|
|
}
|
|
}
|
|
|
|
# Show dependency graph
|
|
export def "services dependencies" [
|
|
service?: string # Specific service (empty = show all)
|
|
] {
|
|
if ($service | is-empty) {
|
|
let graph = (visualize-dependency-graph)
|
|
print $graph
|
|
} else {
|
|
let tree = (get-dependency-tree $service)
|
|
print ($tree | to yaml)
|
|
}
|
|
}
|
|
|
|
# Validate all services
|
|
export def "services validate" [] {
|
|
let validation = (validate-all-services)
|
|
|
|
print $"Total services: ($validation.total_services)"
|
|
print $"Valid: ($validation.valid_services)"
|
|
print $"Invalid: ($validation.invalid_services)"
|
|
print ""
|
|
|
|
let invalid = ($validation.results | where { |r| not $r.valid })
|
|
|
|
if not ($invalid | is-empty) {
|
|
print "Invalid services:"
|
|
for result in $invalid {
|
|
print $" ❌ ($result.service):"
|
|
for issue in $result.issues {
|
|
print $" - ($issue)"
|
|
}
|
|
}
|
|
} else {
|
|
print "✅ All services have valid configurations"
|
|
}
|
|
}
|
|
|
|
# Get readiness report
|
|
export def "services readiness" [] {
|
|
let report = (get-readiness-report)
|
|
|
|
print $"Platform Readiness Report\n"
|
|
print $"Total services: ($report.total_services)"
|
|
print $"Running: ($report.running_services)"
|
|
print $"Ready to start: ($report.ready_to_start)"
|
|
print ""
|
|
|
|
print "Services:"
|
|
for service in $report.services {
|
|
let icon = if $service.running {
|
|
"🟢"
|
|
} else if $service.can_start {
|
|
"🟡"
|
|
} else {
|
|
"🔴"
|
|
}
|
|
|
|
print $" ($icon) ($service.name) - ($service.type) - ($service.category)"
|
|
|
|
if not $service.running and not $service.can_start {
|
|
print $" Issues: ($service.issues)"
|
|
}
|
|
}
|
|
}
|
|
|
|
# Monitor service health
|
|
export def "services monitor" [
|
|
service: string
|
|
--interval: int = 30
|
|
] {
|
|
monitor-service-health $service --interval $interval --alert-on-failure
|
|
}
|