Files
kevinveenbirkenbachandClaude Opus 5.5 1ba796d7f1 fix(ci): pull the images the runner uses itself from the GHCR mirror
The GHCR mirror covered role images only. The images the runner pulls on
its own went straight to Docker Hub: coredns from compose.yml, the cache
stack in compose/cache.override.yml and alpine:latest, the init image of
scripts/docker/cache/package-frontend/certs.sh. With the anonymous
githubactions quota spent, the guide step of Postmarks#0 (main run
37954203718) and Shopware#2 (#872) died on "toomanyrequests" while pulling
alpine:latest, after coredns had hit the same limit.

iter_runner_images (utils/docker/image/discovery.py) finds those images,
and the mirror sync and the fork-PR wait now cover them next to the role
images. On a real GitHub runner compose_file_args layers a generated
build/compose/runner-mirror.override.yml that points only the services of
the layered compose files at their mirror, and the certificate generator
gets the mirrored init image. Local runs and act are unchanged, and the
coredns literal stays in compose.yml for Dependabot. test-dns now waits for
images-mirror-missing like the deploy and workspace jobs, since it brings up
the stack too.

Verified with docker compose config on a simulated GitHub runner: the
service set is unchanged and only the runner images point at
ghcr.io/infinito-nexus/core/mirror/docker.io/..., and an existing role mirror
under that scheme pulls anonymously.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-10 10:37:41 +02:00

54 lines
1.9 KiB
Python

from __future__ import annotations
import os
from utils.distros import distro_names
VALID_DISTROS: tuple[str, ...] = distro_names()
def compose_file_args() -> list[str]:
"""Compose `-f` flags shared by up and down flows.
Each override is gated on the resource it needs being present, not on the
instance slot: an override whose `:?` guard is unsatisfied would abort the
stack outright, so a checkout that was never handed a shared git dir or
cache network simply does not layer that file in.
"""
from .profile import Profile
profile = Profile()
out = ["-f", "compose.yml"]
if profile.shared_git_dir():
out += ["-f", "compose/worktree.override.yml"]
if profile.cache_stack_enabled():
out += ["-f", "compose/cache.override.yml"]
if profile.shared_cache_network():
out += ["-f", "compose/cache.shared.override.yml"]
if (os.environ.get("INFINITO_PUBLISH_PORTS") or "").strip().lower() == "false":
out += ["-f", "compose/noports.override.yml"]
if profile.image_mirror_enabled():
from utils.cache.files import PROJECT_ROOT
from .runner_mirror import write_override
out += ["-f", write_override(PROJECT_ROOT, out[1::2])]
return out
def resolve_distro() -> str:
"""Return INFINITO_DISTRO; raise SystemExit if missing or invalid."""
distro = os.environ["INFINITO_DISTRO"].strip()
if not distro:
raise SystemExit(
"INFINITO_DISTRO is not set. Run 'make dotenv' (or source scripts/meta/env/load.sh) "
f"or export INFINITO_DISTRO=<{'|'.join(VALID_DISTROS)}> "
"before invoking cli.administration.deploy.development."
)
if distro not in VALID_DISTROS:
raise SystemExit(
f"INFINITO_DISTRO={distro!r} is not a valid distro. "
f"Valid: {', '.join(VALID_DISTROS)}."
)
return distro