prvng_core/nulib/main_provisioning/commands/state.nu

128 lines
5.5 KiB
Text
Raw 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
use ../../lib_provisioning/config/accessor.nu *
use ../../lib_provisioning/utils/interface.nu [_print]
use ../../workspace/state.nu *
use ../../workspace/sync.nu *
export def handle_state_command [cmd: string, ops: string, flags: record] {
let workspace_path = if ($env.PROVISIONING_WORKSPACE_PATH? | is-not-empty) {
$env.PROVISIONING_WORKSPACE_PATH
} else {
$env.PWD
}
let infra = ($flags | get -o infra | default "")
let server = ($flags | get -o server | default "")
let taskserv = ($flags | get -o taskserv | default "")
let kubeconfig = ($flags | get -o kubeconfig | default "")
# When help_category == command name ("state"), the subcommand lands in $ops, not $cmd.
let subcmd = if ($ops | is-not-empty) { ($ops | split row " " | first) } else { $cmd }
match $subcmd {
"show" | "s" => {
state-show $workspace_path --server $server
},
"init" | "i" => {
let curr_settings = (find_get_settings --infra $infra)
state-init $workspace_path $curr_settings
_print $"State initialized at (state-path $workspace_path)"
},
"reset" | "r" => {
if ($server | is-empty) or ($taskserv | is-empty) {
error make { msg: "state reset requires --server <hostname> --taskserv <name>" }
}
state-node-reset $workspace_path $server $taskserv
_print $"($server)/($taskserv) reset to pending"
},
"migrate" | "m" => {
state-migrate-from-json $workspace_path
},
"sync" => {
let curr_settings = (find_get_settings --infra $infra)
# 1. Drift detection + reconcile against servers.ncl
let drift_rows = (state-drift $workspace_path $curr_settings --server $server)
let has_drift = ($drift_rows | where drift != "ok" | is-not-empty)
if $has_drift {
_print "── drift ──"
print ($drift_rows | where drift != "ok" | table)
let result = (state-reconcile $workspace_path $curr_settings --server $server)
if ($result.removed | is-not-empty) {
_print $"🗑 Removed ($result.removed | length) orphaned"
}
if ($result.added | is-not-empty) {
_print $" Added ($result.added | length) pending"
}
} else {
_print "✅ No drift against servers.ncl"
}
# 2. External API sync (Hetzner, K8s, SSH)
let skip_ssh = ($flags | get -o skip_ssh | default false)
state-sync $workspace_path $curr_settings --kubeconfig $kubeconfig --skip-ssh=$skip_ssh
},
"drift" | "d" => {
let curr_settings = (find_get_settings --infra $infra)
let rows = (state-drift $workspace_path $curr_settings --server $server)
let has_drift = ($rows | where drift != "ok" | is-not-empty)
if ($rows | is-empty) {
_print "(no state entries to compare)"
} else {
print ($rows | table)
if $has_drift {
_print $"\n⚠ Drift detected. Run (_ansi yellow_bold)provisioning state reconcile(_ansi reset) to fix."
} else {
_print "\n✅ No drift — state matches servers.ncl"
}
}
},
"reconcile" | "rec" => {
let curr_settings = (find_get_settings --infra $infra)
let dry_run = ($flags | get -o dry_run | default false)
# Always show drift first
let drift_rows = (state-drift $workspace_path $curr_settings --server $server)
let has_drift = ($drift_rows | where drift != "ok" | is-not-empty)
if not $has_drift {
_print "✅ No drift — nothing to reconcile"
return
}
print ($drift_rows | where drift != "ok" | table)
if $dry_run {
_print "\n(dry-run: no changes applied)"
return
}
let result = (state-reconcile $workspace_path $curr_settings --server $server)
if ($result.removed | is-not-empty) {
_print $"\n🗑 Removed ($result.removed | length) orphaned entries:"
for r in $result.removed { _print $" ($r.server)/($r.taskserv)" }
}
if ($result.added | is-not-empty) {
_print $"\n Added ($result.added | length) pending entries:"
for a in $result.added { _print $" ($a.server)/($a.taskserv)" }
}
_print "\n✅ State reconciled with servers.ncl"
},
_ => {
_print "Usage: provisioning state <subcommand> [--infra <path>]"
_print ""
_print " show [--server <hostname>] — display state table"
_print " init [--infra <path>] — bootstrap state from settings"
_print " reset --server <hostname> --taskserv <name> — reset node to pending"
_print " migrate — migrate .json → .ncl"
_print " sync [--infra <path>] [--kubeconfig <path>] — reconcile from APIs"
_print " drift [--infra <path>] [--server <hostname>] — detect state vs servers.ncl divergence"
_print " reconcile [--infra <path>] [--server <hostname>] — fix drift (remove orphaned, add missing)"
},
}
}