2026-03-17 02:55:52 +00:00
|
|
|
{
|
2026-03-17 11:05:41 +00:00
|
|
|
"name": "lab",
|
2026-03-17 02:55:52 +00:00
|
|
|
"version": "0.1.0",
|
|
|
|
|
"private": true,
|
|
|
|
|
"description": "PXE bastion server for discover-first bare-metal provisioning",
|
|
|
|
|
"type": "module",
|
|
|
|
|
"scripts": {
|
2026-03-17 11:05:41 +00:00
|
|
|
"build": "pnpm -r run build",
|
2026-03-17 02:55:52 +00:00
|
|
|
"test": "vitest",
|
|
|
|
|
"test:run": "vitest run",
|
2026-03-17 11:05:41 +00:00
|
|
|
"typecheck": "tsc --build",
|
|
|
|
|
"clean": "pnpm -r run clean && rimraf node_modules",
|
feat: ESLint, shell completions, Docker, nfpm packaging, CI/CD
- ESLint with typescript-eslint + prettier (eslint.config.js)
- Shell completions for bash and fish (scripts/generate-completions.ts)
- Multi-stage Dockerfile for bastion (fedora:43 + dnsmasq + node)
- nfpm.yaml for RPM/DEB packaging with bun-compiled binary
- Build scripts: build-rpm.sh, build-bastion.sh, publish-rpm/deb.sh
- Gitea Actions CI/CD: lint, typecheck, test, build, publish
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 21:51:01 +00:00
|
|
|
"lint": "eslint 'src/*/src/**/*.ts'",
|
|
|
|
|
"lint:fix": "eslint 'src/*/src/**/*.ts' --fix",
|
|
|
|
|
"completions:generate": "tsx scripts/generate-completions.ts --write",
|
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
|
|
|
"completions:check": "tsx scripts/generate-completions.ts --check",
|
|
|
|
|
"test:integration": "vitest run -c tests/integration/vitest.config.ts",
|
|
|
|
|
"test:integration:k3s": "vitest run -c tests/integration/vitest.config.ts -t k3s",
|
|
|
|
|
"test:integration:k3s:host": "sudo -E $(which npx) vitest run -c tests/integration/vitest.config.ts -t k3s",
|
|
|
|
|
"test:integration:pxe": "vitest run -c tests/integration/vitest.config.ts -t 'PXE boot'",
|
|
|
|
|
"test:integration:pxe:host": "sudo -E $(which npx) vitest run -c tests/integration/vitest.config.ts -t 'PXE boot'",
|
|
|
|
|
"test:integration:iso": "vitest run -c tests/integration/vitest.config.ts -t 'ISO boot'",
|
2026-03-27 00:26:12 +00:00
|
|
|
"test:integration:iso:host": "sudo -E $(which npx) vitest run -c tests/integration/vitest.config.ts -t 'ISO boot'",
|
feat(bastion): bring VyOS provisioning to Fedora-grade quality
Ports the Fedora provisioning features that matter for a router onto the
VyOS path, and adds the libvirt integration test that proves them.
- Live install logs: the driver streams the installer pty (ANSI-stripped,
batched, best-effort) to POST /api/log, so `labctl provision logs -f`
works during a VyOS install the way Anaconda's syslog does for Fedora.
- installed.ip: report "ready at <ip>" -- the exact detail format
routes/api.ts parses -- using the static mgmt address when known, else
the live DHCP address. Without it VyOS machines landed with an empty IP,
breaking provision list, logs-by-IP, recheck and reprovision.
api.ts also guards the complete handler: VyOS boxes get the "vyos" SSH
hint and never trigger the k3s post-provision.
- EFI network-first boot order: port of the Fedora %post efibootmgr step,
run from the live env after install (NVRAM, not disk). Best-effort.
- Reinstall semantics: VyOS's installer already carries the previous
config and SSH host keys forward -- the analog of Fedora's LV
preservation -- so that stays the default. New --vyos-fresh-config
overwrites the installed config.boot with the generated one instead,
via a post-install target mount that also writes /config/lab-provisioned
(mirrors Fedora's /etc/lab-provisioned, survives image upgrades).
- reprovision/recheck default to the "vyos" SSH user for VyOS machines.
Two hangs found by the VM test and fixed:
- On reinstall the installer asks "Would you like to copy data to the new
image?" (search_previous_installation). Unanswered, the driver blocked
on stdin until its stall timeout -- a silent 15-minute hang.
- The RAID regex missed "Would you like to choose two disks for RAID-1
mirroring?", which would wedge any multi-disk box. Both prompts default
to yes, so a miss also risks an unwanted mirror.
Both are now covered by a unit test asserting all 17 installer prompts
match exactly one rule -- verified to fail against the unfixed code, so
this class of bug is caught in a second instead of a 45-minute VM run.
tests/integration/vyos-provision.test.ts: fresh install, reinstall
preserves config + /config data, and freshConfig override. All 8 pass
against the real nightly ISO (EXIT=0). 273 unit tests pass; no new lint
errors in touched files.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DMVzWZgiKW2wquf5z8S1yH
2026-08-11 11:16:25 +01:00
|
|
|
"test:integration:vyos": "vitest run -c tests/integration/vitest.config.ts -t 'VyOS provisioning'",
|
|
|
|
|
"test:integration:vyos:host": "sudo -E $(which npx) vitest run -c tests/integration/vitest.config.ts -t 'VyOS provisioning'",
|
2026-03-27 00:26:12 +00:00
|
|
|
"test:integration:arm-iso": "vitest run -c tests/integration/vitest.config.ts -t 'ARM ISO'",
|
2026-03-31 03:07:38 +01:00
|
|
|
"test:integration:arm-iso:host": "sudo -E $(which npx) vitest run -c tests/integration/vitest.config.ts -t 'ARM ISO'",
|
|
|
|
|
"test:integration:asahi": "vitest run -c tests/integration/vitest.config.ts -t 'asahi firstboot'",
|
2026-03-31 13:22:24 +01:00
|
|
|
"test:integration:asahi:host": "sudo -E $(which npx) vitest run -c tests/integration/vitest.config.ts -t 'asahi firstboot'",
|
|
|
|
|
"test:integration:asahi-validate": "vitest run -c tests/integration/vitest.config.ts -t 'asahi.*validation'",
|
|
|
|
|
"test:integration:asahi-validate:host": "sudo -E $(which npx) vitest run -c tests/integration/vitest.config.ts -t 'asahi.*validation'"
|
2026-03-17 02:55:52 +00:00
|
|
|
},
|
|
|
|
|
"engines": {
|
|
|
|
|
"node": ">=20.0.0",
|
|
|
|
|
"pnpm": ">=9.0.0"
|
|
|
|
|
},
|
|
|
|
|
"packageManager": "pnpm@9.15.0",
|
|
|
|
|
"devDependencies": {
|
|
|
|
|
"@types/node": "^22.10.0",
|
feat: ESLint, shell completions, Docker, nfpm packaging, CI/CD
- ESLint with typescript-eslint + prettier (eslint.config.js)
- Shell completions for bash and fish (scripts/generate-completions.ts)
- Multi-stage Dockerfile for bastion (fedora:43 + dnsmasq + node)
- nfpm.yaml for RPM/DEB packaging with bun-compiled binary
- Build scripts: build-rpm.sh, build-bastion.sh, publish-rpm/deb.sh
- Gitea Actions CI/CD: lint, typecheck, test, build, publish
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 21:51:01 +00:00
|
|
|
"@typescript-eslint/eslint-plugin": "^8.57.1",
|
|
|
|
|
"@typescript-eslint/parser": "^8.57.1",
|
|
|
|
|
"eslint": "^10.0.3",
|
|
|
|
|
"eslint-config-prettier": "^10.1.8",
|
2026-03-17 02:55:52 +00:00
|
|
|
"rimraf": "^6.0.0",
|
|
|
|
|
"tsx": "^4.21.0",
|
|
|
|
|
"typescript": "^5.7.0",
|
|
|
|
|
"vitest": "^3.0.0"
|
|
|
|
|
}
|
|
|
|
|
}
|