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>
128 lines
3.6 KiB
Bash
Executable File
128 lines
3.6 KiB
Bash
Executable File
#!/bin/bash
|
|
# Build bastion container image (multi-arch) and push to Gitea container registry
|
|
set -e
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
cd "$PROJECT_ROOT"
|
|
|
|
# Load .env for GITEA_TOKEN
|
|
if [ -f .env ]; then
|
|
set -a; source .env; set +a
|
|
fi
|
|
|
|
# ── Argument parsing ───────────────────────────────────────────────
|
|
PUSH=false
|
|
PLATFORMS="linux/amd64,linux/arm64"
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: $(basename "$0") [OPTIONS] [TAG]
|
|
|
|
Build bastion container image (multi-arch) and optionally push to registry.
|
|
|
|
Options:
|
|
--push Push to registry after building
|
|
--platforms LIST Comma-separated platforms (default: linux/amd64,linux/arm64)
|
|
-h, --help Show this help message
|
|
|
|
Arguments:
|
|
TAG Image tag (default: version from package.json)
|
|
|
|
Examples:
|
|
$(basename "$0") # build multi-arch, no push
|
|
$(basename "$0") --push # build + push with version tag
|
|
$(basename "$0") --push latest # build + push as :latest
|
|
$(basename "$0") --platforms linux/amd64 # build amd64 only
|
|
EOF
|
|
exit 0
|
|
}
|
|
|
|
POSITIONAL_ARGS=()
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--push)
|
|
PUSH=true
|
|
shift
|
|
;;
|
|
--platforms)
|
|
PLATFORMS="$2"
|
|
shift 2
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
;;
|
|
*)
|
|
POSITIONAL_ARGS+=("$1")
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
|
|
REGISTRY="${GITEA_REGISTRY:-mysources.co.uk}"
|
|
REPO="michal/lab/bastion"
|
|
FULL_IMAGE="$REGISTRY/$REPO"
|
|
VERSION=$(node -p "require('./package.json').version")
|
|
TAG="${POSITIONAL_ARGS[0]:-$VERSION}"
|
|
|
|
echo "==> Building bastion image"
|
|
echo " Tag: $TAG"
|
|
echo " Platforms: $PLATFORMS"
|
|
echo " Registry: $FULL_IMAGE"
|
|
|
|
# ── Build multi-arch manifest ────────────────────────────────────
|
|
MANIFEST="lab-bastion:$TAG"
|
|
|
|
# Remove existing manifest/image with the same tag
|
|
podman manifest rm "$MANIFEST" 2>/dev/null || true
|
|
podman rmi "$MANIFEST" 2>/dev/null || true
|
|
|
|
echo "==> Building for platforms: $PLATFORMS..."
|
|
podman build \
|
|
--platform "$PLATFORMS" \
|
|
--manifest "$MANIFEST" \
|
|
-f Dockerfile.bastion \
|
|
.
|
|
|
|
echo "==> Build complete. Manifest:"
|
|
podman manifest inspect "$MANIFEST" | grep -E '"(architecture|os)"'
|
|
|
|
# ── Push ─────────────────────────────────────────────────────────
|
|
if [ "$PUSH" = true ]; then
|
|
if [ -z "$GITEA_TOKEN" ]; then
|
|
# Try reading from ~/.gitea-token
|
|
if [ -f "$HOME/.gitea-token" ]; then
|
|
GITEA_TOKEN="$(cat "$HOME/.gitea-token")"
|
|
else
|
|
echo "ERROR: GITEA_TOKEN not set and ~/.gitea-token not found"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
echo "==> Logging in to $REGISTRY..."
|
|
podman login -u michal -p "$GITEA_TOKEN" "$REGISTRY"
|
|
|
|
echo "==> Pushing $FULL_IMAGE:$TAG..."
|
|
podman manifest push --all "$MANIFEST" "docker://$FULL_IMAGE:$TAG"
|
|
|
|
# Also tag as :latest if not already
|
|
if [ "$TAG" != "latest" ]; then
|
|
echo "==> Also pushing as :latest..."
|
|
podman manifest push --all "$MANIFEST" "docker://$FULL_IMAGE:latest"
|
|
fi
|
|
|
|
# Link package to repository if script exists
|
|
if [ -f "$SCRIPT_DIR/link-package.sh" ]; then
|
|
source "$SCRIPT_DIR/link-package.sh"
|
|
link_package "container" "bastion"
|
|
fi
|
|
|
|
echo "==> Pushed successfully!"
|
|
else
|
|
echo "==> Skipping push (use --push to push to registry)"
|
|
fi
|
|
|
|
echo "==> Done!"
|
|
echo " Image: $FULL_IMAGE:$TAG"
|
|
echo " Platforms: $PLATFORMS"
|