mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-08 11:46:35 +00:00
Extend the local cache stack with three independent capabilities: 1. Inner-`dockerd` build coverage for HTTP-only package mirrors. `roles/sys-svc-compose/files/compose.py` (the runner's `compose` wrapper) auto-generates a transient `compose.cache.override.yml` per app when `INFINITO_PACKAGE_CACHE_FRONTEND_IP` is exported. The override pins `build.extra_hosts` for `deb.debian.org`, `archive.ubuntu.com`, and `security.ubuntu.com` to the frontend. `pull.py` now delegates to the wrapper so build/pull operations see the same `-f` set the wrapper auto-detects. nginx in the frontend gains a port-80 listener with path rewrites for those hostnames, and `package.sh` registers two new Nexus proxies (`apt-debian-security`, `apt-ubuntu-security`) for the security suites whose upstream URL prefix differs from the main archive. Alpine is intentionally excluded from the inner-build extra_hosts: 3.18+ defaults to HTTPS, and inner-`dockerd` build containers do not import the frontend CA. Routing apk through the frontend would trip TLS verification. 2. General cache freshness env-var. `scripts/meta/env/cache/package.sh` exports `INFINITO_PACKAGE_CACHE_MAX_AGE_MIN` (default `129600`, i.e. 90 days). The bootstrap helper consumes it for every Nexus proxy's `contentMaxAge`, `metadataMaxAge`, and `negativeCache.timeToLive`, replacing the previous 1440-minute literal. Lower the value when chasing fast-moving upstreams. 3. SPOT cache documentation at `docs/contributing/environment/cache.md`. `compose.yml.md`, `variables.md`, the per-service READMEs, and `requirements/012-...` now link to it instead of restating the stack's behaviour. Net documentation lines drop substantially while the cache page becomes the single user-facing reference. Also: code-comment cleanup per `docs/contributing/documentation.md` guidelines across all touched .py / .sh / .yml files. Multi-paragraph docstrings, banner separators, and restate-the-obvious comments are removed; one-line WHY comments remain where the rationale is not already visible in the code. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
87 lines
2.5 KiB
Python
87 lines
2.5 KiB
Python
from __future__ import annotations
|
|
|
|
import argparse
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
from .common import cache_env_overrides, compose_file_args, resolve_distro
|
|
from .profile import Profile
|
|
|
|
|
|
def _repo_root_from_here() -> Path:
|
|
return Path(__file__).resolve().parents[3]
|
|
|
|
|
|
CI_DOCKER_ROOT = Path("/mnt/docker")
|
|
CI_DOCKER_ROOT_STR = str(CI_DOCKER_ROOT)
|
|
|
|
|
|
def _base_env(*, distro: str) -> dict[str, str]:
|
|
env = dict(os.environ)
|
|
env["INFINITO_DISTRO"] = distro
|
|
env.update(cache_env_overrides())
|
|
return env
|
|
|
|
|
|
def _compose_run(*, repo_root: Path, distro: str, args: list[str]) -> None:
|
|
cmd = ["docker", "compose", "--env-file", "env.ci"]
|
|
env_development = repo_root / "env.development"
|
|
if env_development.exists():
|
|
cmd += ["--env-file", "env.development"]
|
|
|
|
cmd += compose_file_args()
|
|
cmd += Profile().args()
|
|
cmd += list(args)
|
|
env = _base_env(distro=distro)
|
|
env.setdefault("NIX_CONFIG", "")
|
|
subprocess.run(cmd, cwd=repo_root, env=env, check=True, text=True)
|
|
|
|
|
|
def _cleanup_docker_root() -> None:
|
|
docker_root = CI_DOCKER_ROOT
|
|
|
|
if os.environ.get("RUNNING_ON_GITHUB") != "true":
|
|
print(f">>> Not on GitHub - No bind volumes will be deleted: {docker_root}")
|
|
return
|
|
|
|
docker_root_env = os.environ.get("INFINITO_DOCKER_VOLUME", "").strip().rstrip("/")
|
|
|
|
if docker_root_env and docker_root_env != CI_DOCKER_ROOT_STR:
|
|
raise RuntimeError(
|
|
"SECURITY VIOLATION: "
|
|
f"INFINITO_DOCKER_VOLUME={docker_root_env} is not allowed on GitHub runner. "
|
|
f"Only {CI_DOCKER_ROOT_STR} is permitted."
|
|
)
|
|
|
|
if not docker_root.exists():
|
|
print(f">>> Docker root does not exist, nothing to clean: {docker_root}")
|
|
return
|
|
|
|
print(f">>> CI cleanup: wiping Docker root: {docker_root}")
|
|
shutil.rmtree(docker_root, ignore_errors=True)
|
|
docker_root.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
|
def down_stack(*, repo_root: Path, distro: str) -> None:
|
|
print(">>> Stopping compose stack and removing volumes")
|
|
try:
|
|
_compose_run(
|
|
repo_root=repo_root,
|
|
distro=distro,
|
|
args=["down", "--remove-orphans", "-v"],
|
|
)
|
|
finally:
|
|
_cleanup_docker_root()
|
|
|
|
|
|
def add_parser(sub: argparse._SubParsersAction) -> None:
|
|
p = sub.add_parser("down", help="Stop compose stack and remove volumes.")
|
|
p.set_defaults(_handler=handler)
|
|
|
|
|
|
def handler(args: argparse.Namespace) -> int:
|
|
down_stack(repo_root=_repo_root_from_here(), distro=resolve_distro())
|
|
return 0
|