Files
lab/bastion/completions/labctl.fish

241 lines
17 KiB
Fish
Raw Permalink Normal View History

# labctl fish completions -- auto-generated by scripts/generate-completions.ts
# DO NOT EDIT MANUALLY -- run: pnpm completions:generate
complete -c labctl -e
complete -c labctl -f
# Global options
complete -c labctl -s v -l version -d 'Show version'
complete -c labctl -s h -l help -d 'Show help'
feat: install logging, error trapping, PXE/ISO integration tests Kickstart installs on real hardware failed silently — no error reporting, only 3 progress callbacks, zero log streaming. This overhaul makes every install fully observable. Kickstart improvements: - Error trapping in %pre and %post (trap ERR sends failure details to bastion) - 12+ granular progress stages (was 3): SSH, hostname, k3s prep, EFI boot, metadata - Background log streamer: tails %post output and batch-sends to /api/log - bastion_log() function for explicit log lines from kickstart scripts Bastion API: - POST /api/log — receives raw log lines from kickstart (single or batch) - InstallLogBuffer — per-MAC ring buffer (2000 lines) + file persistence - GET /api/logs/:mac — now returns log_lines + log_total alongside stages - SSE /api/logs/:mac/follow — uses named events (event: stage vs event: log) - Progress events forwarded to labd via bastion-progress WebSocket message - Post-provision k3s logs routed through progressBus (was console-only) dnsmasq fixes found during VM testing: - HTTP Boot filename: ipxe-real.efi → ipxe.efi (leftover from old 2-stage approach) - pxe-service directives: only in proxy mode (breaks OVMF PXE in full mode) - PXEClient vendor class echo for UEFI firmware compatibility Integration tests: - PXE boot test: blank UEFI VM → dnsmasq → HTTP Boot → iPXE → bastion → install - ISO boot test: blank VM boots from bastion-generated ISO → same flow - Shared helpers: pxe-network (no DHCP, nftables fix), pxe-vm (UEFI + ISO boot) - test-provision.sh: runs both PXE + ISO tests with prerequisite checks - 250GB sparse QCOW2 disk (LVM layout needs ~204GB) 201 unit tests passing (11 new). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:26:33 +00:00
# Helper: test if exactly a subcommand chain is active (no extra positional args)
function __labctl_using_cmd
set -l tokens (commandline -opc)
set -l expected $argv
set -l depth (count $expected)
set -l found 0
set -l i 1
for tok in $tokens[2..]
if string match -q -- "-*" $tok
continue
end
set i (math $i + 1)
set -l idx (math $i - 1)
if test $idx -le $depth
if test "$tok" != "$expected[$idx]"
return 1
end
set found (math $found + 1)
else
return 1
end
end
test $found -eq $depth
end
feat: install logging, error trapping, PXE/ISO integration tests Kickstart installs on real hardware failed silently — no error reporting, only 3 progress callbacks, zero log streaming. This overhaul makes every install fully observable. Kickstart improvements: - Error trapping in %pre and %post (trap ERR sends failure details to bastion) - 12+ granular progress stages (was 3): SSH, hostname, k3s prep, EFI boot, metadata - Background log streamer: tails %post output and batch-sends to /api/log - bastion_log() function for explicit log lines from kickstart scripts Bastion API: - POST /api/log — receives raw log lines from kickstart (single or batch) - InstallLogBuffer — per-MAC ring buffer (2000 lines) + file persistence - GET /api/logs/:mac — now returns log_lines + log_total alongside stages - SSE /api/logs/:mac/follow — uses named events (event: stage vs event: log) - Progress events forwarded to labd via bastion-progress WebSocket message - Post-provision k3s logs routed through progressBus (was console-only) dnsmasq fixes found during VM testing: - HTTP Boot filename: ipxe-real.efi → ipxe.efi (leftover from old 2-stage approach) - pxe-service directives: only in proxy mode (breaks OVMF PXE in full mode) - PXEClient vendor class echo for UEFI firmware compatibility Integration tests: - PXE boot test: blank UEFI VM → dnsmasq → HTTP Boot → iPXE → bastion → install - ISO boot test: blank VM boots from bastion-generated ISO → same flow - Shared helpers: pxe-network (no DHCP, nftables fix), pxe-vm (UEFI + ISO boot) - test-provision.sh: runs both PXE + ISO tests with prerequisite checks - 250GB sparse QCOW2 disk (LVM layout needs ~204GB) 201 unit tests passing (11 new). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:26:33 +00:00
# Helper: test if command starts with a subcommand chain (options still apply after args)
function __labctl_in_cmd
set -l tokens (commandline -opc)
set -l expected $argv
set -l depth (count $expected)
set -l found 0
for tok in $tokens[2..]
if string match -q -- "-*" $tok
continue
end
set found (math $found + 1)
if test $found -le $depth
if test "$tok" != "$expected[$found]"
return 1
end
end
end
test $found -ge $depth
end
# Dynamic: fetch machine hostnames from bastion (installed + queued)
function __labctl_installed_hosts
curl -s http://localhost:8080/api/machines 2>/dev/null |
python3 -c 'import sys,json; d=json.load(sys.stdin); hosts=[v.get("hostname","") for v in {**d.get("install_queue",{}), **d.get("installed",{})}.values() if v.get("hostname")]; [print(h) for h in set(hosts)]' 2>/dev/null
end
# Dynamic: fetch all known MAC addresses (discovered + queue + installed)
function __labctl_known_macs
curl -s http://localhost:8080/api/machines 2>/dev/null |
python3 -c 'import sys,json; d=json.load(sys.stdin); [print(k) for k in {**d.get("discovered",{}), **d.get("install_queue",{}), **d.get("installed",{})}]' 2>/dev/null
end
# Dynamic: fetch hostnames and MACs from all states
function __labctl_hosts_and_macs
curl -s http://localhost:8080/api/machines 2>/dev/null |
python3 -c 'import sys,json; d=json.load(sys.stdin); a={**d.get("discovered",{}), **d.get("install_queue",{}), **d.get("installed",{})}; macs=list(a.keys()); hosts=[v.get("hostname","") for v in {**d.get("install_queue",{}), **d.get("installed",{})}.values() if v.get("hostname")]; [print(x) for x in set(macs+hosts)]' 2>/dev/null
end
# Target argument completions
complete -c labctl -n "__labctl_using_cmd app k3s install" -a "(__labctl_installed_hosts)" -d 'installed host'
complete -c labctl -n "__labctl_using_cmd app k3s health" -a "(__labctl_installed_hosts)" -d 'installed host'
complete -c labctl -n "__labctl_using_cmd app labcontroller deploy" -a "(__labctl_installed_hosts)" -d 'installed host'
complete -c labctl -n "__labctl_using_cmd app labcontroller status" -a "(__labctl_installed_hosts)" -d 'installed host'
complete -c labctl -n "__labctl_using_cmd provision install" -a "(__labctl_known_macs)" -d 'MAC address'
complete -c labctl -n "__labctl_using_cmd provision reprovision" -a "(__labctl_hosts_and_macs)" -d 'host or MAC'
complete -c labctl -n "__labctl_using_cmd provision forget" -a "(__labctl_hosts_and_macs)" -d 'host or MAC'
complete -c labctl -n "__labctl_using_cmd provision logs" -a "(__labctl_hosts_and_macs)" -d 'host or MAC'
# Top-level commands
feat: install logging, error trapping, PXE/ISO integration tests Kickstart installs on real hardware failed silently — no error reporting, only 3 progress callbacks, zero log streaming. This overhaul makes every install fully observable. Kickstart improvements: - Error trapping in %pre and %post (trap ERR sends failure details to bastion) - 12+ granular progress stages (was 3): SSH, hostname, k3s prep, EFI boot, metadata - Background log streamer: tails %post output and batch-sends to /api/log - bastion_log() function for explicit log lines from kickstart scripts Bastion API: - POST /api/log — receives raw log lines from kickstart (single or batch) - InstallLogBuffer — per-MAC ring buffer (2000 lines) + file persistence - GET /api/logs/:mac — now returns log_lines + log_total alongside stages - SSE /api/logs/:mac/follow — uses named events (event: stage vs event: log) - Progress events forwarded to labd via bastion-progress WebSocket message - Post-provision k3s logs routed through progressBus (was console-only) dnsmasq fixes found during VM testing: - HTTP Boot filename: ipxe-real.efi → ipxe.efi (leftover from old 2-stage approach) - pxe-service directives: only in proxy mode (breaks OVMF PXE in full mode) - PXEClient vendor class echo for UEFI firmware compatibility Integration tests: - PXE boot test: blank UEFI VM → dnsmasq → HTTP Boot → iPXE → bastion → install - ISO boot test: blank VM boots from bastion-generated ISO → same flow - Shared helpers: pxe-network (no DHCP, nftables fix), pxe-vm (UEFI + ISO boot) - test-provision.sh: runs both PXE + ISO tests with prerequisite checks - 250GB sparse QCOW2 disk (LVM layout needs ~204GB) 201 unit tests passing (11 new). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:26:33 +00:00
complete -c labctl -n "not __fish_seen_subcommand_from version init provision config login doctor app roles" -a version -d 'Show version information'
complete -c labctl -n "not __fish_seen_subcommand_from version init provision config login doctor app roles" -a init -d 'Initialise infrastructure components'
complete -c labctl -n "not __fish_seen_subcommand_from version init provision config login doctor app roles" -a provision -d 'Machine provisioning operations'
complete -c labctl -n "not __fish_seen_subcommand_from version init provision config login doctor app roles" -a config -d 'View and modify CLI configuration'
complete -c labctl -n "not __fish_seen_subcommand_from version init provision config login doctor app roles" -a login -d 'Authenticate with labd and obtain client certificate'
complete -c labctl -n "not __fish_seen_subcommand_from version init provision config login doctor app roles" -a doctor -d 'Diagnose configuration and connectivity issues'
complete -c labctl -n "not __fish_seen_subcommand_from version init provision config login doctor app roles" -a app -d 'Application management'
complete -c labctl -n "not __fish_seen_subcommand_from version init provision config login doctor app roles" -a roles -d 'List available machine roles'
# init subcommands
complete -c labctl -n "__labctl_using_cmd init" -a bastion -d 'Bastion PXE server management'
# init bastion subcommands
complete -c labctl -n "__labctl_using_cmd init bastion" -a standalone -d 'Standalone bastion server lifecycle'
# init bastion standalone subcommands
complete -c labctl -n "__labctl_using_cmd init bastion standalone" -a start -d 'Start the bastion server (HTTP + dnsmasq PXE)'
complete -c labctl -n "__labctl_using_cmd init bastion standalone" -a stop -d 'Stop a running bastion server'
complete -c labctl -n "__labctl_using_cmd init bastion standalone" -a status -d 'Show bastion server status'
# init bastion standalone start options
feat: install logging, error trapping, PXE/ISO integration tests Kickstart installs on real hardware failed silently — no error reporting, only 3 progress callbacks, zero log streaming. This overhaul makes every install fully observable. Kickstart improvements: - Error trapping in %pre and %post (trap ERR sends failure details to bastion) - 12+ granular progress stages (was 3): SSH, hostname, k3s prep, EFI boot, metadata - Background log streamer: tails %post output and batch-sends to /api/log - bastion_log() function for explicit log lines from kickstart scripts Bastion API: - POST /api/log — receives raw log lines from kickstart (single or batch) - InstallLogBuffer — per-MAC ring buffer (2000 lines) + file persistence - GET /api/logs/:mac — now returns log_lines + log_total alongside stages - SSE /api/logs/:mac/follow — uses named events (event: stage vs event: log) - Progress events forwarded to labd via bastion-progress WebSocket message - Post-provision k3s logs routed through progressBus (was console-only) dnsmasq fixes found during VM testing: - HTTP Boot filename: ipxe-real.efi → ipxe.efi (leftover from old 2-stage approach) - pxe-service directives: only in proxy mode (breaks OVMF PXE in full mode) - PXEClient vendor class echo for UEFI firmware compatibility Integration tests: - PXE boot test: blank UEFI VM → dnsmasq → HTTP Boot → iPXE → bastion → install - ISO boot test: blank VM boots from bastion-generated ISO → same flow - Shared helpers: pxe-network (no DHCP, nftables fix), pxe-vm (UEFI + ISO boot) - test-provision.sh: runs both PXE + ISO tests with prerequisite checks - 250GB sparse QCOW2 disk (LVM layout needs ~204GB) 201 unit tests passing (11 new). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:26:33 +00:00
complete -c labctl -n "__labctl_in_cmd init bastion standalone start" -l port -d 'HTTP port' -x
complete -c labctl -n "__labctl_in_cmd init bastion standalone start" -l dir -d 'Bastion data directory' -x
complete -c labctl -n "__labctl_in_cmd init bastion standalone start" -l domain -d 'Internal domain for hostnames' -x
complete -c labctl -n "__labctl_in_cmd init bastion standalone start" -l dhcp-mode -d 'DHCP mode: proxy or full' -x
complete -c labctl -n "__labctl_in_cmd init bastion standalone start" -l fedora -d 'Fedora version' -x
complete -c labctl -n "__labctl_in_cmd init bastion standalone start" -l arch -d 'Architecture' -x
complete -c labctl -n "__labctl_in_cmd init bastion standalone start" -l timezone -d 'Timezone' -x
complete -c labctl -n "__labctl_in_cmd init bastion standalone start" -l locale -d 'Locale' -x
complete -c labctl -n "__labctl_in_cmd init bastion standalone start" -l skip-dnsmasq -d 'Skip starting dnsmasq (for testing)'
complete -c labctl -n "__labctl_in_cmd init bastion standalone start" -l skip-artifacts -d 'Skip downloading boot artifacts (for testing)'
complete -c labctl -n "__labctl_in_cmd init bastion standalone start" -l foreground -d 'Run in foreground (default: daemonize)'
# init bastion standalone stop options
feat: install logging, error trapping, PXE/ISO integration tests Kickstart installs on real hardware failed silently — no error reporting, only 3 progress callbacks, zero log streaming. This overhaul makes every install fully observable. Kickstart improvements: - Error trapping in %pre and %post (trap ERR sends failure details to bastion) - 12+ granular progress stages (was 3): SSH, hostname, k3s prep, EFI boot, metadata - Background log streamer: tails %post output and batch-sends to /api/log - bastion_log() function for explicit log lines from kickstart scripts Bastion API: - POST /api/log — receives raw log lines from kickstart (single or batch) - InstallLogBuffer — per-MAC ring buffer (2000 lines) + file persistence - GET /api/logs/:mac — now returns log_lines + log_total alongside stages - SSE /api/logs/:mac/follow — uses named events (event: stage vs event: log) - Progress events forwarded to labd via bastion-progress WebSocket message - Post-provision k3s logs routed through progressBus (was console-only) dnsmasq fixes found during VM testing: - HTTP Boot filename: ipxe-real.efi → ipxe.efi (leftover from old 2-stage approach) - pxe-service directives: only in proxy mode (breaks OVMF PXE in full mode) - PXEClient vendor class echo for UEFI firmware compatibility Integration tests: - PXE boot test: blank UEFI VM → dnsmasq → HTTP Boot → iPXE → bastion → install - ISO boot test: blank VM boots from bastion-generated ISO → same flow - Shared helpers: pxe-network (no DHCP, nftables fix), pxe-vm (UEFI + ISO boot) - test-provision.sh: runs both PXE + ISO tests with prerequisite checks - 250GB sparse QCOW2 disk (LVM layout needs ~204GB) 201 unit tests passing (11 new). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:26:33 +00:00
complete -c labctl -n "__labctl_in_cmd init bastion standalone stop" -l dir -d 'Bastion data directory' -x
# provision subcommands
complete -c labctl -n "__labctl_using_cmd provision" -a list -d 'List all known machines'
feat: install logging, error trapping, PXE/ISO integration tests Kickstart installs on real hardware failed silently — no error reporting, only 3 progress callbacks, zero log streaming. This overhaul makes every install fully observable. Kickstart improvements: - Error trapping in %pre and %post (trap ERR sends failure details to bastion) - 12+ granular progress stages (was 3): SSH, hostname, k3s prep, EFI boot, metadata - Background log streamer: tails %post output and batch-sends to /api/log - bastion_log() function for explicit log lines from kickstart scripts Bastion API: - POST /api/log — receives raw log lines from kickstart (single or batch) - InstallLogBuffer — per-MAC ring buffer (2000 lines) + file persistence - GET /api/logs/:mac — now returns log_lines + log_total alongside stages - SSE /api/logs/:mac/follow — uses named events (event: stage vs event: log) - Progress events forwarded to labd via bastion-progress WebSocket message - Post-provision k3s logs routed through progressBus (was console-only) dnsmasq fixes found during VM testing: - HTTP Boot filename: ipxe-real.efi → ipxe.efi (leftover from old 2-stage approach) - pxe-service directives: only in proxy mode (breaks OVMF PXE in full mode) - PXEClient vendor class echo for UEFI firmware compatibility Integration tests: - PXE boot test: blank UEFI VM → dnsmasq → HTTP Boot → iPXE → bastion → install - ISO boot test: blank VM boots from bastion-generated ISO → same flow - Shared helpers: pxe-network (no DHCP, nftables fix), pxe-vm (UEFI + ISO boot) - test-provision.sh: runs both PXE + ISO tests with prerequisite checks - 250GB sparse QCOW2 disk (LVM layout needs ~204GB) 201 unit tests passing (11 new). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:26:33 +00:00
complete -c labctl -n "__labctl_using_cmd provision" -a install -d 'Queue a discovered machine for OS installation'
complete -c labctl -n "__labctl_using_cmd provision" -a reprovision -d 'Queue install + SSH reboot into PXE (target: hostname, MAC, or IP)'
complete -c labctl -n "__labctl_using_cmd provision" -a debug -d 'PXE boot into Fedora rescue mode for debugging (target: hostname, MAC, or IP)'
complete -c labctl -n "__labctl_using_cmd provision" -a forget -d 'Remove a machine from bastion state'
complete -c labctl -n "__labctl_using_cmd provision" -a register -d 'Register an already-installed machine (e.g. after state loss)'
complete -c labctl -n "__labctl_using_cmd provision" -a asahi -d 'Show instructions to provision an Apple Silicon Mac with Asahi Linux'
feat: install logging, error trapping, PXE/ISO integration tests Kickstart installs on real hardware failed silently — no error reporting, only 3 progress callbacks, zero log streaming. This overhaul makes every install fully observable. Kickstart improvements: - Error trapping in %pre and %post (trap ERR sends failure details to bastion) - 12+ granular progress stages (was 3): SSH, hostname, k3s prep, EFI boot, metadata - Background log streamer: tails %post output and batch-sends to /api/log - bastion_log() function for explicit log lines from kickstart scripts Bastion API: - POST /api/log — receives raw log lines from kickstart (single or batch) - InstallLogBuffer — per-MAC ring buffer (2000 lines) + file persistence - GET /api/logs/:mac — now returns log_lines + log_total alongside stages - SSE /api/logs/:mac/follow — uses named events (event: stage vs event: log) - Progress events forwarded to labd via bastion-progress WebSocket message - Post-provision k3s logs routed through progressBus (was console-only) dnsmasq fixes found during VM testing: - HTTP Boot filename: ipxe-real.efi → ipxe.efi (leftover from old 2-stage approach) - pxe-service directives: only in proxy mode (breaks OVMF PXE in full mode) - PXEClient vendor class echo for UEFI firmware compatibility Integration tests: - PXE boot test: blank UEFI VM → dnsmasq → HTTP Boot → iPXE → bastion → install - ISO boot test: blank VM boots from bastion-generated ISO → same flow - Shared helpers: pxe-network (no DHCP, nftables fix), pxe-vm (UEFI + ISO boot) - test-provision.sh: runs both PXE + ISO tests with prerequisite checks - 250GB sparse QCOW2 disk (LVM layout needs ~204GB) 201 unit tests passing (11 new). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:26:33 +00:00
complete -c labctl -n "__labctl_using_cmd provision" -a logs -d 'Show provisioning logs for a machine (hostname, MAC, or IP)'
complete -c labctl -n "__labctl_using_cmd provision" -a makeiso -d 'Generate a UEFI-bootable iPXE ISO for network provisioning'
complete -c labctl -n "__labctl_using_cmd provision" -a recheck -d 'Refresh hardware info for all installed machines via SSH'
# provision install options
dedicated data disks: whole-disk longhorn/rancher volumes, by stable by-id path A machine with spare NVMe bays (thebeast: 1TB OS + 2TB + 2TB) wants the opposite trade from the fixed 250G/300G LVs that exist to FIT a 1TB disk: give /var/lib/longhorn and /var/lib/rancher a whole disk each and keep the OS VG small. Until now every generator was single-disk (ignoredisk --only-use=$DISK, one VG) and had no way to say that. New in the shared layout (v2 only): - DataDisks { longhorn?, rancher? }: /dev/disk/by-id paths ONLY, because nvme0n1/nvme1n1 enumeration is not stable across boots on multi-NVMe hosts and a swapped kernel name formats the wrong disk. - v2Layout() drops the LV whose mount a dedicated disk supplies. - validateDataDisks() shared by HTTP API, websocket handler and CLI, so all three reject with the same words: by-id enforced, capability-gated (no longhorn disk on a control-plane-only node, no rancher disk without k3s), no double-booking one disk. Fedora kickstart (the only generator extended; dataDisks on ubuntu/vyos are rejected, not dropped): - %pre resolves each by-id path to tonight's kernel name; a missing disk fails the install loudly instead of continuing single-disk. - Fresh disk: ONE xfs partition spanning it, labelled lab-longhorn / lab-rancher. --grow is correct here -- consuming the disk is the point, unlike LVs competing inside a shared VG. - The label is on-disk truth, exactly like the lab-schema-v2 VG tag: a reprovision rediscovers labelled disks via blkid with NO flags and mounts them --noformat; a fresh install refuses to wipe or shadow a labelled disk it was not told about; a label on the wrong disk, or a data LV coexisting with a dedicated disk, aborts rather than guesses. - --disk now also accepts a by-id path (resolved in %pre), and auto-detect can never pick a data disk as the OS disk. Plumbing: InstallConfig.dataDisks, POST /api/install validation, labctl provision install --longhorn-disk/--rancher-disk, labd forwarding. The labd command-install path also silently DROPPED schemaVersion (an explicit --schema-version 2 on a legacy role became v1 on the far side); it now travels with dataDisks in the protocol message. migration/THEBEAST-K8S-WORKER.md is the concrete runbook: disk map by serial, data still to copy off the degraded (zero-redundancy) rpool, VLAN move, the exact labctl command, and the k8s0 join with CI/CD taint. 569 tests pass (34 new), tsc --build clean, no new lint errors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V6HNx6cyr4J4CiMGCy1wkF
2026-10-14 18:58:37 +01:00
complete -c labctl -n "__labctl_in_cmd provision install" -l role -d 'Machine role (see below)' -xa 'vanilla worker infra labcontroller standalone-cluster k8s-controller k8s-worker k8s-combo'
complete -c labctl -n "__labctl_in_cmd provision install" -l os -d 'Operating system' -xa 'fedora-43 ubuntu-26.04 vyos-rolling'
dedicated data disks: whole-disk longhorn/rancher volumes, by stable by-id path A machine with spare NVMe bays (thebeast: 1TB OS + 2TB + 2TB) wants the opposite trade from the fixed 250G/300G LVs that exist to FIT a 1TB disk: give /var/lib/longhorn and /var/lib/rancher a whole disk each and keep the OS VG small. Until now every generator was single-disk (ignoredisk --only-use=$DISK, one VG) and had no way to say that. New in the shared layout (v2 only): - DataDisks { longhorn?, rancher? }: /dev/disk/by-id paths ONLY, because nvme0n1/nvme1n1 enumeration is not stable across boots on multi-NVMe hosts and a swapped kernel name formats the wrong disk. - v2Layout() drops the LV whose mount a dedicated disk supplies. - validateDataDisks() shared by HTTP API, websocket handler and CLI, so all three reject with the same words: by-id enforced, capability-gated (no longhorn disk on a control-plane-only node, no rancher disk without k3s), no double-booking one disk. Fedora kickstart (the only generator extended; dataDisks on ubuntu/vyos are rejected, not dropped): - %pre resolves each by-id path to tonight's kernel name; a missing disk fails the install loudly instead of continuing single-disk. - Fresh disk: ONE xfs partition spanning it, labelled lab-longhorn / lab-rancher. --grow is correct here -- consuming the disk is the point, unlike LVs competing inside a shared VG. - The label is on-disk truth, exactly like the lab-schema-v2 VG tag: a reprovision rediscovers labelled disks via blkid with NO flags and mounts them --noformat; a fresh install refuses to wipe or shadow a labelled disk it was not told about; a label on the wrong disk, or a data LV coexisting with a dedicated disk, aborts rather than guesses. - --disk now also accepts a by-id path (resolved in %pre), and auto-detect can never pick a data disk as the OS disk. Plumbing: InstallConfig.dataDisks, POST /api/install validation, labctl provision install --longhorn-disk/--rancher-disk, labd forwarding. The labd command-install path also silently DROPPED schemaVersion (an explicit --schema-version 2 on a legacy role became v1 on the far side); it now travels with dataDisks in the protocol message. migration/THEBEAST-K8S-WORKER.md is the concrete runbook: disk map by serial, data still to copy off the degraded (zero-redundancy) rpool, VLAN move, the exact labctl command, and the k8s0 join with CI/CD taint. 569 tests pass (34 new), tsc --build clean, no new lint errors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V6HNx6cyr4J4CiMGCy1wkF
2026-10-14 18:58:37 +01:00
complete -c labctl -n "__labctl_in_cmd provision install" -l disk -d 'Target OS disk: kernel name or stable /dev/disk/by-id/ path (auto-detect if omitted)' -x
complete -c labctl -n "__labctl_in_cmd provision install" -l schema-version -d 'Disk layout for a FRESH install (default 1). Ignored on reprovision: the layout already on the disk wins.' -xa '1 2'
complete -c labctl -n "__labctl_in_cmd provision install" -l longhorn-disk -d 'Dedicated whole disk for /var/lib/longhorn, as a stable /dev/disk/by-id/ path (fedora, schema v2 only)' -x
complete -c labctl -n "__labctl_in_cmd provision install" -l rancher-disk -d 'Dedicated whole disk for /var/lib/rancher, as a stable /dev/disk/by-id/ path (fedora, schema v2 only)' -x
complete -c labctl -n "__labctl_in_cmd provision install" -l vyos-mgmt -d 'VyOS: untagged interface the machine PXE boots from (default eth0)' -x
complete -c labctl -n "__labctl_in_cmd provision install" -l vyos-mgmt-address -d 'VyOS: CIDR for the management interface, or \'dhcp\' (default dhcp)' -x
complete -c labctl -n "__labctl_in_cmd provision install" -l vyos-bond -d 'VyOS: comma-separated LACP bond members (must exclude the PXE NIC)' -x
complete -c labctl -n "__labctl_in_cmd provision install" -l vyos-bond-address -d 'VyOS: address on the untagged bond (trunk native VLAN)' -x
complete -c labctl -n "__labctl_in_cmd provision install" -l vyos-bond-vrrp -d 'VyOS: VRRP VIP floated on the untagged bond' -x
complete -c labctl -n "__labctl_in_cmd provision install" -l vlan-vip -d 'VyOS: VRRP VIP for a --vlan entry (repeatable)' -x
complete -c labctl -n "__labctl_in_cmd provision install" -l vyos-vrrp-priority -d 'VyOS: VRRP priority for all groups on this box (higher = master)' -x
complete -c labctl -n "__labctl_in_cmd provision install" -l vyos-mgmt-vlan -d 'VyOS: tagged management VLAN on the PXE port' -x
complete -c labctl -n "__labctl_in_cmd provision install" -l vlan -d 'VyOS: tagged VLAN sub-interface on the bond (repeatable)' -x
complete -c labctl -n "__labctl_in_cmd provision install" -l vyos-password -d 'VyOS: password for the \'vyos\' user' -x
complete -c labctl -n "__labctl_in_cmd provision install" -l vyos-hwid -d 'VyOS: pin an interface name to a MAC via hw-id (repeatable)' -x
complete -c labctl -n "__labctl_in_cmd provision install" -l vyos-fresh-config -d 'VyOS: on reinstall, overwrite the preserved config with the generated one'
dedicated data disks: whole-disk longhorn/rancher volumes, by stable by-id path A machine with spare NVMe bays (thebeast: 1TB OS + 2TB + 2TB) wants the opposite trade from the fixed 250G/300G LVs that exist to FIT a 1TB disk: give /var/lib/longhorn and /var/lib/rancher a whole disk each and keep the OS VG small. Until now every generator was single-disk (ignoredisk --only-use=$DISK, one VG) and had no way to say that. New in the shared layout (v2 only): - DataDisks { longhorn?, rancher? }: /dev/disk/by-id paths ONLY, because nvme0n1/nvme1n1 enumeration is not stable across boots on multi-NVMe hosts and a swapped kernel name formats the wrong disk. - v2Layout() drops the LV whose mount a dedicated disk supplies. - validateDataDisks() shared by HTTP API, websocket handler and CLI, so all three reject with the same words: by-id enforced, capability-gated (no longhorn disk on a control-plane-only node, no rancher disk without k3s), no double-booking one disk. Fedora kickstart (the only generator extended; dataDisks on ubuntu/vyos are rejected, not dropped): - %pre resolves each by-id path to tonight's kernel name; a missing disk fails the install loudly instead of continuing single-disk. - Fresh disk: ONE xfs partition spanning it, labelled lab-longhorn / lab-rancher. --grow is correct here -- consuming the disk is the point, unlike LVs competing inside a shared VG. - The label is on-disk truth, exactly like the lab-schema-v2 VG tag: a reprovision rediscovers labelled disks via blkid with NO flags and mounts them --noformat; a fresh install refuses to wipe or shadow a labelled disk it was not told about; a label on the wrong disk, or a data LV coexisting with a dedicated disk, aborts rather than guesses. - --disk now also accepts a by-id path (resolved in %pre), and auto-detect can never pick a data disk as the OS disk. Plumbing: InstallConfig.dataDisks, POST /api/install validation, labctl provision install --longhorn-disk/--rancher-disk, labd forwarding. The labd command-install path also silently DROPPED schemaVersion (an explicit --schema-version 2 on a legacy role became v1 on the far side); it now travels with dataDisks in the protocol message. migration/THEBEAST-K8S-WORKER.md is the concrete runbook: disk map by serial, data still to copy off the degraded (zero-redundancy) rpool, VLAN move, the exact labctl command, and the k8s0 join with CI/CD taint. 569 tests pass (34 new), tsc --build clean, no new lint errors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V6HNx6cyr4J4CiMGCy1wkF
2026-10-14 18:58:37 +01:00
complete -c labctl -n "__labctl_in_cmd provision install" -l vyos-bundle -d 'VyOS: apply a Pulumi-rendered bundle verbatim (kubernetes-deployment/infra/vyos/vyos-bundle.json). Replaces the derived --vyos-bond/--vlan/... config; secret values are left unset for `pulumi up`.' -x
complete -c labctl -n "__labctl_in_cmd provision install" -l vyos-api-key -d 'VyOS: enable the HTTP API with this key so Pulumi can manage the router from first boot' -x
complete -c labctl -n "__labctl_in_cmd provision install" -l vyos-api-listen -d 'VyOS: address the HTTP API binds to (default: the static management address). Required when management is DHCP; the API is never bound to all interfaces.' -x
# provision reprovision options
dedicated data disks: whole-disk longhorn/rancher volumes, by stable by-id path A machine with spare NVMe bays (thebeast: 1TB OS + 2TB + 2TB) wants the opposite trade from the fixed 250G/300G LVs that exist to FIT a 1TB disk: give /var/lib/longhorn and /var/lib/rancher a whole disk each and keep the OS VG small. Until now every generator was single-disk (ignoredisk --only-use=$DISK, one VG) and had no way to say that. New in the shared layout (v2 only): - DataDisks { longhorn?, rancher? }: /dev/disk/by-id paths ONLY, because nvme0n1/nvme1n1 enumeration is not stable across boots on multi-NVMe hosts and a swapped kernel name formats the wrong disk. - v2Layout() drops the LV whose mount a dedicated disk supplies. - validateDataDisks() shared by HTTP API, websocket handler and CLI, so all three reject with the same words: by-id enforced, capability-gated (no longhorn disk on a control-plane-only node, no rancher disk without k3s), no double-booking one disk. Fedora kickstart (the only generator extended; dataDisks on ubuntu/vyos are rejected, not dropped): - %pre resolves each by-id path to tonight's kernel name; a missing disk fails the install loudly instead of continuing single-disk. - Fresh disk: ONE xfs partition spanning it, labelled lab-longhorn / lab-rancher. --grow is correct here -- consuming the disk is the point, unlike LVs competing inside a shared VG. - The label is on-disk truth, exactly like the lab-schema-v2 VG tag: a reprovision rediscovers labelled disks via blkid with NO flags and mounts them --noformat; a fresh install refuses to wipe or shadow a labelled disk it was not told about; a label on the wrong disk, or a data LV coexisting with a dedicated disk, aborts rather than guesses. - --disk now also accepts a by-id path (resolved in %pre), and auto-detect can never pick a data disk as the OS disk. Plumbing: InstallConfig.dataDisks, POST /api/install validation, labctl provision install --longhorn-disk/--rancher-disk, labd forwarding. The labd command-install path also silently DROPPED schemaVersion (an explicit --schema-version 2 on a legacy role became v1 on the far side); it now travels with dataDisks in the protocol message. migration/THEBEAST-K8S-WORKER.md is the concrete runbook: disk map by serial, data still to copy off the degraded (zero-redundancy) rpool, VLAN move, the exact labctl command, and the k8s0 join with CI/CD taint. 569 tests pass (34 new), tsc --build clean, no new lint errors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V6HNx6cyr4J4CiMGCy1wkF
2026-10-14 18:58:37 +01:00
complete -c labctl -n "__labctl_in_cmd provision reprovision" -l role -d 'Machine role (see below)' -xa 'vanilla worker infra labcontroller standalone-cluster k8s-controller k8s-worker k8s-combo'
complete -c labctl -n "__labctl_in_cmd provision reprovision" -l os -d 'Operating system' -xa 'fedora-43 ubuntu-26.04 vyos-rolling'
feat: install logging, error trapping, PXE/ISO integration tests Kickstart installs on real hardware failed silently — no error reporting, only 3 progress callbacks, zero log streaming. This overhaul makes every install fully observable. Kickstart improvements: - Error trapping in %pre and %post (trap ERR sends failure details to bastion) - 12+ granular progress stages (was 3): SSH, hostname, k3s prep, EFI boot, metadata - Background log streamer: tails %post output and batch-sends to /api/log - bastion_log() function for explicit log lines from kickstart scripts Bastion API: - POST /api/log — receives raw log lines from kickstart (single or batch) - InstallLogBuffer — per-MAC ring buffer (2000 lines) + file persistence - GET /api/logs/:mac — now returns log_lines + log_total alongside stages - SSE /api/logs/:mac/follow — uses named events (event: stage vs event: log) - Progress events forwarded to labd via bastion-progress WebSocket message - Post-provision k3s logs routed through progressBus (was console-only) dnsmasq fixes found during VM testing: - HTTP Boot filename: ipxe-real.efi → ipxe.efi (leftover from old 2-stage approach) - pxe-service directives: only in proxy mode (breaks OVMF PXE in full mode) - PXEClient vendor class echo for UEFI firmware compatibility Integration tests: - PXE boot test: blank UEFI VM → dnsmasq → HTTP Boot → iPXE → bastion → install - ISO boot test: blank VM boots from bastion-generated ISO → same flow - Shared helpers: pxe-network (no DHCP, nftables fix), pxe-vm (UEFI + ISO boot) - test-provision.sh: runs both PXE + ISO tests with prerequisite checks - 250GB sparse QCOW2 disk (LVM layout needs ~204GB) 201 unit tests passing (11 new). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:26:33 +00:00
complete -c labctl -n "__labctl_in_cmd provision reprovision" -l disk -d 'Target disk device (auto-detect if omitted)' -x
complete -c labctl -n "__labctl_in_cmd provision reprovision" -l user -d 'SSH user for the reboot (default: vyos for VyOS machines, else current user)' -x
feat: install logging, error trapping, PXE/ISO integration tests Kickstart installs on real hardware failed silently — no error reporting, only 3 progress callbacks, zero log streaming. This overhaul makes every install fully observable. Kickstart improvements: - Error trapping in %pre and %post (trap ERR sends failure details to bastion) - 12+ granular progress stages (was 3): SSH, hostname, k3s prep, EFI boot, metadata - Background log streamer: tails %post output and batch-sends to /api/log - bastion_log() function for explicit log lines from kickstart scripts Bastion API: - POST /api/log — receives raw log lines from kickstart (single or batch) - InstallLogBuffer — per-MAC ring buffer (2000 lines) + file persistence - GET /api/logs/:mac — now returns log_lines + log_total alongside stages - SSE /api/logs/:mac/follow — uses named events (event: stage vs event: log) - Progress events forwarded to labd via bastion-progress WebSocket message - Post-provision k3s logs routed through progressBus (was console-only) dnsmasq fixes found during VM testing: - HTTP Boot filename: ipxe-real.efi → ipxe.efi (leftover from old 2-stage approach) - pxe-service directives: only in proxy mode (breaks OVMF PXE in full mode) - PXEClient vendor class echo for UEFI firmware compatibility Integration tests: - PXE boot test: blank UEFI VM → dnsmasq → HTTP Boot → iPXE → bastion → install - ISO boot test: blank VM boots from bastion-generated ISO → same flow - Shared helpers: pxe-network (no DHCP, nftables fix), pxe-vm (UEFI + ISO boot) - test-provision.sh: runs both PXE + ISO tests with prerequisite checks - 250GB sparse QCOW2 disk (LVM layout needs ~204GB) 201 unit tests passing (11 new). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:26:33 +00:00
# provision debug options
complete -c labctl -n "__labctl_in_cmd provision debug" -l pxe-boot -d 'Boot installed system via PXE (kernel+initrd from network, root from NVMe)'
# provision register options
dedicated data disks: whole-disk longhorn/rancher volumes, by stable by-id path A machine with spare NVMe bays (thebeast: 1TB OS + 2TB + 2TB) wants the opposite trade from the fixed 250G/300G LVs that exist to FIT a 1TB disk: give /var/lib/longhorn and /var/lib/rancher a whole disk each and keep the OS VG small. Until now every generator was single-disk (ignoredisk --only-use=$DISK, one VG) and had no way to say that. New in the shared layout (v2 only): - DataDisks { longhorn?, rancher? }: /dev/disk/by-id paths ONLY, because nvme0n1/nvme1n1 enumeration is not stable across boots on multi-NVMe hosts and a swapped kernel name formats the wrong disk. - v2Layout() drops the LV whose mount a dedicated disk supplies. - validateDataDisks() shared by HTTP API, websocket handler and CLI, so all three reject with the same words: by-id enforced, capability-gated (no longhorn disk on a control-plane-only node, no rancher disk without k3s), no double-booking one disk. Fedora kickstart (the only generator extended; dataDisks on ubuntu/vyos are rejected, not dropped): - %pre resolves each by-id path to tonight's kernel name; a missing disk fails the install loudly instead of continuing single-disk. - Fresh disk: ONE xfs partition spanning it, labelled lab-longhorn / lab-rancher. --grow is correct here -- consuming the disk is the point, unlike LVs competing inside a shared VG. - The label is on-disk truth, exactly like the lab-schema-v2 VG tag: a reprovision rediscovers labelled disks via blkid with NO flags and mounts them --noformat; a fresh install refuses to wipe or shadow a labelled disk it was not told about; a label on the wrong disk, or a data LV coexisting with a dedicated disk, aborts rather than guesses. - --disk now also accepts a by-id path (resolved in %pre), and auto-detect can never pick a data disk as the OS disk. Plumbing: InstallConfig.dataDisks, POST /api/install validation, labctl provision install --longhorn-disk/--rancher-disk, labd forwarding. The labd command-install path also silently DROPPED schemaVersion (an explicit --schema-version 2 on a legacy role became v1 on the far side); it now travels with dataDisks in the protocol message. migration/THEBEAST-K8S-WORKER.md is the concrete runbook: disk map by serial, data still to copy off the degraded (zero-redundancy) rpool, VLAN move, the exact labctl command, and the k8s0 join with CI/CD taint. 569 tests pass (34 new), tsc --build clean, no new lint errors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V6HNx6cyr4J4CiMGCy1wkF
2026-10-14 18:58:37 +01:00
complete -c labctl -n "__labctl_in_cmd provision register" -l role -d 'Machine role' -xa 'vanilla worker infra labcontroller standalone-cluster k8s-controller k8s-worker k8s-combo'
complete -c labctl -n "__labctl_in_cmd provision register" -l ip -d 'Machine IP address' -x
# provision logs options
complete -c labctl -n "__labctl_in_cmd provision logs" -s f -l follow -d 'Follow log output in real-time'
# provision makeiso options
complete -c labctl -n "__labctl_in_cmd provision makeiso" -l arch -d 'Target architecture(s)' -xa 'x86_64 aarch64'
complete -c labctl -n "__labctl_in_cmd provision makeiso" -l local -d 'Build ISO locally instead of using bastion-hosted URL'
complete -c labctl -n "__labctl_in_cmd provision makeiso" -l out -d 'Output path for local ISO build' -x
feat: install logging, error trapping, PXE/ISO integration tests Kickstart installs on real hardware failed silently — no error reporting, only 3 progress callbacks, zero log streaming. This overhaul makes every install fully observable. Kickstart improvements: - Error trapping in %pre and %post (trap ERR sends failure details to bastion) - 12+ granular progress stages (was 3): SSH, hostname, k3s prep, EFI boot, metadata - Background log streamer: tails %post output and batch-sends to /api/log - bastion_log() function for explicit log lines from kickstart scripts Bastion API: - POST /api/log — receives raw log lines from kickstart (single or batch) - InstallLogBuffer — per-MAC ring buffer (2000 lines) + file persistence - GET /api/logs/:mac — now returns log_lines + log_total alongside stages - SSE /api/logs/:mac/follow — uses named events (event: stage vs event: log) - Progress events forwarded to labd via bastion-progress WebSocket message - Post-provision k3s logs routed through progressBus (was console-only) dnsmasq fixes found during VM testing: - HTTP Boot filename: ipxe-real.efi → ipxe.efi (leftover from old 2-stage approach) - pxe-service directives: only in proxy mode (breaks OVMF PXE in full mode) - PXEClient vendor class echo for UEFI firmware compatibility Integration tests: - PXE boot test: blank UEFI VM → dnsmasq → HTTP Boot → iPXE → bastion → install - ISO boot test: blank VM boots from bastion-generated ISO → same flow - Shared helpers: pxe-network (no DHCP, nftables fix), pxe-vm (UEFI + ISO boot) - test-provision.sh: runs both PXE + ISO tests with prerequisite checks - 250GB sparse QCOW2 disk (LVM layout needs ~204GB) 201 unit tests passing (11 new). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:26:33 +00:00
# provision recheck options
complete -c labctl -n "__labctl_in_cmd provision recheck" -l user -d 'SSH user' -x
complete -c labctl -n "__labctl_in_cmd provision recheck" -l target -d 'Only recheck a specific machine (by hostname or MAC)' -x
feat: install logging, error trapping, PXE/ISO integration tests Kickstart installs on real hardware failed silently — no error reporting, only 3 progress callbacks, zero log streaming. This overhaul makes every install fully observable. Kickstart improvements: - Error trapping in %pre and %post (trap ERR sends failure details to bastion) - 12+ granular progress stages (was 3): SSH, hostname, k3s prep, EFI boot, metadata - Background log streamer: tails %post output and batch-sends to /api/log - bastion_log() function for explicit log lines from kickstart scripts Bastion API: - POST /api/log — receives raw log lines from kickstart (single or batch) - InstallLogBuffer — per-MAC ring buffer (2000 lines) + file persistence - GET /api/logs/:mac — now returns log_lines + log_total alongside stages - SSE /api/logs/:mac/follow — uses named events (event: stage vs event: log) - Progress events forwarded to labd via bastion-progress WebSocket message - Post-provision k3s logs routed through progressBus (was console-only) dnsmasq fixes found during VM testing: - HTTP Boot filename: ipxe-real.efi → ipxe.efi (leftover from old 2-stage approach) - pxe-service directives: only in proxy mode (breaks OVMF PXE in full mode) - PXEClient vendor class echo for UEFI firmware compatibility Integration tests: - PXE boot test: blank UEFI VM → dnsmasq → HTTP Boot → iPXE → bastion → install - ISO boot test: blank VM boots from bastion-generated ISO → same flow - Shared helpers: pxe-network (no DHCP, nftables fix), pxe-vm (UEFI + ISO boot) - test-provision.sh: runs both PXE + ISO tests with prerequisite checks - 250GB sparse QCOW2 disk (LVM layout needs ~204GB) 201 unit tests passing (11 new). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:26:33 +00:00
# config subcommands
complete -c labctl -n "__labctl_using_cmd config" -a list -d 'Show all configuration values'
complete -c labctl -n "__labctl_using_cmd config" -a get -d 'Get a configuration value'
complete -c labctl -n "__labctl_using_cmd config" -a set -d 'Set a configuration value'
complete -c labctl -n "__labctl_using_cmd config" -a path -d 'Show configuration file path'
# login options
complete -c labctl -n "__labctl_in_cmd login" -l server -d 'labd server URL' -x
# doctor options
complete -c labctl -n "__labctl_in_cmd doctor" -l json -d 'Output results as JSON'
# app subcommands
complete -c labctl -n "__labctl_using_cmd app" -a labcontroller -d 'Labcontroller deployment (bastion + labd + CockroachDB)'
complete -c labctl -n "__labctl_using_cmd app" -a k3s -d 'k3s cluster management'
# app labcontroller subcommands
complete -c labctl -n "__labctl_using_cmd app labcontroller" -a deploy -d 'Deploy labcontroller stack to a k3s node'
complete -c labctl -n "__labctl_using_cmd app labcontroller" -a status -d 'Check labcontroller deployment status (all hosts if no target)'
# app labcontroller deploy options
complete -c labctl -n "__labctl_in_cmd app labcontroller deploy" -l user -d 'SSH user' -x
complete -c labctl -n "__labctl_in_cmd app labcontroller deploy" -l crdb-replicas -d 'CockroachDB replicas' -x
# app labcontroller status options
complete -c labctl -n "__labctl_in_cmd app labcontroller status" -l user -d 'SSH user' -x
# app k3s subcommands
dedicated data disks: whole-disk longhorn/rancher volumes, by stable by-id path A machine with spare NVMe bays (thebeast: 1TB OS + 2TB + 2TB) wants the opposite trade from the fixed 250G/300G LVs that exist to FIT a 1TB disk: give /var/lib/longhorn and /var/lib/rancher a whole disk each and keep the OS VG small. Until now every generator was single-disk (ignoredisk --only-use=$DISK, one VG) and had no way to say that. New in the shared layout (v2 only): - DataDisks { longhorn?, rancher? }: /dev/disk/by-id paths ONLY, because nvme0n1/nvme1n1 enumeration is not stable across boots on multi-NVMe hosts and a swapped kernel name formats the wrong disk. - v2Layout() drops the LV whose mount a dedicated disk supplies. - validateDataDisks() shared by HTTP API, websocket handler and CLI, so all three reject with the same words: by-id enforced, capability-gated (no longhorn disk on a control-plane-only node, no rancher disk without k3s), no double-booking one disk. Fedora kickstart (the only generator extended; dataDisks on ubuntu/vyos are rejected, not dropped): - %pre resolves each by-id path to tonight's kernel name; a missing disk fails the install loudly instead of continuing single-disk. - Fresh disk: ONE xfs partition spanning it, labelled lab-longhorn / lab-rancher. --grow is correct here -- consuming the disk is the point, unlike LVs competing inside a shared VG. - The label is on-disk truth, exactly like the lab-schema-v2 VG tag: a reprovision rediscovers labelled disks via blkid with NO flags and mounts them --noformat; a fresh install refuses to wipe or shadow a labelled disk it was not told about; a label on the wrong disk, or a data LV coexisting with a dedicated disk, aborts rather than guesses. - --disk now also accepts a by-id path (resolved in %pre), and auto-detect can never pick a data disk as the OS disk. Plumbing: InstallConfig.dataDisks, POST /api/install validation, labctl provision install --longhorn-disk/--rancher-disk, labd forwarding. The labd command-install path also silently DROPPED schemaVersion (an explicit --schema-version 2 on a legacy role became v1 on the far side); it now travels with dataDisks in the protocol message. migration/THEBEAST-K8S-WORKER.md is the concrete runbook: disk map by serial, data still to copy off the degraded (zero-redundancy) rpool, VLAN move, the exact labctl command, and the k8s0 join with CI/CD taint. 569 tests pass (34 new), tsc --build clean, no new lint errors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V6HNx6cyr4J4CiMGCy1wkF
2026-10-14 18:58:37 +01:00
complete -c labctl -n "__labctl_using_cmd app k3s" -a evacuate -d 'Cordon, evict Longhorn replicas and drain so a node can be safely wiped'
complete -c labctl -n "__labctl_using_cmd app k3s" -a admit -d 'Return an evacuated node to service: uncordon, clear eviction, restore its Longhorn disk'
feat: install logging, error trapping, PXE/ISO integration tests Kickstart installs on real hardware failed silently — no error reporting, only 3 progress callbacks, zero log streaming. This overhaul makes every install fully observable. Kickstart improvements: - Error trapping in %pre and %post (trap ERR sends failure details to bastion) - 12+ granular progress stages (was 3): SSH, hostname, k3s prep, EFI boot, metadata - Background log streamer: tails %post output and batch-sends to /api/log - bastion_log() function for explicit log lines from kickstart scripts Bastion API: - POST /api/log — receives raw log lines from kickstart (single or batch) - InstallLogBuffer — per-MAC ring buffer (2000 lines) + file persistence - GET /api/logs/:mac — now returns log_lines + log_total alongside stages - SSE /api/logs/:mac/follow — uses named events (event: stage vs event: log) - Progress events forwarded to labd via bastion-progress WebSocket message - Post-provision k3s logs routed through progressBus (was console-only) dnsmasq fixes found during VM testing: - HTTP Boot filename: ipxe-real.efi → ipxe.efi (leftover from old 2-stage approach) - pxe-service directives: only in proxy mode (breaks OVMF PXE in full mode) - PXEClient vendor class echo for UEFI firmware compatibility Integration tests: - PXE boot test: blank UEFI VM → dnsmasq → HTTP Boot → iPXE → bastion → install - ISO boot test: blank VM boots from bastion-generated ISO → same flow - Shared helpers: pxe-network (no DHCP, nftables fix), pxe-vm (UEFI + ISO boot) - test-provision.sh: runs both PXE + ISO tests with prerequisite checks - 250GB sparse QCOW2 disk (LVM layout needs ~204GB) 201 unit tests passing (11 new). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:26:33 +00:00
complete -c labctl -n "__labctl_using_cmd app k3s" -a install -d 'Install k3s on a target machine (hostname, IP, or MAC)'
complete -c labctl -n "__labctl_using_cmd app k3s" -a health -d 'Check k3s health (all hosts if no target given)'
complete -c labctl -n "__labctl_using_cmd app k3s" -a list -d 'List installed machines and their k3s status'
complete -c labctl -n "__labctl_using_cmd app k3s" -a kubeconfig -d 'Fetch kubeconfig from a target and merge into ~/.kube/config'
feat: install logging, error trapping, PXE/ISO integration tests Kickstart installs on real hardware failed silently — no error reporting, only 3 progress callbacks, zero log streaming. This overhaul makes every install fully observable. Kickstart improvements: - Error trapping in %pre and %post (trap ERR sends failure details to bastion) - 12+ granular progress stages (was 3): SSH, hostname, k3s prep, EFI boot, metadata - Background log streamer: tails %post output and batch-sends to /api/log - bastion_log() function for explicit log lines from kickstart scripts Bastion API: - POST /api/log — receives raw log lines from kickstart (single or batch) - InstallLogBuffer — per-MAC ring buffer (2000 lines) + file persistence - GET /api/logs/:mac — now returns log_lines + log_total alongside stages - SSE /api/logs/:mac/follow — uses named events (event: stage vs event: log) - Progress events forwarded to labd via bastion-progress WebSocket message - Post-provision k3s logs routed through progressBus (was console-only) dnsmasq fixes found during VM testing: - HTTP Boot filename: ipxe-real.efi → ipxe.efi (leftover from old 2-stage approach) - pxe-service directives: only in proxy mode (breaks OVMF PXE in full mode) - PXEClient vendor class echo for UEFI firmware compatibility Integration tests: - PXE boot test: blank UEFI VM → dnsmasq → HTTP Boot → iPXE → bastion → install - ISO boot test: blank VM boots from bastion-generated ISO → same flow - Shared helpers: pxe-network (no DHCP, nftables fix), pxe-vm (UEFI + ISO boot) - test-provision.sh: runs both PXE + ISO tests with prerequisite checks - 250GB sparse QCOW2 disk (LVM layout needs ~204GB) 201 unit tests passing (11 new). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:26:33 +00:00
dedicated data disks: whole-disk longhorn/rancher volumes, by stable by-id path A machine with spare NVMe bays (thebeast: 1TB OS + 2TB + 2TB) wants the opposite trade from the fixed 250G/300G LVs that exist to FIT a 1TB disk: give /var/lib/longhorn and /var/lib/rancher a whole disk each and keep the OS VG small. Until now every generator was single-disk (ignoredisk --only-use=$DISK, one VG) and had no way to say that. New in the shared layout (v2 only): - DataDisks { longhorn?, rancher? }: /dev/disk/by-id paths ONLY, because nvme0n1/nvme1n1 enumeration is not stable across boots on multi-NVMe hosts and a swapped kernel name formats the wrong disk. - v2Layout() drops the LV whose mount a dedicated disk supplies. - validateDataDisks() shared by HTTP API, websocket handler and CLI, so all three reject with the same words: by-id enforced, capability-gated (no longhorn disk on a control-plane-only node, no rancher disk without k3s), no double-booking one disk. Fedora kickstart (the only generator extended; dataDisks on ubuntu/vyos are rejected, not dropped): - %pre resolves each by-id path to tonight's kernel name; a missing disk fails the install loudly instead of continuing single-disk. - Fresh disk: ONE xfs partition spanning it, labelled lab-longhorn / lab-rancher. --grow is correct here -- consuming the disk is the point, unlike LVs competing inside a shared VG. - The label is on-disk truth, exactly like the lab-schema-v2 VG tag: a reprovision rediscovers labelled disks via blkid with NO flags and mounts them --noformat; a fresh install refuses to wipe or shadow a labelled disk it was not told about; a label on the wrong disk, or a data LV coexisting with a dedicated disk, aborts rather than guesses. - --disk now also accepts a by-id path (resolved in %pre), and auto-detect can never pick a data disk as the OS disk. Plumbing: InstallConfig.dataDisks, POST /api/install validation, labctl provision install --longhorn-disk/--rancher-disk, labd forwarding. The labd command-install path also silently DROPPED schemaVersion (an explicit --schema-version 2 on a legacy role became v1 on the far side); it now travels with dataDisks in the protocol message. migration/THEBEAST-K8S-WORKER.md is the concrete runbook: disk map by serial, data still to copy off the degraded (zero-redundancy) rpool, VLAN move, the exact labctl command, and the k8s0 join with CI/CD taint. 569 tests pass (34 new), tsc --build clean, no new lint errors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V6HNx6cyr4J4CiMGCy1wkF
2026-10-14 18:58:37 +01:00
# app k3s evacuate options
complete -c labctl -n "__labctl_in_cmd app k3s evacuate" -l user -d 'SSH user' -x
complete -c labctl -n "__labctl_in_cmd app k3s evacuate" -l allow-single-replica -d 'permit evacuating volumes that have only one replica (rebuilds from the only copy; there is no backup target)'
# app k3s admit options
complete -c labctl -n "__labctl_in_cmd app k3s admit" -l user -d 'SSH user' -x
feat: install logging, error trapping, PXE/ISO integration tests Kickstart installs on real hardware failed silently — no error reporting, only 3 progress callbacks, zero log streaming. This overhaul makes every install fully observable. Kickstart improvements: - Error trapping in %pre and %post (trap ERR sends failure details to bastion) - 12+ granular progress stages (was 3): SSH, hostname, k3s prep, EFI boot, metadata - Background log streamer: tails %post output and batch-sends to /api/log - bastion_log() function for explicit log lines from kickstart scripts Bastion API: - POST /api/log — receives raw log lines from kickstart (single or batch) - InstallLogBuffer — per-MAC ring buffer (2000 lines) + file persistence - GET /api/logs/:mac — now returns log_lines + log_total alongside stages - SSE /api/logs/:mac/follow — uses named events (event: stage vs event: log) - Progress events forwarded to labd via bastion-progress WebSocket message - Post-provision k3s logs routed through progressBus (was console-only) dnsmasq fixes found during VM testing: - HTTP Boot filename: ipxe-real.efi → ipxe.efi (leftover from old 2-stage approach) - pxe-service directives: only in proxy mode (breaks OVMF PXE in full mode) - PXEClient vendor class echo for UEFI firmware compatibility Integration tests: - PXE boot test: blank UEFI VM → dnsmasq → HTTP Boot → iPXE → bastion → install - ISO boot test: blank VM boots from bastion-generated ISO → same flow - Shared helpers: pxe-network (no DHCP, nftables fix), pxe-vm (UEFI + ISO boot) - test-provision.sh: runs both PXE + ISO tests with prerequisite checks - 250GB sparse QCOW2 disk (LVM layout needs ~204GB) 201 unit tests passing (11 new). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:26:33 +00:00
# app k3s install options
dedicated data disks: whole-disk longhorn/rancher volumes, by stable by-id path A machine with spare NVMe bays (thebeast: 1TB OS + 2TB + 2TB) wants the opposite trade from the fixed 250G/300G LVs that exist to FIT a 1TB disk: give /var/lib/longhorn and /var/lib/rancher a whole disk each and keep the OS VG small. Until now every generator was single-disk (ignoredisk --only-use=$DISK, one VG) and had no way to say that. New in the shared layout (v2 only): - DataDisks { longhorn?, rancher? }: /dev/disk/by-id paths ONLY, because nvme0n1/nvme1n1 enumeration is not stable across boots on multi-NVMe hosts and a swapped kernel name formats the wrong disk. - v2Layout() drops the LV whose mount a dedicated disk supplies. - validateDataDisks() shared by HTTP API, websocket handler and CLI, so all three reject with the same words: by-id enforced, capability-gated (no longhorn disk on a control-plane-only node, no rancher disk without k3s), no double-booking one disk. Fedora kickstart (the only generator extended; dataDisks on ubuntu/vyos are rejected, not dropped): - %pre resolves each by-id path to tonight's kernel name; a missing disk fails the install loudly instead of continuing single-disk. - Fresh disk: ONE xfs partition spanning it, labelled lab-longhorn / lab-rancher. --grow is correct here -- consuming the disk is the point, unlike LVs competing inside a shared VG. - The label is on-disk truth, exactly like the lab-schema-v2 VG tag: a reprovision rediscovers labelled disks via blkid with NO flags and mounts them --noformat; a fresh install refuses to wipe or shadow a labelled disk it was not told about; a label on the wrong disk, or a data LV coexisting with a dedicated disk, aborts rather than guesses. - --disk now also accepts a by-id path (resolved in %pre), and auto-detect can never pick a data disk as the OS disk. Plumbing: InstallConfig.dataDisks, POST /api/install validation, labctl provision install --longhorn-disk/--rancher-disk, labd forwarding. The labd command-install path also silently DROPPED schemaVersion (an explicit --schema-version 2 on a legacy role became v1 on the far side); it now travels with dataDisks in the protocol message. migration/THEBEAST-K8S-WORKER.md is the concrete runbook: disk map by serial, data still to copy off the degraded (zero-redundancy) rpool, VLAN move, the exact labctl command, and the k8s0 join with CI/CD taint. 569 tests pass (34 new), tsc --build clean, no new lint errors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V6HNx6cyr4J4CiMGCy1wkF
2026-10-14 18:58:37 +01:00
complete -c labctl -n "__labctl_in_cmd app k3s install" -l role -d 'k3s role: infra, labcontroller, standalone-cluster, k8s-controller, k8s-combo (servers) or worker, k8s-worker (agents)' -x
feat: install logging, error trapping, PXE/ISO integration tests Kickstart installs on real hardware failed silently — no error reporting, only 3 progress callbacks, zero log streaming. This overhaul makes every install fully observable. Kickstart improvements: - Error trapping in %pre and %post (trap ERR sends failure details to bastion) - 12+ granular progress stages (was 3): SSH, hostname, k3s prep, EFI boot, metadata - Background log streamer: tails %post output and batch-sends to /api/log - bastion_log() function for explicit log lines from kickstart scripts Bastion API: - POST /api/log — receives raw log lines from kickstart (single or batch) - InstallLogBuffer — per-MAC ring buffer (2000 lines) + file persistence - GET /api/logs/:mac — now returns log_lines + log_total alongside stages - SSE /api/logs/:mac/follow — uses named events (event: stage vs event: log) - Progress events forwarded to labd via bastion-progress WebSocket message - Post-provision k3s logs routed through progressBus (was console-only) dnsmasq fixes found during VM testing: - HTTP Boot filename: ipxe-real.efi → ipxe.efi (leftover from old 2-stage approach) - pxe-service directives: only in proxy mode (breaks OVMF PXE in full mode) - PXEClient vendor class echo for UEFI firmware compatibility Integration tests: - PXE boot test: blank UEFI VM → dnsmasq → HTTP Boot → iPXE → bastion → install - ISO boot test: blank VM boots from bastion-generated ISO → same flow - Shared helpers: pxe-network (no DHCP, nftables fix), pxe-vm (UEFI + ISO boot) - test-provision.sh: runs both PXE + ISO tests with prerequisite checks - 250GB sparse QCOW2 disk (LVM layout needs ~204GB) 201 unit tests passing (11 new). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:26:33 +00:00
complete -c labctl -n "__labctl_in_cmd app k3s install" -l user -d 'SSH user' -x
dedicated data disks: whole-disk longhorn/rancher volumes, by stable by-id path A machine with spare NVMe bays (thebeast: 1TB OS + 2TB + 2TB) wants the opposite trade from the fixed 250G/300G LVs that exist to FIT a 1TB disk: give /var/lib/longhorn and /var/lib/rancher a whole disk each and keep the OS VG small. Until now every generator was single-disk (ignoredisk --only-use=$DISK, one VG) and had no way to say that. New in the shared layout (v2 only): - DataDisks { longhorn?, rancher? }: /dev/disk/by-id paths ONLY, because nvme0n1/nvme1n1 enumeration is not stable across boots on multi-NVMe hosts and a swapped kernel name formats the wrong disk. - v2Layout() drops the LV whose mount a dedicated disk supplies. - validateDataDisks() shared by HTTP API, websocket handler and CLI, so all three reject with the same words: by-id enforced, capability-gated (no longhorn disk on a control-plane-only node, no rancher disk without k3s), no double-booking one disk. Fedora kickstart (the only generator extended; dataDisks on ubuntu/vyos are rejected, not dropped): - %pre resolves each by-id path to tonight's kernel name; a missing disk fails the install loudly instead of continuing single-disk. - Fresh disk: ONE xfs partition spanning it, labelled lab-longhorn / lab-rancher. --grow is correct here -- consuming the disk is the point, unlike LVs competing inside a shared VG. - The label is on-disk truth, exactly like the lab-schema-v2 VG tag: a reprovision rediscovers labelled disks via blkid with NO flags and mounts them --noformat; a fresh install refuses to wipe or shadow a labelled disk it was not told about; a label on the wrong disk, or a data LV coexisting with a dedicated disk, aborts rather than guesses. - --disk now also accepts a by-id path (resolved in %pre), and auto-detect can never pick a data disk as the OS disk. Plumbing: InstallConfig.dataDisks, POST /api/install validation, labctl provision install --longhorn-disk/--rancher-disk, labd forwarding. The labd command-install path also silently DROPPED schemaVersion (an explicit --schema-version 2 on a legacy role became v1 on the far side); it now travels with dataDisks in the protocol message. migration/THEBEAST-K8S-WORKER.md is the concrete runbook: disk map by serial, data still to copy off the degraded (zero-redundancy) rpool, VLAN move, the exact labctl command, and the k8s0 join with CI/CD taint. 569 tests pass (34 new), tsc --build clean, no new lint errors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V6HNx6cyr4J4CiMGCy1wkF
2026-10-14 18:58:37 +01:00
complete -c labctl -n "__labctl_in_cmd app k3s install" -l k3s-server -d 'k3s server URL (required for agent roles, and to JOIN as a server)' -x
complete -c labctl -n "__labctl_in_cmd app k3s install" -l k3s-token -d 'k3s join token; on a first server it SEEDS the cluster token' -x
complete -c labctl -n "__labctl_in_cmd app k3s install" -l k3s-version -d 'exact k3s version, e.g. v1.34.6+k3s1. Unset installs LATEST, which on a rejoining node can be several minor versions ahead of the cluster' -x
feat: install logging, error trapping, PXE/ISO integration tests Kickstart installs on real hardware failed silently — no error reporting, only 3 progress callbacks, zero log streaming. This overhaul makes every install fully observable. Kickstart improvements: - Error trapping in %pre and %post (trap ERR sends failure details to bastion) - 12+ granular progress stages (was 3): SSH, hostname, k3s prep, EFI boot, metadata - Background log streamer: tails %post output and batch-sends to /api/log - bastion_log() function for explicit log lines from kickstart scripts Bastion API: - POST /api/log — receives raw log lines from kickstart (single or batch) - InstallLogBuffer — per-MAC ring buffer (2000 lines) + file persistence - GET /api/logs/:mac — now returns log_lines + log_total alongside stages - SSE /api/logs/:mac/follow — uses named events (event: stage vs event: log) - Progress events forwarded to labd via bastion-progress WebSocket message - Post-provision k3s logs routed through progressBus (was console-only) dnsmasq fixes found during VM testing: - HTTP Boot filename: ipxe-real.efi → ipxe.efi (leftover from old 2-stage approach) - pxe-service directives: only in proxy mode (breaks OVMF PXE in full mode) - PXEClient vendor class echo for UEFI firmware compatibility Integration tests: - PXE boot test: blank UEFI VM → dnsmasq → HTTP Boot → iPXE → bastion → install - ISO boot test: blank VM boots from bastion-generated ISO → same flow - Shared helpers: pxe-network (no DHCP, nftables fix), pxe-vm (UEFI + ISO boot) - test-provision.sh: runs both PXE + ISO tests with prerequisite checks - 250GB sparse QCOW2 disk (LVM layout needs ~204GB) 201 unit tests passing (11 new). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:26:33 +00:00
# app k3s health options
complete -c labctl -n "__labctl_in_cmd app k3s health" -l user -d 'SSH user' -x
# app k3s list options
complete -c labctl -n "__labctl_in_cmd app k3s list" -l user -d 'SSH user' -x
# app k3s kubeconfig options
complete -c labctl -n "__labctl_in_cmd app k3s kubeconfig" -l user -d 'SSH user' -x
complete -c labctl -n "__labctl_in_cmd app k3s kubeconfig" -l context -d 'Context name (defaults to hostname)' -x
complete -c labctl -n "__labctl_in_cmd app k3s kubeconfig" -l print -d 'Print kubeconfig to stdout instead of merging'