The velero CLI and server are version-coupled, so VELERO_VERSION follows the server running on prod (docker.io/velero/velero:v1.18.2, chart 12.2.3, verified 2026-11-07). It has no renovate marker on purpose: bump it together with the chart's appVersion. The verify stage asserts that `velero version --client-only` reports the pin. The build arg reaches CI through build-image.sh --print-build-args, so no .gitea/ or ci/ change is needed. Co-Authored-By: Claude Opus 5.5 <[email protected]>
86 lines
4.2 KiB
Bash
Executable File
86 lines
4.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
###############################################################################
|
|
# infra/devcontainer/build-image.sh — build the pinned dev `toolbox` image and prove it works.
|
|
#
|
|
# ./build-image.sh # build + verify (tag: home-k3s-dev:local)
|
|
# ./build-image.sh --no-verify # build only
|
|
# IMAGE=foo:bar ./build-image.sh # build under another local name
|
|
# ENGINE=docker ./build-image.sh # build with docker instead of podman
|
|
# ./build-image.sh --print-build-args # print KEY=VALUE build args (what CI consumes)
|
|
#
|
|
# ONE BUILD DEFINITION, TWO CALLERS. `dev.sh build` calls this for local development. The CI
|
|
# image pipeline (.gitea/workflows/images.yaml -> .gitea/workflows/scripts/images.sh) builds the
|
|
# SAME Containerfile on rootless BuildKit (platform/buildkit/) — no container engine exists in a
|
|
# CI job — taking its build args from `--print-build-args`, and PUBLISHES the result as
|
|
# gitea.home.keithjackson.dev/home-network/toolbox. The Containerfile (including its `verify`
|
|
# test stage) and the arg list here are the one recipe both use.
|
|
#
|
|
# THIS SCRIPT NEVER PUSHES. Publishing is CI's job (images.yaml, on push to main), not a
|
|
# workstation's: an image that exists only because someone ran `podman push` from a laptop has
|
|
# no build log, no recorded inputs and no verification anyone else can read.
|
|
#
|
|
# VERSIONS ARE NOT DEFINED HERE. infra/devcontainer/versions.env is the single source of truth.
|
|
###############################################################################
|
|
set -euo pipefail
|
|
|
|
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
ENGINE="${ENGINE:-podman}"
|
|
IMAGE="${IMAGE:-home-k3s-dev:local}"
|
|
|
|
VERIFY=1
|
|
PRINT_ARGS=0
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--no-verify) VERIFY=0 ;;
|
|
--print-build-args) PRINT_ARGS=1 ;;
|
|
-h|--help) sed -n '2,/^####/p' "${BASH_SOURCE[0]}" | sed '$d' | sed 's/^# \{0,1\}//'; exit 0 ;;
|
|
*) echo "unknown argument: $arg" >&2; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
log() { printf '\n\033[1m==> %s\033[0m\n' "$*"; }
|
|
die() { printf '\033[31mERROR: %s\033[0m\n' "$*" >&2; exit 1; }
|
|
|
|
# shellcheck disable=SC1091
|
|
source "${HERE}/versions.env"
|
|
|
|
# THE build args, in ONE place. `--print-build-args` hands exactly this list to the CI pipeline
|
|
# (.gitea/workflows/scripts/images.sh), which builds on rootless BuildKit rather than calling
|
|
# "$ENGINE build" — so CI and a local build cannot drift apart on a pin.
|
|
BUILD_ARGS=(
|
|
"FEDORA_VERSION=$FEDORA_VERSION" "OPENTOFU_VERSION=$OPENTOFU_VERSION" "AGE_VERSION=$AGE_VERSION"
|
|
"SOPS_VERSION=$SOPS_VERSION" "FLUX_VERSION=$FLUX_VERSION" "KUBECTL_VERSION=$KUBECTL_VERSION"
|
|
"HELM_VERSION=$HELM_VERSION" "KYVERNO_VERSION=$KYVERNO_VERSION"
|
|
"KYVERNO_JSON_VERSION=$KYVERNO_JSON_VERSION" "CHAINSAW_VERSION=$CHAINSAW_VERSION"
|
|
"YAMLLINT_VERSION=$YAMLLINT_VERSION" "YQ_VERSION=$YQ_VERSION"
|
|
"CHECK_JSONSCHEMA_VERSION=$CHECK_JSONSCHEMA_VERSION" "PROMTOOL_VERSION=$PROMTOOL_VERSION"
|
|
"VELERO_VERSION=$VELERO_VERSION"
|
|
)
|
|
if [ "${PRINT_ARGS}" -eq 1 ]; then printf '%s\n' "${BUILD_ARGS[@]}"; exit 0; fi
|
|
|
|
command -v "${ENGINE}" >/dev/null 2>&1 || die "'${ENGINE}' not on PATH (set ENGINE=docker to use docker)"
|
|
|
|
ARG_FLAGS=()
|
|
for a in "${BUILD_ARGS[@]}"; do ARG_FLAGS+=(--build-arg "$a"); done
|
|
# Provenance: CI passes the commit it is building, so a pulled image names its source tree.
|
|
LABEL_ARGS=()
|
|
[ -z "${BUILD_REVISION:-}" ] || LABEL_ARGS+=(--label "org.opencontainers.image.revision=${BUILD_REVISION}")
|
|
|
|
# --- verify --------------------------------------------------------------------
|
|
# The assertions live in the Containerfile's `verify` stage (every tool on PATH, the
|
|
# version-sensitive ones report their versions.env pins — promtool above all, because
|
|
# ci/versions.env asserts a promtool/Prometheus lockstep — and no network), so the SAME proof
|
|
# runs here under podman and in CI under rootless BuildKit. A failing assertion fails the build.
|
|
if [ "${VERIFY}" -eq 1 ]; then
|
|
log "Verifying (Containerfile target: verify)"
|
|
"$ENGINE" build "${ARG_FLAGS[@]}" --target verify -f "${HERE}/Containerfile" "${HERE}"
|
|
log "Toolbox verified"
|
|
fi
|
|
|
|
log "Building ${IMAGE}"
|
|
"$ENGINE" build "${LABEL_ARGS[@]}" "${ARG_FLAGS[@]}" --target toolbox \
|
|
-t "$IMAGE" -f "${HERE}/Containerfile" "${HERE}"
|
|
|
|
log "Built ${IMAGE}"
|
|
printf ' image id %s\n' "$("$ENGINE" image inspect --format '{{.Id}}' "$IMAGE")"
|