From c48a82c4c811964250dbb38f4179509571787cfb Mon Sep 17 00:00:00 2001 From: shankar0123 Date: Thu, 30 Apr 2026 18:46:02 +0000 Subject: [PATCH] =?UTF-8?q?fix(ci):=20real=20digests=20+=20matrix=E2=86=92?= =?UTF-8?q?service=20mapping=20for=20deploy-vendor-e2e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bundle II Phases 1+15 shipped fabricated @sha256 digests across 11 sidecars (deploy/docker-compose.test.yml) plus the f5-mock-icontrol Dockerfile golang FROM line. The H-001 bare-FROM CI guard passed locally because it only regex-checks for the *presence* of @sha256: — it does not verify the digest resolves on the registry. Result: every deploy-vendor-e2e matrix job failed at `docker compose up` with 'manifest unknown'. Two classes of fix: 1. Replace the 11 fabricated digests with real, registry-resolved digests (verified via curl against registry-1.docker.io, ghcr.io, mcr.microsoft.com manifest endpoints): - httpd:2.4-alpine - haproxy:3.0-alpine - traefik:v3.1 - caddy:2.8-alpine - envoyproxy/envoy:v1.32-latest - boky/postfix:latest - dovecot/dovecot:latest - lscr.io/linuxserver/openssh-server:latest (via ghcr.io) - kindest/node:v1.31.0 - mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2022 (manifest.v2 single-image digest — the image is Windows-only so there is no multi-arch list digest to follow) - golang:1.25.9-bookworm (in deploy/test/f5-mock-icontrol/Dockerfile) debian:bookworm-slim was also fabricated under the comment claiming it 'matches libest sidecar'; replaced with the real amd64-linux digest. 2. Special-case the matrix.vendor → docker-compose service mapping in .github/workflows/ci.yml::deploy-vendor-e2e step 'Bring up vendor sidecar'. The original step assumed a uniform '${{ matrix.vendor }}-test' suffix, but four matrix entries don't conform: - nginx → reuses apache-test (the legacy nginx sidecar in the compose file is named 'nginx' with no profile; the nginx vendor-edge tests in deploy/test/nginx_vendor_e2e_test.go call requireSidecar(t,"apache") because the sidecar map doesn't include an 'nginx' key — comment in source explains) - ssh → openssh-test - k8s → k8s-kind-test - f5-mock → f5-mock-icontrol (must be built first; no published image) - javakeystore → no sidecar (pure-Go placeholder stubs) Wraps the bring-up in a case statement that maps every matrix entry to its real sidecar name (or '' for the no-sidecar case), and exits 0 cleanly for vendors that don't need a sidecar. Per the CLAUDE.md 'never go from memory' + 'complete path' rules, this fix: - ground-truths every digest against the actual registry (curl against the OCI v2 manifest endpoint with the right Accept header), not memory or grep - closes the 'lying field' footgun: H-001 guard now validates a contract that's actually satisfied (digests exist + pull) Verification: yaml parses on both files, H-001 guard simulation returns no bare FROMs, all 12 manifest endpoints return HTTP 200 on the new digests. --- .github/workflows/ci.yml | 37 +++++++++++++++++++++---- deploy/docker-compose.test.yml | 20 ++++++------- deploy/test/f5-mock-icontrol/Dockerfile | 4 +-- 3 files changed, 44 insertions(+), 17 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fd983d4..baeca7c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1380,13 +1380,40 @@ jobs: cache: true - name: Bring up vendor sidecar + # Map matrix.vendor → docker-compose service name. The naming is + # NOT 1:1 because (a) the legacy NGINX vendor-edge tests reuse the + # apache-test sidecar via requireSidecar(t,"apache") — see the + # comment in deploy/test/nginx_vendor_e2e_test.go; (b) the openssh + # service is named openssh-test (not ssh-test); (c) the kind + # cluster service is named k8s-kind-test; (d) the F5 mock service + # is named f5-mock-icontrol and must be built first because it + # has no published image; (e) the JavaKeystore tests are pure-Go + # placeholder stubs that exercise no sidecar. run: | - if [ "${{ matrix.vendor }}" = "f5-mock" ]; then - docker compose --profile deploy-e2e -f deploy/docker-compose.test.yml build f5-mock-icontrol - docker compose --profile deploy-e2e -f deploy/docker-compose.test.yml up -d f5-mock-icontrol - else - docker compose --profile deploy-e2e -f deploy/docker-compose.test.yml up -d ${{ matrix.vendor }}-test + set -e + case "${{ matrix.vendor }}" in + nginx) SVC=apache-test ;; # nginx tests reuse apache sidecar + apache) SVC=apache-test ;; + haproxy) SVC=haproxy-test ;; + traefik) SVC=traefik-test ;; + caddy) SVC=caddy-test ;; + envoy) SVC=envoy-test ;; + postfix) SVC=postfix-test ;; + dovecot) SVC=dovecot-test ;; + ssh) SVC=openssh-test ;; + k8s) SVC=k8s-kind-test ;; + f5-mock) SVC=f5-mock-icontrol ;; + javakeystore) SVC="" ;; # pure-Go placeholder stubs; no sidecar needed + *) echo "::error::unknown matrix vendor '${{ matrix.vendor }}'"; exit 1 ;; + esac + if [ -z "$SVC" ]; then + echo "vendor=${{ matrix.vendor }} runs without a sidecar (pure-Go placeholder tests)" + exit 0 fi + if [ "${{ matrix.vendor }}" = "f5-mock" ]; then + docker compose --profile deploy-e2e -f deploy/docker-compose.test.yml build "$SVC" + fi + docker compose --profile deploy-e2e -f deploy/docker-compose.test.yml up -d "$SVC" sleep 5 - name: Run vendor-edge e2e diff --git a/deploy/docker-compose.test.yml b/deploy/docker-compose.test.yml index 559873a..37c65f1 100644 --- a/deploy/docker-compose.test.yml +++ b/deploy/docker-compose.test.yml @@ -486,7 +486,7 @@ services: # docs/deployment-vendor-matrix.md. apache-test: - image: httpd:2.4-alpine@sha256:8e8ee9929d4d8ddbed9ff3e5aaad26cdb46c40a4e51d8fdd02c41bff37d1d65a + image: httpd:2.4-alpine@sha256:f9061a65c6e8f50d5636e10806da3d5a238877c11d6bc0149dc5131be0a1a19f container_name: certctl-test-apache ports: - "20443:443" @@ -500,7 +500,7 @@ services: profiles: [deploy-e2e] haproxy-test: - image: haproxy:3.0-alpine@sha256:2e8a7b9f3c91c2c46a90e3a98a7e44e0f7c89def96b3f2bd2a7d0a48a9f4d36a + image: haproxy:3.0-alpine@sha256:5b645ad4f3294cf5bc50ab8b201fdeb73732eca2928185df335735c698e8c3e2 container_name: certctl-test-haproxy ports: - "20444:443" @@ -513,7 +513,7 @@ services: profiles: [deploy-e2e] traefik-test: - image: traefik:v3.1@sha256:c5a92b19a3a77a3a60b9d9cdf3f60d7f08e7e9a2e4cdbcfb4a08b2e8a9e86e7c + image: traefik:v3.1@sha256:8516638b18e67e999d293e4ff0e5baf7807674cd4bdd3d36d448497bcbf0a174 container_name: certctl-test-traefik command: - --providers.file.directory=/etc/traefik/dynamic @@ -531,7 +531,7 @@ services: profiles: [deploy-e2e] caddy-test: - image: caddy:2.8-alpine@sha256:0afbb4bbcdaf0b3036020168f2796e6c80ddf95a7f5de2d3a5d8d7d80796a3df + image: caddy:2.8-alpine@sha256:b95ed06fbc6d74d24a40902090c8cc6086ce7d08ba60a3a7e8e62bf164a9d7bb container_name: certctl-test-caddy command: caddy run --config /etc/caddy/Caddyfile --adapter caddyfile ports: @@ -546,7 +546,7 @@ services: profiles: [deploy-e2e] envoy-test: - image: envoyproxy/envoy:v1.32-latest@sha256:b87f1a50f78ce96a5bca7eaa6c8d5e0e6d4edd6c8e9c2b9d7d2c39b5f6a2e3a4 + image: envoyproxy/envoy:v1.32-latest@sha256:6ed0d4f28b8122df896062c425b34f18b8287e8c71c6badb3b84ca2e2f47c519 container_name: certctl-test-envoy command: envoy -c /etc/envoy/envoy.yaml --log-level error ports: @@ -560,7 +560,7 @@ services: profiles: [deploy-e2e] postfix-test: - image: boky/postfix:latest@sha256:8d4f1ad9d2e1c4f9e3d4f9c1d7e6c0e9e8c5f5b3d1a4f7c4e1f2d6c5b3e9c8a7 + image: boky/postfix:latest@sha256:cd7e192900bfc49a67291a572b5f645f9e7d1b8d7f2b79b0364b4b4176964e21 container_name: certctl-test-postfix environment: ALLOWED_SENDER_DOMAINS: "test.local" @@ -575,7 +575,7 @@ services: profiles: [deploy-e2e] dovecot-test: - image: dovecot/dovecot:latest@sha256:7f4e2c1b6d4a5f7c8e6d9b3f4e7c2a8d6e3f1c4b9a8e7d6c5b4a3f2e1d0c9b8a + image: dovecot/dovecot:latest@sha256:4046993478e8c8bcb841fdbff2d8de1b233484cc0196b3723f6c588e7eaf7301 container_name: certctl-test-dovecot ports: - "20993:993" @@ -589,7 +589,7 @@ services: profiles: [deploy-e2e] openssh-test: - image: lscr.io/linuxserver/openssh-server:latest@sha256:d6a7e4c3b2f1a0d9c8b7e6f5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e7d6c5 + image: lscr.io/linuxserver/openssh-server:latest@sha256:742f577d4100f5ad3b38f270d722931bbe98b997444c13b1a2a838df12a9971e container_name: certctl-test-openssh environment: USER_NAME: "certctl" @@ -629,7 +629,7 @@ services: # The kind binary lives in the test image; the Docker socket is mounted # so kind can manage child containers. k8s-kind-test: - image: kindest/node:v1.31.0@sha256:53df588e04085fd41ae12de0c3fe4c72f7013bba32a20e7325357a1ac94ba865 + image: kindest/node:v1.31.0@sha256:7fbc5644a803286a69ff9c5695f03bb01b512896835e15df7df17f756f7245ac container_name: certctl-test-kind privileged: true networks: @@ -646,7 +646,7 @@ services: # Image not pulled by default (no profile match on Linux); included # here so Windows operators get the same compose surface. windows-iis-test: - image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2022@sha256:placeholder-operator-pins-on-windows + image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2022@sha256:8d0b0e651ad514e3fb05978db66f38036118812e1b9314a48f10419cad8a3462 container_name: certctl-test-iis ports: - "20448:443" diff --git a/deploy/test/f5-mock-icontrol/Dockerfile b/deploy/test/f5-mock-icontrol/Dockerfile index e893565..47e0da2 100644 --- a/deploy/test/f5-mock-icontrol/Dockerfile +++ b/deploy/test/f5-mock-icontrol/Dockerfile @@ -7,13 +7,13 @@ # quarterly per docs/deployment-vendor-matrix.md. # golang:1.25.9-bookworm digest pinned per H-001. -FROM golang:1.25.9-bookworm@sha256:a3a4d83e8e83bf9bb6bf6c5e41bcde5a8e8e1d8e6b9cbcd3b9e7c5d4e7f9c1d5 AS builder +FROM golang:1.25.9-bookworm@sha256:1a1408bf8d2d3077f9508880caf0e8bb0fde195fe3c890e7ea480dfb66dc7827 AS builder WORKDIR /src COPY deploy/test/f5-mock-icontrol/ ./ RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags "-s -w" -o /out/f5-mock-icontrol . # debian:bookworm-slim digest pinned per H-001 (matches libest sidecar). -FROM debian:bookworm-slim@sha256:f9c6a2fd2ddbc23e336b6257a5245e31f996953ef06cd13a59fa0a1df2d5c252 +FROM debian:bookworm-slim@sha256:5a2a80d11944804c01b8619bc967e31801ec39bf3257ab80b91070eb23625644 RUN useradd --create-home --shell /bin/bash mockf5 COPY --from=builder /out/f5-mock-icontrol /usr/local/bin/f5-mock-icontrol USER mockf5