- 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.
127 lines
4.9 KiB
Text
127 lines
4.9 KiB
Text
use dag-executor.nu [load-dag]
|
|
use ../workspace/state.nu [state-read, state-node-get]
|
|
use ../lib_provisioning/config/accessor.nu *
|
|
use ../lib_provisioning/utils/settings.nu [find_get_settings, settings_with_env]
|
|
|
|
def state-icon [s: string]: nothing -> string {
|
|
match $s {
|
|
"completed" => $"(_ansi green)✅(_ansi reset)",
|
|
"running" => $"(_ansi yellow)🔄(_ansi reset)",
|
|
"failed" => $"(_ansi red)❌(_ansi reset)",
|
|
"blocked" => $"(_ansi red_dimmed)⊘(_ansi reset)",
|
|
_ => $"(_ansi default_dimmed)⏳(_ansi reset)",
|
|
}
|
|
}
|
|
|
|
def state-col [s: string]: nothing -> string {
|
|
match $s {
|
|
"completed" => (_ansi green),
|
|
"running" => (_ansi yellow),
|
|
"failed" => (_ansi red),
|
|
"blocked" => (_ansi red_dimmed),
|
|
_ => (_ansi default_dimmed),
|
|
}
|
|
}
|
|
|
|
def fmt-ts [ts: string]: nothing -> string {
|
|
if ($ts | is-empty) { "—" } else { $ts | str replace "T" " " | str replace "Z" "" }
|
|
}
|
|
|
|
# Show DAG formula execution progress — which taskservs completed, pending, failed
|
|
export def "main status" [
|
|
--infra (-i): string = ""
|
|
--settings (-s): string = ""
|
|
--server: string = ""
|
|
] {
|
|
let curr_settings = (settings_with_env (find_get_settings --infra $infra --settings $settings))
|
|
let workspace_path = ($curr_settings.src_path? | default $env.PWD)
|
|
let dag = (load-dag $curr_settings)
|
|
|
|
if not $dag.has_dag {
|
|
_print "No DAG found — no formula state to show."
|
|
return
|
|
}
|
|
|
|
let st = (state-read $workspace_path)
|
|
|
|
for formula in $dag.formulas {
|
|
if ($server | is-not-empty) and $formula.server != $server { continue }
|
|
|
|
let all_done = ($formula.nodes | all {|n|
|
|
let ns = (state-node-get $workspace_path $formula.server $n.taskserv.name)
|
|
$ns.state == "completed"
|
|
})
|
|
let tag = if $all_done {
|
|
$"(_ansi green)[complete](_ansi reset)"
|
|
} else {
|
|
$"(_ansi yellow)[in progress](_ansi reset)"
|
|
}
|
|
|
|
_print $"▶ (_ansi green_bold)($formula.id)(_ansi reset) on (_ansi cyan_bold)($formula.server)(_ansi reset) ($tag)"
|
|
|
|
for node in $formula.nodes {
|
|
let ns = (state-node-get $workspace_path $formula.server $node.taskserv.name)
|
|
let icon = (state-icon $ns.state)
|
|
let col = (state-col $ns.state)
|
|
let name_pad = ($node.taskserv.name | fill -a l -w 20)
|
|
let st_pad = ($ns.state | fill -a l -w 10)
|
|
let ts = if $ns.state == "completed" { fmt-ts $ns.ended_at } else { "" }
|
|
let extra = if ($ns.blocker? | default "" | is-not-empty) {
|
|
$" ← blocked by (_ansi red)($ns.blocker)(_ansi reset)"
|
|
} else { "" }
|
|
_print $" ($icon) ($col)($name_pad)(_ansi reset) ($col)($st_pad)(_ansi reset) ($ts)($extra)"
|
|
}
|
|
_print ""
|
|
}
|
|
}
|
|
|
|
# List all taskservs in the DAG with their state
|
|
export def "main list" [
|
|
--infra (-i): string = ""
|
|
--settings (-s): string = ""
|
|
--server: string = ""
|
|
--out: string = ""
|
|
] {
|
|
let curr_settings = (settings_with_env (find_get_settings --infra $infra --settings $settings))
|
|
let workspace_path = ($curr_settings.src_path? | default $env.PWD)
|
|
let dag = (load-dag $curr_settings)
|
|
|
|
if not $dag.has_dag {
|
|
_print "No DAG found."
|
|
return
|
|
}
|
|
|
|
let rows = ($dag.formulas | each {|formula|
|
|
if ($server | is-not-empty) and $formula.server != $server { [] } else {
|
|
$formula.nodes | each {|node|
|
|
let ns = (state-node-get $workspace_path $formula.server $node.taskserv.name)
|
|
{
|
|
taskserv: $node.taskserv.name,
|
|
server: $formula.server,
|
|
state: $ns.state,
|
|
profile: ($node.taskserv.profile? | default "default"),
|
|
depends_on: ($node.depends_on? | default [] | each {|d| $d.node_id } | str join ","),
|
|
ended: (fmt-ts $ns.ended_at),
|
|
actor: ($ns.actor?.identity? | default ""),
|
|
}
|
|
}
|
|
}
|
|
} | flatten)
|
|
|
|
if $out == "json" { $rows | to json; return }
|
|
if $out == "yaml" { $rows | to yaml; return }
|
|
|
|
_print $"(_ansi default_dimmed)TASKSERV SERVER STATE PROFILE DEPENDS-ON ENDED(_ansi reset)"
|
|
for row in $rows {
|
|
let col = (state-col $row.state)
|
|
let icon = (state-icon $row.state)
|
|
_print (
|
|
$"($icon) ($col)($row.taskserv | fill -a l -w 20)(_ansi reset)" +
|
|
$" (_ansi cyan)($row.server | fill -a l -w 17)(_ansi reset)" +
|
|
$" ($col)($row.state | fill -a l -w 10)(_ansi reset)" +
|
|
$" ($row.profile | fill -a l -w 10)" +
|
|
$" ($row.depends_on | fill -a l -w 20)" +
|
|
$" ($row.ended)"
|
|
)
|
|
}
|
|
}
|