From 75baf2e41566bc26672570d9456624fd33ee22e6 Mon Sep 17 00:00:00 2001 From: Thales Maciel Date: Sat, 18 Apr 2026 15:26:57 -0300 Subject: [PATCH] publish-golden-image: content-addressed tarball names Embed the sha256 prefix in the uploaded filename so every rebuild lives at a unique URL. Cloudflare's edge cache (and any similar CDN in front of R2) can never serve stale bytes for the URL the catalog points at. The R2 console offers no per-URL purge for this bucket layout, so making the URL itself content-addressed is the only durable fix. Also republishes the debian-bookworm catalog entry with the new filename. Co-Authored-By: Claude Opus 4.7 (1M context) --- internal/imagecat/catalog.json | 6 +++--- scripts/publish-golden-image.sh | 21 ++++++++++++++++----- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/internal/imagecat/catalog.json b/internal/imagecat/catalog.json index 9501847..f8e9fd5 100644 --- a/internal/imagecat/catalog.json +++ b/internal/imagecat/catalog.json @@ -6,9 +6,9 @@ "distro": "debian", "arch": "x86_64", "kernel_ref": "generic-6.12", - "tarball_url": "https://images.thaloco.com/debian-bookworm-x86_64.tar.zst", - "tarball_sha256": "d035010db47bfa93a1d0275bf6f14c440b4e4eff2119bc82371b640be99623d6", - "size_bytes": 289965534 + "tarball_url": "https://images.thaloco.com/debian-bookworm-x86_64-e5000c22ea98.tar.zst", + "tarball_sha256": "e5000c22ea9801b25425361628ea177328e0fa85181dd00775c09f77d0c5baf2", + "size_bytes": 289965264 } ] } diff --git a/scripts/publish-golden-image.sh b/scripts/publish-golden-image.sh index 5636f9a..5348e71 100755 --- a/scripts/publish-golden-image.sh +++ b/scripts/publish-golden-image.sh @@ -65,10 +65,11 @@ if [[ "$SKIP_UPLOAD" -ne 1 ]]; then done fi -TARBALL_NAME="${NAME}-${ARCH}.tar.zst" STAGE="$(mktemp -d)" trap 'rm -rf "$STAGE"' EXIT -OUT="$STAGE/$TARBALL_NAME" +# Build to a temp name; the content-addressed final name is chosen +# after sha256 is computed. +BUILD_OUT="$STAGE/build.tar.zst" log "building bundle via make-golden-bundle.sh" SIZE_FLAG=() @@ -81,11 +82,21 @@ SIZE_FLAG=() --description "$DESCRIPTION" \ --platform "$PLATFORM" \ "${SIZE_FLAG[@]}" \ - --out "$OUT" + --out "$BUILD_OUT" -SHA256="$(sha256sum "$OUT" | awk '{print $1}')" -SIZE_BYTES="$(stat -c '%s' "$OUT")" +SHA256="$(sha256sum "$BUILD_OUT" | awk '{print $1}')" +SIZE_BYTES="$(stat -c '%s' "$BUILD_OUT")" HUMAN="$(numfmt --to=iec --suffix=B "$SIZE_BYTES" 2>/dev/null || echo "${SIZE_BYTES}B")" + +# Content-addressed filename: every rebuild lives at a unique URL, so +# stale CDN caches can never serve the wrong bytes for the URL the +# catalog points at. First 12 hex chars of sha256 is plenty of +# collision margin for this workload. +SHA_PREFIX="${SHA256:0:12}" +TARBALL_NAME="${NAME}-${ARCH}-${SHA_PREFIX}.tar.zst" +OUT="$STAGE/$TARBALL_NAME" +mv "$BUILD_OUT" "$OUT" + log "bundle ready: $TARBALL_NAME ($HUMAN, sha256 $SHA256)" if [[ "$SKIP_UPLOAD" -eq 1 ]]; then