ci: multi-arch-safe php.net guard and emergency workflow (no platform change)
- scripts/image-label-amd64.sh: index-safe read of the amd64 image's labels (OCI index with attestations, Docker manifest list, single manifest). - scripts/php-emergency-guard.sh: used by both build-push.yaml guard sites; same decisions as the old inline step on single-platform images, but FAILS CLOSED when the labels cannot be read (only "tag not found" passes). - lsphp-source-emergency.yaml: push by digest + assemble (copy of HMB assemble-multiarch-index.sh); optional arm64; refuses to replace a multi-arch production tag with amd64-only unless allow_amd64_only. - Tests wired into Shell-Checks; main build matrix platforms unchanged. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0185ukXjXyosSkunDsdWz3mb
This commit is contained in:
1 parent
4b35869477
commit
8a6a6d7b44
8 files changed
+565
-24
No files matched your search
Executable
+40
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env bash
|
||||
## index-platforms.sh REF
|
||||
## Prints "index <os/arch> ..." (real platforms only, attestation children
|
||||
## excluded) when REF is an image index / manifest list, or "single" when it is
|
||||
## a plain single-platform manifest. Exit 3 = REF not found, 1 = any other
|
||||
## failure (fail closed). Used by lsphp-source-emergency.yaml to refuse to
|
||||
## replace a multi-arch tag with an amd64-only one.
|
||||
## Env: IMAGETOOLS overrides "docker buildx imagetools" (tests use a stub).
|
||||
set -euo pipefail
|
||||
IMAGETOOLS=${IMAGETOOLS:-docker buildx imagetools}
|
||||
ref=${1:?usage: index-platforms.sh REF}
|
||||
err=$(mktemp); trap 'rm -f "$err"' EXIT
|
||||
rc=0
|
||||
# shellcheck disable=SC2086
|
||||
raw=$($IMAGETOOLS inspect --raw "$ref" 2>"$err") || rc=$?
|
||||
if [ "$rc" -ne 0 ]; then
|
||||
if grep -qiE 'not found|manifest unknown|name unknown|: 404' "$err"; then echo "index-platforms: $ref not found" >&2; exit 3; fi
|
||||
echo "index-platforms: imagetools failed: $(head -c 300 "$err" | tr '\n' ' ')" >&2; exit 1
|
||||
fi
|
||||
printf '%s' "$raw" | python3 -I -c '
|
||||
import json, sys
|
||||
try:
|
||||
d = json.load(sys.stdin)
|
||||
except Exception as e:
|
||||
sys.stderr.write("index-platforms: not JSON: %s\n" % e); sys.exit(1)
|
||||
if isinstance(d, dict) and isinstance(d.get("manifests"), list):
|
||||
ps = []
|
||||
for m in d["manifests"]:
|
||||
p = m.get("platform") if isinstance(m, dict) else None
|
||||
if not isinstance(p, dict) or "vnd.docker.reference.type" in (m.get("annotations") or {}):
|
||||
continue
|
||||
if p.get("os") in (None, "", "unknown") or p.get("architecture") in (None, "", "unknown"):
|
||||
continue
|
||||
ps.append("%s/%s" % (p["os"], p["architecture"]))
|
||||
print("index " + " ".join(sorted(set(ps))))
|
||||
elif isinstance(d, dict) and isinstance(d.get("config"), dict):
|
||||
print("single")
|
||||
else:
|
||||
sys.stderr.write("index-platforms: neither index nor image manifest\n"); sys.exit(1)
|
||||
'
|
||||
Reference in new issue
Block a user