mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 02:54:26 +00:00
moby/buildkit was hardcoded in four places across two workflows and catthehacker/ubuntu in two act scripts, none of them reachable by the image mirror: utils/docker/image/discovery.py only scans roles/**/meta/services.yml. So the one image the CI build cannot proceed without was pulled straight from Docker Hub, unmirrored, which is what broke the fedora build in run 30160077828. Declare both as mirror-only services on svc-runner, following the test-e2e-playwright precedent, so the existing mirror pipeline picks them up unchanged. New scripts/meta/resolve/image/service_ref.sh reads image+version back out of the declaration and is the single source for consumers outside Ansible; its mode argument is mandatory (upstream never touches the network, mirror prefers the GHCR tag and falls back to upstream). The fallback is why the mirror job can keep running in parallel with the build instead of gating it. ACT_PLATFORM_IMAGE moves to an env handler so act consumers read the declared value via BASH_ENV, and workflow.sh now demands it instead of defaulting to a literal. Operator overrides still win through eb.setdefault. Verified: service_ref.sh in all four paths (upstream, mirror hit, missing mode, invalid mode); the mirror path matches GHCRProvider.image_base() character for character and resolves against the live registry anonymously; ACT_PLATFORM_IMAGE resolves through the real BASH_ENV mechanism; make quality green on all four targets. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
97 lines
2.8 KiB
Bash
Executable File
97 lines
2.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Resolve the pull ref of a service declared in a role's meta/services.yml.
|
|
# Usage: service_ref.sh <role> <service> <upstream|mirror>
|
|
# upstream the declared upstream ref; never touches the network
|
|
# mirror the GHCR mirror ref when that tag exists, otherwise the upstream ref
|
|
# Output format: <image>:<version>
|
|
# This is the SPOT for image refs consumed outside Ansible (CI workflows, helper scripts).
|
|
set -euo pipefail
|
|
|
|
usage="Usage: service_ref.sh <role> <service> <upstream|mirror>"
|
|
role="${1:?${usage}}"
|
|
service="${2:?${usage}}"
|
|
source_kind="${3:?${usage}}"
|
|
|
|
case "${source_kind}" in
|
|
upstream | mirror) ;;
|
|
*)
|
|
echo "Unknown source '${source_kind}'. ${usage}" >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
|
|
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
repo_root="$(cd "${script_dir}/../../../.." && pwd)"
|
|
services_yml="${repo_root}/roles/${role}/meta/services.yml"
|
|
|
|
if [[ ! -f "${services_yml}" ]]; then
|
|
echo "No such services file: ${services_yml}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if ! pair="$(awk -v want="${service}" '
|
|
/^[^[:space:]#]/ { in_block = ($0 == want ":") }
|
|
in_block && $1 == "image:" { image = $2 }
|
|
in_block && $1 == "version:" { version = $2 }
|
|
END {
|
|
gsub(/"/, "", version)
|
|
if (image == "" || version == "") exit 1
|
|
printf "%s %s\n", image, version
|
|
}
|
|
' "${services_yml}")"; then
|
|
echo "No image/version pair for service '${service}' in ${services_yml}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
read -r image version <<<"${pair}"
|
|
upstream="${image}:${version}"
|
|
|
|
if [[ "${source_kind}" == upstream ]]; then
|
|
printf '%s\n' "${upstream}"
|
|
exit 0
|
|
fi
|
|
|
|
if ! command -v docker >/dev/null 2>&1; then
|
|
echo "docker is unavailable; using upstream ${upstream}" >&2
|
|
printf '%s\n' "${upstream}"
|
|
exit 0
|
|
fi
|
|
|
|
if ! namespace="$("${repo_root}/scripts/meta/resolve/repository/owner.sh")" ||
|
|
! repository="$("${repo_root}/scripts/meta/resolve/repository/name.sh")"; then
|
|
echo "Could not resolve the GHCR namespace/repository; using upstream ${upstream}" >&2
|
|
printf '%s\n' "${upstream}"
|
|
exit 0
|
|
fi
|
|
|
|
if [[ -z "${INFINITO_GHCR_MIRROR_PREFIX:-}" ]]; then
|
|
INFINITO_GHCR_MIRROR_PREFIX="$(awk -F= '$1 == "INFINITO_GHCR_MIRROR_PREFIX" { print $2; exit }' "${repo_root}/default.env")"
|
|
fi
|
|
: "${INFINITO_GHCR_MIRROR_PREFIX:?not in the environment and not declared in default.env}"
|
|
|
|
first="${image%%/*}"
|
|
case "${first}" in
|
|
docker.io | registry-1.docker.io | index.docker.io)
|
|
registry="docker.io"
|
|
name="${image#*/}"
|
|
;;
|
|
*.* | *:*)
|
|
registry="${first}"
|
|
name="${image#*/}"
|
|
;;
|
|
*)
|
|
registry="docker.io"
|
|
name="${image}"
|
|
;;
|
|
esac
|
|
|
|
mirror="ghcr.io/${namespace}/${repository}/${INFINITO_GHCR_MIRROR_PREFIX}/${registry}/${name}:${version}"
|
|
|
|
if docker manifest inspect "${mirror}" >/dev/null 2>&1; then
|
|
echo "Resolved ${upstream} to GHCR mirror ${mirror}" >&2
|
|
printf '%s\n' "${mirror}"
|
|
else
|
|
echo "No GHCR mirror for ${upstream} yet; using upstream" >&2
|
|
printf '%s\n' "${upstream}"
|
|
fi
|