prvng_core/nulib/main_provisioning/workspace.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

191 lines
7.2 KiB
Text

use ../lib_provisioning/config/accessor.nu *
use ../lib_provisioning/workspace *
use ../lib_provisioning/workspace/config_commands.nu *
# Workspace initialization and management
export def "main workspace" [
...args # Workspace command arguments
--infra (-i): string # Infra path
--check (-c) # Check mode only
--out: string # Output format: json, yaml, text
--notitles # Hide table titles
--verbose (-v) # Verbose output
--force (-f) # Force operation
--debug (-x) # Debug mode
--activate (-a) # Activate after register
] {
# Parse subcommand from args
let workspace_command = if ($args | length) > 0 { $args.0 } else { "list" }
let remaining_args = if ($args | length) > 1 { $args | skip 1 } else { [] }
# Check if help command was specified
if $workspace_command in ["help" "h"] {
^$"($env.PROVISIONING_NAME)" help workspace --notitles
return
}
# Execute workspace commands directly
match $workspace_command {
"list" => {
let format = if ($out | is-not-empty) { $out } else { "table" }
workspace list --format $format --notitles=$notitles
}
"activate" | "switch" => {
if ($remaining_args | length) < 1 {
print "❌ Workspace name required for activate/switch"
exit 1
}
workspace activate ($remaining_args | first)
}
"active" => {
workspace active
}
"register" => {
if ($remaining_args | length) < 2 {
print "❌ Workspace name and path required for register"
exit 1
}
workspace register ($remaining_args | first) ($remaining_args | get 1) --activate=$activate
}
"remove" => {
if ($remaining_args | length) < 1 {
print "❌ Workspace name required for remove"
exit 1
}
workspace remove ($remaining_args | first)
}
"update" => {
let ws_name = if ($remaining_args | length) > 0 { $remaining_args.0 } else { "" }
if ($ws_name | is-not-empty) {
workspace update $ws_name --check=$check --force=$force --verbose=$verbose
} else {
workspace update --check=$check --force=$force --verbose=$verbose
}
}
"check-updates" => {
let ws_name = if ($remaining_args | length) > 0 { $remaining_args.0 } else { "" }
if ($ws_name | is-not-empty) {
workspace check-updates $ws_name --verbose=$verbose
} else {
workspace check-updates --verbose=$verbose
}
}
"validate" => {
let ws_name = if ($remaining_args | length) > 0 { $remaining_args.0 } else { "" }
let active_ws = if ($ws_name | is-not-empty) {
$ws_name
} else {
let details = (get-active-workspace-details)
if ($details == null) {
print "❌ No active workspace. Pass a workspace name or activate one first."
exit 1
}
$details.name
}
let ws_root = (get-workspace-path $active_ws)
let infra_arg = if ($infra | is-not-empty) { $infra } else { "wuji" }
let dag_path = ($ws_root | path join "infra" $infra_arg "dag.ncl")
if ($dag_path | path exists) {
main dag validate --workspace $active_ws --infra $infra_arg
} else {
workspace-config-validate $active_ws
}
}
"sync-modules" => {
let ws_name = if ($remaining_args | length) > 0 { $remaining_args.0 } else { "" }
if ($ws_name | is-not-empty) {
workspace sync-modules $ws_name --check=$check --force=$force --verbose=$verbose
} else {
workspace sync-modules --check=$check --force=$force --verbose=$verbose
}
}
"init" => {
if ($remaining_args | length) < 1 {
print "❌ Workspace name required for init"
exit 1
}
let ws_name = $remaining_args.0
let ws_path = if ($remaining_args | length) > 1 {
$remaining_args | skip 1 | str join " "
} else {
([$env.HOME "workspaces" $ws_name] | path join)
}
print $"TODO: Initialize workspace ($ws_name) at ($ws_path)"
}
"config" => {
# Handle workspace config subcommands
if ($remaining_args | length) == 0 {
print "❌ Config subcommand required"
print "Available config subcommands:"
print " show [name] - Show workspace config"
print " validate [name] - Validate configuration"
print " generate provider <name> - Generate provider config"
print " edit <type> [name] - Edit config (main|provider|platform|kms)"
print " hierarchy [name] - Show config loading order"
print " list [name] - List config files"
exit 1
}
let config_subcommand = $remaining_args.0
let config_remaining = if ($remaining_args | length) > 1 { $remaining_args | skip 1 } else { [] }
match $config_subcommand {
"show" => {
let ws_name = if ($config_remaining | length) > 0 { $config_remaining.0 } else { "" }
workspace-config-show $ws_name --format=$out
}
"validate" => {
let ws_name = if ($config_remaining | length) > 0 { $config_remaining.0 } else { "" }
workspace-config-validate $ws_name
}
"generate" => {
if ($config_remaining | length) < 2 {
print "❌ generate requires: generate provider <name>"
exit 1
}
let gen_type = $config_remaining.0
let gen_name = $config_remaining.1
workspace-config-generate-provider $gen_type $gen_name
}
"edit" => {
if ($config_remaining | length) == 0 {
print "❌ edit requires: edit <type> [name]"
exit 1
}
let edit_type = $config_remaining.0
let edit_ws_name = if ($config_remaining | length) > 1 { $config_remaining.1 } else { "" }
workspace-config-edit $edit_type $edit_ws_name
}
"hierarchy" => {
let ws_name = if ($config_remaining | length) > 0 { $config_remaining.0 } else { "" }
workspace-config-hierarchy $ws_name
}
"list" => {
let ws_name = if ($config_remaining | length) > 0 { $config_remaining.0 } else { "" }
workspace-config-list $ws_name --type=($out | default "all")
}
_ => {
print $"❌ Unknown config subcommand: ($config_subcommand)"
exit 1
}
}
}
_ => {
print $"❌ Unknown workspace command: ($workspace_command)"
print ""
print "Available workspace commands:"
print " list - List all workspaces"
print " activate <name> - Activate/switch to workspace"
print " switch <name> - Alias for activate"
print " active - Show currently active workspace"
print " register <name> <path> - Register new workspace"
print " remove <name> - Remove workspace from registry"
print " update - Update all workspace directories"
print " check-updates - Check what needs updating"
print " sync-modules - Sync workspace modules (providers, clusters)"
print " config - Configuration management"
print " validate [name] - Validate DAG topology (dag.ncl) or workspace config"
exit 1
}
}
}