From 5a1c89b7053bfd318d65281730ca49b431e0ec36 Mon Sep 17 00:00:00 2001 From: Philip Peterson <1326208+philip-peterson@users.noreply.github.com> Date: Fri, 30 Oct 2026 19:55:20 -0800 Subject: [PATCH] Vendor upstream images into the forge's mirror/ before pulling [skip ci] Co-Authored-By: Claude Opus 5.5 --- .forgejo/vendor-images.sh | 34 ++++++++++++++++++++++++++++++++++ .forgejo/workflows/iso.yml | 18 +++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100755 .forgejo/vendor-images.sh diff --git a/.forgejo/vendor-images.sh b/.forgejo/vendor-images.sh new file mode 100755 index 0000000..0d85d4a --- /dev/null +++ b/.forgejo/vendor-images.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# Copies upstream images into this forge's registry, as +# forge.quinefoundation.com/quine-global-labs/mirror//, +# which runner-x86-linux's registries.conf tries before the upstream +# registry (petersweb-infra, hosts/runner-x86-linux). So builds pull from +# the forge, and still build from yesterday's copy when upstream is down. +# +# Usage: vendor-images.sh REF... (registry-qualified, e.g. +# quay.io/fedora/fedora-bootc:rawhide, or name:tag@sha256:...) +# +# Needs a `podman login` to the forge first. Best effort: an image that +# can't be copied is a warning, not a failure; the build then gets the +# mirror's last copy, or upstream's. +set -uo pipefail + +mirror=${MIRROR:-forge.quinefoundation.com/quine-global-labs/mirror} +# Read from upstream itself, not from the mirror registries.conf points at. +export CONTAINERS_REGISTRIES_CONF=/dev/null + +for ref in "$@"; do + dest="docker://$mirror/${ref%@*}" + if [[ $ref == *@sha256:* ]]; then + # Pinned by digest: copy the whole index unchanged, so the digest the + # build asks for exists on the mirror. + opts=(--multi-arch all --preserve-digests) + else + opts=(--multi-arch system) + fi + echo "::group::$ref" + # Layers already on the mirror aren't downloaded again. + skopeo copy --retry-times 5 "${opts[@]}" "docker://$ref" "$dest" || + echo "::warning::couldn't vendor $ref; builds get the mirror's last copy, or upstream's" + echo "::endgroup::" +done diff --git a/.forgejo/workflows/iso.yml b/.forgejo/workflows/iso.yml index 264d5c9..8c36dd0 100644 --- a/.forgejo/workflows/iso.yml +++ b/.forgejo/workflows/iso.yml @@ -11,6 +11,10 @@ name: Image and installer ISO # hosts/runner-x86-linux): bootc-image-builder needs an x86_64 host with # root podman and ~30 GB of free disk. # +# Upstream images (Fedora's, bootc-image-builder) are vendored into +# forge.quinefoundation.com/quine-global-labs/mirror/ first, and pulled +# from there (.forgejo/vendor-images.sh). +# # Secrets: REGISTRY_TOKEN (a Forgejo token with package write access), # MINIO_SECRET_KEY. MINIO_ACCESS_KEY is a variable or a secret (it's just the # MinIO user's name, `quine-linux`). @@ -70,11 +74,23 @@ jobs: REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }} run: printf %s "$REGISTRY_TOKEN" | podman login "$REGISTRY" -u "$REGISTRY_USER" --password-stdin + - name: Vendor upstream images + # Into the forge's mirror/ (.forgejo/vendor-images.sh), which the + # pulls below then read: the installer's two bases + # (installer/Containerfile) and bootc-image-builder (Taskfile.yml). + run: | + .forgejo/vendor-images.sh \ + quay.io/fedora/fedora-bootc:rawhide \ + registry.fedoraproject.org/fedora:rawhide \ + ghcr.io/osbuild/bootc-image-builder:latest + - name: Pull base images # Before the builds, with retries: quay.io's CDN cuts off multi-GB # layers now and then ("unexpected EOF"), and a pull inside # `buildah build` gives up after one reconnect. Already-pulled - # images cost only a manifest check. + # images cost only a manifest check. The upstream ones come from the + # forge's mirror/ when it has them (runner-x86-linux's + # registries.conf). run: | for img in \ "$BASE_IMAGE" \