#!/usr/bin/env nu # Thin entry for taskserv commands. # Bypasses full dispatcher — loads only taskservs/* + targeted lib_provisioning pieces. # Order matters: lib_provisioning symbols must be in scope BEFORE use taskservs * # because taskservs/create.nu relies on provisioning_init etc. being pre-loaded. 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 { [] })) # Session timestamp used by taskservs/handlers.nu for working directory paths if ($env.NOW? | is-empty) { $env.NOW = (date now | format date "%Y_%m_%d_%H_%M_%S") } # SSH options — disable strict host checking for provisioning (mirrors env.nu:117) if ($env.SSH_OPS? | is-empty) { $env.SSH_OPS = [ "StrictHostKeyChecking=accept-new" $"UserKnownHostsFile=(if $nu.os-info.name == 'windows' { 'NUL' } else { '/dev/null' })" ] } # Taskservs extension path — used by get-taskservs-path / get-run-taskservs-path let prov = ($env.PROVISIONING? | default "") if ($env.PROVISIONING_TASKSERVS_PATH? | is-empty) and ($prov | is-not-empty) { $env.PROVISIONING_TASKSERVS_PATH = ($prov | path join "extensions" "taskservs") } # Strip leading "taskserv"/"task"/"t" token so get-provisioning-args returns the sub-command # e.g. "taskserv create --infra x" → "create --infra x" let args_raw = ($env.PROVISIONING_ARGS? | default "") $env.PROVISIONING_ARGS = ($args_raw | str replace --regex '^(taskserv|task|t)\s+' '') let _coerce = {|raw| $raw == "true" or $raw == "1" } let raw_no_titles = ($env.PROVISIONING_NO_TITLES? | default "") if ($raw_no_titles | describe) == "string" and ($raw_no_titles | is-not-empty) { $env.PROVISIONING_NO_TITLES = (do $_coerce $raw_no_titles) } let raw_no_terminal = ($env.PROVISIONING_NO_TERMINAL? | default "") if ($raw_no_terminal | describe) == "string" and ($raw_no_terminal | is-not-empty) { $env.PROVISIONING_NO_TERMINAL = (do $_coerce $raw_no_terminal) } let raw_titles_shown = ($env.PROVISIONING_TITLES_SHOWN? | default "") if ($raw_titles_shown | describe) == "string" and ($raw_titles_shown | is-not-empty) { $env.PROVISIONING_TITLES_SHOWN = (do $_coerce $raw_titles_shown) } let raw_debug = ($env.PROVISIONING_DEBUG? | default "") if ($raw_debug | describe) == "string" and ($raw_debug | is-not-empty) { $env.PROVISIONING_DEBUG = (do $_coerce $raw_debug) } } # ── lib_provisioning pieces (MUST precede use taskservs * so create.nu resolves at parse time) ── use lib_provisioning/utils/init.nu * use lib_provisioning/utils/interface.nu [ _print _ansi set-provisioning-out set-provisioning-no-terminal get-provisioning-no-terminal get-provisioning-out end_run desktop_run_notify show_clip_to log_debug ] use lib_provisioning/utils/logging.nu [ set-debug-enabled set-metadata-enabled is-debug-enabled is-debug-check-enabled is-metadata-enabled ] use lib_provisioning/utils/settings.nu [ find_get_settings settings_with_env set-wk-cnprov get_file_format ] use lib_provisioning/sops/lib.nu [get_def_sops, get_def_age] use lib_provisioning/utils/templates.nu [on_template_path, run_from_template] use lib_provisioning/plugins_defs.nu [port_scan] use ../../extensions/providers/prov_lib/middleware.nu * # ── taskservs module (resolves provisioning_init etc. from above) ── use taskservs * def main [ ...args: string # args[0] = "taskserv"/"t", args[1] = subcommand --infra (-i): string = "" --settings (-s): string = "" --iptype: string = "public" --reset # Force reinstall: kubeadm reset before re-install (sets CMD_TSK=reinstall) --cmd: string = "" # Override cmd_task: scripts, config, update, restart, reinstall, remove --check (-c) --upload (-u) --force # Delete taskservs no longer in servers.ncl (reads from state file) --yes (-y) # Confirm delete without prompt --debug (-x) --xc --xr --xm --metadata --notitles --out: string = "" ]: nothing -> nothing { if $debug { $env.PROVISIONING_DEBUG = true } let first = ($args | get 0? | default "") let rest = if $first in ["taskserv", "task", "t"] { $args | skip 1 } else { $args } let sub = ($rest | get 0? | default "create") let task_name = ($rest | get 1? | default "") let server_arg = ($rest | get 2? | default "") match $sub { "create" | "c" => { if ($task_name | is-not-empty) and ($server_arg | is-not-empty) { if $reset { main create $task_name $server_arg --reset --infra $infra --settings $settings --iptype $iptype --check=$check --upload=$upload --debug=$debug --xc=$xc --xr=$xr --notitles=$notitles --out=$out --cmd $cmd } else { main create $task_name $server_arg --infra $infra --settings $settings --iptype $iptype --check=$check --upload=$upload --debug=$debug --xc=$xc --xr=$xr --notitles=$notitles --out=$out --cmd $cmd } } else if ($task_name | is-not-empty) { if $reset { main create $task_name --reset --infra $infra --settings $settings --iptype $iptype --check=$check --upload=$upload --debug=$debug --xc=$xc --xr=$xr --notitles=$notitles --out=$out --cmd $cmd } else { main create $task_name --infra $infra --settings $settings --iptype $iptype --check=$check --upload=$upload --debug=$debug --xc=$xc --xr=$xr --notitles=$notitles --out=$out --cmd $cmd } } else { if $reset { main create --reset --infra $infra --settings $settings --iptype $iptype --check=$check --upload=$upload --debug=$debug --xc=$xc --xr=$xr --notitles=$notitles --out=$out --cmd $cmd } else { main create --infra $infra --settings $settings --iptype $iptype --check=$check --upload=$upload --debug=$debug --xc=$xc --xr=$xr --notitles=$notitles --out=$out --cmd $cmd } } } "update" | "u" => { # Update: bump version or reconfigure — no state-gate, always runs if ($task_name | is-not-empty) and ($server_arg | is-not-empty) { main create $task_name $server_arg --infra $infra --settings $settings --iptype $iptype --debug=$debug --xc=$xc --xr=$xr --notitles=$notitles --out=$out --cmd "update" } else if ($task_name | is-not-empty) { main create $task_name --infra $infra --settings $settings --iptype $iptype --debug=$debug --xc=$xc --xr=$xr --notitles=$notitles --out=$out --cmd "update" } else { main create --infra $infra --settings $settings --iptype $iptype --debug=$debug --xc=$xc --xr=$xr --notitles=$notitles --out=$out --cmd "update" } } "reset" | "r" => { # Reset: stop + clean data + reinstall from scratch if ($task_name | is-not-empty) and ($server_arg | is-not-empty) { main create $task_name $server_arg --reset --infra $infra --settings $settings --iptype $iptype --debug=$debug --xc=$xc --xr=$xr --notitles=$notitles --out=$out } else if ($task_name | is-not-empty) { main create $task_name --reset --infra $infra --settings $settings --iptype $iptype --debug=$debug --xc=$xc --xr=$xr --notitles=$notitles --out=$out } else { main create --reset --infra $infra --settings $settings --iptype $iptype --debug=$debug --xc=$xc --xr=$xr --notitles=$notitles --out=$out } } "run" => { # Run: arbitrary cmd_task op (scripts, config, restart, remove, ...) let op = if ($cmd | is-not-empty) { $cmd } else { $task_name } let ts = if ($cmd | is-not-empty) { $task_name } else { $server_arg } let sv = if ($cmd | is-not-empty) { $server_arg } else { "" } if ($ts | is-not-empty) and ($sv | is-not-empty) { main create $ts $sv --infra $infra --settings $settings --iptype $iptype --debug=$debug --xc=$xc --xr=$xr --notitles=$notitles --out=$out --cmd $op } else if ($ts | is-not-empty) { main create $ts --infra $infra --settings $settings --iptype $iptype --debug=$debug --xc=$xc --xr=$xr --notitles=$notitles --out=$out --cmd $op } else { main create --infra $infra --settings $settings --iptype $iptype --debug=$debug --xc=$xc --xr=$xr --notitles=$notitles --out=$out --cmd $op } } "delete" | "d" => { if ($task_name | is-not-empty) and ($server_arg | is-not-empty) { if $force { main delete $task_name $server_arg --force --infra $infra --settings $settings --yes=$yes --debug=$debug --notitles=$notitles } else { main delete $task_name $server_arg --infra $infra --settings $settings --yes=$yes --debug=$debug --notitles=$notitles } } else if ($task_name | is-not-empty) { if $force { main delete $task_name --force --infra $infra --settings $settings --yes=$yes --debug=$debug --notitles=$notitles } else { main delete $task_name --infra $infra --settings $settings --yes=$yes --debug=$debug --notitles=$notitles } } else { main delete --infra $infra --settings $settings --yes=$yes --debug=$debug --notitles=$notitles } } "generate" | "g" => { if ($task_name | is-not-empty) { main generate $task_name --infra $infra --settings $settings --debug=$debug --notitles=$notitles } else { main generate --infra $infra --settings $settings --debug=$debug --notitles=$notitles } } "status" | "st" => { if ($task_name | is-not-empty) { main status --server $task_name --infra $infra --settings $settings } else { main status --infra $infra --settings $settings } } "list" | "ls" => { use ./components/mod.nu [component-list] let workspace = ($env.PROVISIONING_KLOUD? | default "") component-list "taskserv" $workspace } "show" | "s" => { use ./components/mod.nu [component-show] let workspace = ($env.PROVISIONING_KLOUD? | default "") component-show $task_name $workspace false } _ => { print "Usage: provisioning taskserv [taskserv] [server] [flags]" print " create (c) — initial install (state-gate: skips completed nodes)" print " update (u) — update version/config (always runs, no state-gate)" print " reset (r) — stop + clean data + reinstall from scratch" print " run — run arbitrary op: scripts, config, restart, remove, ..." print " delete (d) — remove taskservs" print " generate (g) — generate taskserv configs" print " status (st) — show DAG formula progress per server" print " list (ls) — list taskserv-mode components" print " show (s) — show component details [--workspace ] [--ext]" } } }