prvng_core/nulib/main_provisioning/commands/state.nu
Jesús Pérez 894046ef5a
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

127 lines
5.5 KiB
Text
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)"
},
}
}