#!/usr/bin/env bash # Drift guard (Codex review, #254/#324): every vLLM compose whose # `image: ${VLLM_IMAGE:-}` default is a FIXED docker image must match the # install.spec of the engine its registry slug resolves to. This catches the # "bump the engine spec but forget the compose literal" drift that would silently # feed direct `docker compose` users a stale image (the launcher injects VLLM_IMAGE # from the engine and is fine; the compose literal is the unguarded path). # # Skipped (by design): # - templated literals like `…:nightly-${VLLM_NIGHTLY_SHA}` — self-sync via the # launcher-injected var, so the literal is always in step with the engine. # - pip-method engines (vllm-pip-baseline) — no docker image to match. set -euo pipefail ROOT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd)" python3 - "$ROOT_DIR" <<'PY' import sys, re, pathlib ROOT = pathlib.Path(sys.argv[1]) sys.path.insert(0, str(ROOT)) from scripts.lib.profiles.compose_registry import COMPOSE_REGISTRY from scripts.lib.profiles.compat import load_profiles # Slugs whose ENGINE is itself pending the #254 migration off the purged # vllm-nightly-clean nightly (the engine repoint needs its own stock-v0.22.0 # boot + tool-call/MTP validation — out of the #324 leg). Their compose literal # was pre-bumped to v0.22.0, so they read as "drifted" against the dead nightly # spec until the engine is repointed. Exempted + reported (NOT silently skipped); # delete each from this set when it migrates to vllm-stable, and the guard then # covers it. Tracked in #254. PENDING_254 = set() profiles = load_profiles() pat = re.compile(r'image:\s*\$\{VLLM_IMAGE:-([^}]+)\}') drift, checked, pending, deprecated = [], 0, [], 0 for slug, entry in COMPOSE_REGISTRY.items(): if entry.get("status") == "deprecated": deprecated += 1 continue # on its way out — not drift-guarded if slug in PENDING_254: pending.append(slug) continue eng_id = entry.get("engine") eng = profiles.engines.get(eng_id) if eng_id else None if eng is None: continue install = getattr(eng, "install", None) or {} if install.get("method") != "docker_image": continue # pip baseline etc. — no docker image to compare against spec = install.get("spec", "") cpath = entry.get("compose_path") if not cpath: continue p = ROOT / cpath if not p.exists(): continue m = pat.search(p.read_text()) if not m: continue literal = m.group(1).strip() if "${" in literal: continue # templated (e.g. nightly-${VLLM_NIGHTLY_SHA}) — self-syncs checked += 1 if literal != spec: drift.append( f" {slug}: compose default `{literal}` != engine `{eng_id}` install.spec " f"`{spec}` ({cpath})" ) if drift: print("IMAGE DRIFT — a fixed compose `${VLLM_IMAGE:-…}` default disagrees with the") print("engine its slug resolves to (direct `docker compose` would serve a stale image):") print("\n".join(drift)) print("Fix: bump the compose literal to the engine install.spec (or vice-versa).") sys.exit(1) if pending: print(f"NOTE: {len(pending)} slug(s) exempt pending #254 engine migration: {', '.join(sorted(pending))}") print( f"test-compose-image-drift: ok ({checked} fixed-image vLLM composes match their engine spec; " f"{deprecated} deprecated skipped, {len(pending)} pending-#254 exempt)" ) PY