prvng_core/nulib/provisioning-batch.nu

166 lines
7 KiB
Text
Raw Permalink Normal View History

feat(core): three-layer DAG, unified component arch, commands-registry cache, Nushell 0.112.2 migration - DAG architecture: `dag show/validate/export` (nulib/main_provisioning/dag.nu), config loader (lib_provisioning/config/loader/dag.nu), taskserv dag-executor. Backed by schemas/lib/dag/*.ncl; orchestrator emits NATS events via WorkspaceComposition::into_workflow. See ADR-020, ADR-021. - Unified Component Architecture: components/mod.nu, main_provisioning/ {components,workflow,extensions,ontoref-queries}.nu. Full workflow engine with topological sort and NATS subject emission. Blocks A-H complete (libre-daoshi). - Commands-registry: nulib/commands-registry.ncl (Nickel source, 314 lines) + JSON cache at ~/.cache/provisioning/commands-registry.json rebuilt on source change. cli/provisioning fast-path alias expansion avoids cold Nu startup. ADDING_COMMANDS.md documents new-command workflow. - Platform service manager: service-manager.nu (+573), startup.nu (+611), service-check.nu (+255); autostart/bootstrap/health/target refactored. - Nushell 0.112.2 migration: removed all try/catch and bash redirections; external commands prefixed with ^; type signatures enforced. Driven by scripts/refactor-try-catch{,-simplified}.nu. - TTY stack: removed shlib/*-tty.sh; replaced by cli/tty-dispatch.sh, tty-filter.sh, tty-commands.conf. - New domain modules: images/ (golden image lifecycle), workspace/{state,sync}.nu, main_provisioning/{bootstrap,cluster-deploy,fip,state}.nu, commands/{state, build,integrations/auth,utilities/alias}.nu, platform.nu expanded (+874). - Config loader overhaul: loader/core.nu slimmed (-759), cache/core.nu refactored (-454), removed legacy loaders/file_loader.nu (-330). - Thirteen new provisioning-<domain>.nu top-level modules for bash dispatcher. - Tests: test_workspace_state.nu (+351); updates to test_oci_registry, test_services. - README + CHANGELOG updated.
2026-04-17 04:27:33 +01:00
#!/usr/bin/env nu
# Thin entry for batch workflow commands.
# Loads ONLY workflows/batch.nu (~95ms vs ~12s for the full double-load).
export-env {
let lib_dirs_raw = ($env.NU_LIB_DIRS? | default "")
let current_lib_dirs = if ($lib_dirs_raw | type) == "string" {
if ($lib_dirs_raw | is-empty) { [] } else { ($lib_dirs_raw | split row ":") }
} else {
$lib_dirs_raw
}
let dynamic = ($env.PROVISIONING? | default "" | path join "core" "nulib")
$env.NU_LIB_DIRS = ([
"/opt/provisioning/core/nulib"
"/usr/local/provisioning/core/nulib"
] | append $current_lib_dirs | append (if ($dynamic | is-not-empty) { [$dynamic] } else { [] }))
}
use workflows/batch.nu *
def main [
...args: string
--status: string = ""
--environment: string = ""
--name: string = ""
--limit: int = 50
--format: string = "table"
--priority: int = 5
--interval: duration = 3sec
--timeout: duration = 30min
--checkpoint: string = ""
--reason: string = ""
--period: string = "24h"
--from-file: string = ""
--description: string = ""
--check-syntax (-s)
--check-dependencies (-d)
--wait (-w)
--force (-f)
--quiet (-q)
--detailed
--debug (-x)
--out: string
]: nothing -> nothing {
if $debug { $env.PROVISIONING_DEBUG = true }
# CMD_ARGS from the bash wrapper includes the command name as arg[0] ("batch"/"bat").
# Strip it so arg[0] becomes the subcommand.
let first = ($args | get 0? | default "")
let sub_args = if $first in ["batch", "bat"] { $args | skip 1 } else { $args }
let task = ($sub_args | get 0? | default "")
let ops = ($sub_args | skip 1)
let workflow_param = ($ops | get 0? | default "")
match $task {
"list" => {
let result = (batch list --status $status --environment $environment --name $name --limit $limit --format $format)
if ($out | is-not-empty) and $out == "json" { print ($result | to json) } else { print ($result | table) }
}
"status" => {
if ($workflow_param | is-empty) { print "❌ Workflow ID required"; exit 1 }
batch status $workflow_param --format $format
}
"submit" => {
if ($workflow_param | is-empty) { print "❌ Workflow file path required"; exit 1 }
let result = if $wait {
batch submit $workflow_param --name $name --priority $priority --environment $environment --wait --timeout $timeout
} else {
batch submit $workflow_param --name $name --priority $priority --environment $environment
}
if ($out | is-not-empty) and $out == "json" { print ($result | to json) }
}
"validate" => {
if ($workflow_param | is-empty) { print "❌ Workflow file path required"; exit 1 }
let result = if $check_syntax and $check_dependencies {
batch validate $workflow_param --check-syntax --check-dependencies
} else if $check_syntax {
batch validate $workflow_param --check-syntax
} else if $check_dependencies {
batch validate $workflow_param --check-dependencies
} else {
batch validate $workflow_param
}
if $result.valid { print "✅ Workflow is valid" } else {
print "❌ Workflow validation failed"
print $"Errors: ($result.errors | str join '\n ')"
}
}
"monitor" => {
if ($workflow_param | is-empty) { print "❌ Workflow ID required"; exit 1 }
if $quiet {
batch monitor $workflow_param --interval $interval --timeout $timeout --quiet
} else {
batch monitor $workflow_param --interval $interval --timeout $timeout
}
}
"rollback" => {
if ($workflow_param | is-empty) { print "❌ Workflow ID required"; exit 1 }
let result = if ($checkpoint | is-not-empty) {
batch rollback $workflow_param --checkpoint $checkpoint --force
} else if $force {
batch rollback $workflow_param --force
} else {
batch rollback $workflow_param
}
if ($out | is-not-empty) and $out == "json" { print ($result | to json) }
}
"cancel" => {
if ($workflow_param | is-empty) { print "❌ Workflow ID required"; exit 1 }
let result = if ($reason | is-not-empty) and $force {
batch cancel $workflow_param --reason $reason --force
} else if ($reason | is-not-empty) {
batch cancel $workflow_param --reason $reason
} else if $force {
batch cancel $workflow_param --force
} else {
batch cancel $workflow_param
}
if ($out | is-not-empty) and $out == "json" { print ($result | to json) }
}
"template" => {
let action = if ($workflow_param | is-not-empty) { $workflow_param } else { "list" }
let tpl_name = ($ops | get 1? | default "")
let result = match $action {
"list" => { batch template "list" }
"show" => { if ($tpl_name | is-empty) { print "❌ Template name required"; exit 1 }; batch template "show" $tpl_name }
"delete" => { if ($tpl_name | is-empty) { print "❌ Template name required"; exit 1 }; batch template "delete" $tpl_name }
"create" => {
if ($tpl_name | is-empty) or ($from_file | is-empty) { print "❌ Name and --from-file required"; exit 1 }
batch template "create" $tpl_name --from-file $from_file --description $description
}
_ => { print $"❌ Unknown template action: ($action)"; exit 1 }
}
if ($out | is-not-empty) and $out == "json" { print ($result | to json) } else { print ($result | table) }
}
"stats" => {
let result = if $detailed {
batch stats --period $period --environment $environment --detailed
} else {
batch stats --period $period --environment $environment
}
if ($out | is-not-empty) and $out == "json" { print ($result | to json) }
}
"health" => {
batch health
}
"help" | "h" => {
print "Batch Workflow Management"
print "Usage: provisioning batch <command> [args]"
print ""
print "Commands: list, status, submit, validate, monitor, rollback, cancel, template, stats, health"
}
"" => {
print "❌ Batch subcommand required"
print "Commands: list, status, submit, validate, monitor, rollback, cancel, template, stats, health"
exit 1
}
_ => {
print $"❌ Unknown batch command: ($task)"
print "Commands: list, status, submit, validate, monitor, rollback, cancel, template, stats, health"
exit 1
}
}
}