Replaces the OCI-push flow with a bundle-based one that mirrors the kernel catalog (publish-kernel.sh / kernelcat). - scripts/make-golden-bundle.sh: docker build → docker create → docker export | banger internal make-bundle → .tar.zst. Defaults target debian-bookworm / generic-6.12 / x86_64; pinned --size 4G to leave headroom for first-boot installs and in-VM apt use. - scripts/publish-golden-image.sh: rewritten to call make-golden-bundle, rclone upload to R2 (banger-images bucket, images.thaloco.com), and jq-patch internal/imagecat/catalog.json with URL / sha256 / size. --skip-upload stops after bundle build and copies to dist/. make-bundle default ext4 sizing also bumped from +25% to +50% headroom (mkfs.ext4 needs room for inode tables, block-group metadata, journal, and the default 5% reserved-blocks margin). The old 25% was too tight for the ~950 MB golden rootfs and aborted with "Could not allocate block". End-to-end smoke (local): golden Dockerfile → 286 MB tar.zst bundle with correct manifest, valid ext4, and all banger units + vsock agent present. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
120 lines
3.8 KiB
Bash
Executable file
120 lines
3.8 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# make-golden-bundle.sh
|
|
#
|
|
# Build the banger golden image from images/golden/Dockerfile and
|
|
# package it as a .tar.zst bundle suitable for publishing to the
|
|
# imagecat catalog. Does not upload — see publish-golden-image.sh.
|
|
#
|
|
# Pipeline:
|
|
# docker build -> docker create -> docker export | banger internal make-bundle
|
|
#
|
|
# Usage:
|
|
# scripts/make-golden-bundle.sh [--name <n>] [--kernel-ref <k>] \
|
|
# [--distro <d>] [--arch <a>] [--description "..."] \
|
|
# [--out <path>] [--size <spec>] [--platform <p>]
|
|
#
|
|
# Defaults:
|
|
# --name debian-bookworm
|
|
# --kernel-ref generic-6.12
|
|
# --distro debian
|
|
# --arch x86_64
|
|
# --platform linux/amd64
|
|
# --out <repo>/dist/<name>-<arch>.tar.zst
|
|
#
|
|
# Environment overrides:
|
|
# BANGER_BIN path to banger binary (default build/bin/banger)
|
|
# BANGER_VSOCK_AGENT_BIN path to companion (default build/bin/banger-vsock-agent)
|
|
|
|
set -euo pipefail
|
|
|
|
log() { printf '[make-golden-bundle] %s\n' "$*" >&2; }
|
|
die() { log "$*"; exit 1; }
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
DOCKERFILE="$REPO_ROOT/images/golden/Dockerfile"
|
|
CONTEXT="$REPO_ROOT/images/golden"
|
|
|
|
NAME="debian-bookworm"
|
|
KERNEL_REF="generic-6.12"
|
|
DISTRO="debian"
|
|
ARCH="x86_64"
|
|
DESCRIPTION=""
|
|
OUT=""
|
|
# 4G is a deliberate over-allocation for the golden image: it leaves
|
|
# room for first-boot apt-installs of sshd on derived pulls and for
|
|
# the user's own apt-installs during sandbox use.
|
|
SIZE="4G"
|
|
PLATFORM="linux/amd64"
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--name) NAME="${2:-}"; shift 2;;
|
|
--kernel-ref) KERNEL_REF="${2:-}"; shift 2;;
|
|
--distro) DISTRO="${2:-}"; shift 2;;
|
|
--arch) ARCH="${2:-}"; shift 2;;
|
|
-d|--description) DESCRIPTION="${2:-}"; shift 2;;
|
|
--out) OUT="${2:-}"; shift 2;;
|
|
--size) SIZE="${2:-}"; shift 2;;
|
|
--platform) PLATFORM="${2:-}"; shift 2;;
|
|
-h|--help)
|
|
sed -n '2,/^set -euo/p' "$0" | sed 's/^# \?//' | sed '$d'
|
|
exit 0
|
|
;;
|
|
*) die "unknown option: $1";;
|
|
esac
|
|
done
|
|
|
|
for tool in docker zstd sha256sum; do
|
|
command -v "$tool" >/dev/null 2>&1 || die "missing required tool: $tool"
|
|
done
|
|
[[ -f "$DOCKERFILE" ]] || die "dockerfile missing: $DOCKERFILE"
|
|
|
|
BANGER_BIN="${BANGER_BIN:-$REPO_ROOT/build/bin/banger}"
|
|
[[ -x "$BANGER_BIN" ]] || die "banger binary not executable: $BANGER_BIN (run 'make build' or set BANGER_BIN)"
|
|
VSOCK_AGENT="${BANGER_VSOCK_AGENT_BIN:-$REPO_ROOT/build/bin/banger-vsock-agent}"
|
|
[[ -x "$VSOCK_AGENT" ]] || die "banger-vsock-agent not executable: $VSOCK_AGENT (run 'make build')"
|
|
|
|
if [[ -z "$OUT" ]]; then
|
|
OUT="$REPO_ROOT/dist/${NAME}-${ARCH}.tar.zst"
|
|
fi
|
|
mkdir -p "$(dirname "$OUT")"
|
|
|
|
DOCKER_TAG="banger-golden:${NAME}"
|
|
|
|
log "building $DOCKER_TAG (platform=$PLATFORM)"
|
|
docker build --platform "$PLATFORM" -t "$DOCKER_TAG" -f "$DOCKERFILE" "$CONTEXT"
|
|
|
|
log "creating docker container (not started)"
|
|
CONTAINER_ID="$(docker create "$DOCKER_TAG")"
|
|
cleanup() { docker rm -f "$CONTAINER_ID" >/dev/null 2>&1 || true; }
|
|
trap cleanup EXIT
|
|
|
|
log "piping container filesystem into banger internal make-bundle"
|
|
SIZE_FLAG=()
|
|
[[ -n "$SIZE" ]] && SIZE_FLAG=(--size "$SIZE")
|
|
DESC_FLAG=()
|
|
[[ -n "$DESCRIPTION" ]] && DESC_FLAG=(--description "$DESCRIPTION")
|
|
KERNEL_REF_FLAG=()
|
|
[[ -n "$KERNEL_REF" ]] && KERNEL_REF_FLAG=(--kernel-ref "$KERNEL_REF")
|
|
|
|
export BANGER_VSOCK_AGENT_BIN="$VSOCK_AGENT"
|
|
docker export "$CONTAINER_ID" | \
|
|
"$BANGER_BIN" internal make-bundle \
|
|
--rootfs-tar - \
|
|
--name "$NAME" \
|
|
--distro "$DISTRO" \
|
|
--arch "$ARCH" \
|
|
"${KERNEL_REF_FLAG[@]}" \
|
|
"${DESC_FLAG[@]}" \
|
|
"${SIZE_FLAG[@]}" \
|
|
--out "$OUT"
|
|
|
|
SHA256="$(sha256sum "$OUT" | awk '{print $1}')"
|
|
SIZE_BYTES="$(stat -c '%s' "$OUT")"
|
|
HUMAN="$(numfmt --to=iec --suffix=B "$SIZE_BYTES" 2>/dev/null || echo "${SIZE_BYTES}B")"
|
|
|
|
log "bundle: $OUT"
|
|
log "sha256: $SHA256"
|
|
log "size: $HUMAN ($SIZE_BYTES bytes)"
|
|
printf '%s\n' "$OUT"
|