feat: install logging, error trapping, PXE/ISO integration tests
Some checks failed
CI/CD / lint (pull_request) Failing after 13s
CI/CD / test (pull_request) Failing after 10s
CI/CD / typecheck (pull_request) Failing after 36s
CI/CD / build (pull_request) Has been skipped
CI/CD / publish-rpm (pull_request) Has been skipped
CI/CD / publish-deb (pull_request) Has been skipped
Some checks failed
CI/CD / lint (pull_request) Failing after 13s
CI/CD / test (pull_request) Failing after 10s
CI/CD / typecheck (pull_request) Failing after 36s
CI/CD / build (pull_request) Has been skipped
CI/CD / publish-rpm (pull_request) Has been skipped
CI/CD / publish-deb (pull_request) Has been skipped
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>
This commit is contained in:
71
bastion/scripts/test-integration.sh
Executable file
71
bastion/scripts/test-integration.sh
Executable file
@@ -0,0 +1,71 @@
|
||||
#!/bin/bash
|
||||
# Run integration tests inside a Node container with access to host libvirt.
|
||||
#
|
||||
# Usage: sudo ./scripts/test-integration.sh [vitest args...]
|
||||
# Example: sudo ./scripts/test-integration.sh -t k3s
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
# Detect real user (even when running via sudo)
|
||||
REAL_USER="${SUDO_USER:-$(whoami)}"
|
||||
REAL_HOME="/home/${REAL_USER}"
|
||||
|
||||
echo "==> Running integration tests in container"
|
||||
echo " Project: ${PROJECT_ROOT}"
|
||||
echo " User: ${REAL_USER}"
|
||||
echo " SSH key: ${REAL_HOME}/.ssh/"
|
||||
echo ""
|
||||
|
||||
# Check prerequisites
|
||||
if ! command -v podman &>/dev/null && ! command -v docker &>/dev/null; then
|
||||
echo "ERROR: podman or docker required"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
RUNTIME="podman"
|
||||
if ! command -v podman &>/dev/null; then
|
||||
RUNTIME="docker"
|
||||
fi
|
||||
|
||||
# Check libvirt socket
|
||||
if [ ! -S /var/run/libvirt/libvirt-sock ]; then
|
||||
echo "ERROR: libvirt socket not found at /var/run/libvirt/libvirt-sock"
|
||||
echo " Is libvirtd running? Try: sudo systemctl start libvirtd"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create a temp dir for cloud-init artifacts (avoids SELinux /tmp relabel)
|
||||
WORK_TMP="/var/tmp/lab-integration-$$"
|
||||
mkdir -p "${WORK_TMP}"
|
||||
trap "rm -rf ${WORK_TMP}" EXIT
|
||||
|
||||
exec $RUNTIME run --rm \
|
||||
--name lab-integration-test \
|
||||
--privileged \
|
||||
--security-opt label=disable \
|
||||
--network=host \
|
||||
-v "${PROJECT_ROOT}:${PROJECT_ROOT}" \
|
||||
-v "${REAL_HOME}/.ssh:${REAL_HOME}/.ssh:ro" \
|
||||
-v "/var/run/libvirt/libvirt-sock:/var/run/libvirt/libvirt-sock" \
|
||||
-v "/var/lib/libvirt/images:/var/lib/libvirt/images" \
|
||||
-v "${WORK_TMP}:/tmp/lab-integration-tests" \
|
||||
-w "${PROJECT_ROOT}" \
|
||||
-e "SSH_KEY_PATH=${REAL_HOME}/.ssh/id_rsa" \
|
||||
-e "HOME=${REAL_HOME}" \
|
||||
node:22-bookworm \
|
||||
bash -c "
|
||||
# Install system deps for libvirt client + cloud-init ISO creation
|
||||
apt-get update -qq && apt-get install -y -qq libvirt-clients virtinst genisoimage openssh-client qemu-utils sudo >/dev/null 2>&1
|
||||
|
||||
# Install pnpm
|
||||
corepack enable && corepack prepare pnpm@9 --activate >/dev/null 2>&1
|
||||
|
||||
echo '==> Installing project dependencies...'
|
||||
pnpm install --frozen-lockfile 2>/dev/null
|
||||
|
||||
echo '==> Running integration tests...'
|
||||
echo ''
|
||||
pnpm run test:integration $*
|
||||
"
|
||||
Reference in New Issue
Block a user