feat: multi-arch (amd64+arm64) root image + haproxy upstream-version pin (2026.11.3) #19

Merged
jknapp merged 1 commits from feat/hmb-multiarch-and-haproxy-pin into main 2026-11-12 02:04:33 +00:00
Owner

What

T5 of the WHP multi-arch image plan.

  1. Root image multi-arch (.gitea/workflows/build-push.yaml): one job on the x86 runner; amd64 (required) and arm64 (QEMU, continue-on-error, 30 min timeout) are pushed BY DIGEST to Gitea + GHCR; scripts/assemble-multiarch-index.sh (unchanged, reused) then creates :latest, :<version>, :<sha> in both registries. arm64 failure => amd64-only tags; stale arm64 never re-attached. Adds workflow_dispatch (was missing). QEMU step now platforms: arm64.
  2. haproxy pin (Dockerfile): was 3.0.11-1+deb13u3. Debian already ships 3.0.11-1+deb13u4 (amd64 and arm64); u3 is still installable, so the build passes today but ships the superseded revision and would hard-fail once u3 leaves the archive. Now ARG HAPROXY_UPSTREAM=3.0.11 + an apt preference Pin: version 3.0.11-* so apt takes the newest Debian revision of that upstream version; the build fails unless dpkg and haproxy -v both report 3.0.11. A 3.0->3.1 / 3.0.12 bump still needs a reviewed ARG change + the haproxy -c gate.
  3. VERSION 2026.11.2 -> 2026.11.3 so the publish does not overwrite the :2026.11.2 rollback tag.

Dockerfile needed no other arch changes (apt haproxy/certbot/socat, pip wheels, no hard-coded binaries). The existing build gate (11 unit suites + haproxy -c scenarios) runs inside the Dockerfile, so it runs for amd64 exactly as before AND for arm64 under QEMU.

Verified locally (throwaway registry, nothing published)

  • amd64 rootfs diff vs main: only the haproxy binary + dpkg metadata (u3 -> u4) plus nondeterministic noise (logs, machine-id, pip cache, pyc, test tmp dirs). No other file differs.
  • Both platforms build; arm64 image runs haproxy -vv (3.0.11-1+deb13u4, same feature list as amd64 incl. QUIC), python imports, validate-rendered-config.py passes on arm64.
  • Index assembled by the real script lists amd64+arm64 for 3 tags x 2 repos; forced arm64 failure (with a stale digest supplied) yields an amd64-only index; scripts/test-assemble-multiarch-index.py 12/12.

Merge / first run

Merging triggers a publish (push to main). Merge with [skip ci] in the merge title, then run workflow_dispatch manually. Record rollback digests first (see PR comment / report).

🤖 Generated with Claude Code

https://claude.ai/code/session_0185ukXjXyosSkunDsdWz3mb

## What T5 of the WHP multi-arch image plan. 1. **Root image multi-arch** (`.gitea/workflows/build-push.yaml`): one job on the x86 runner; amd64 (required) and arm64 (QEMU, `continue-on-error`, 30 min timeout) are pushed BY DIGEST to Gitea + GHCR; `scripts/assemble-multiarch-index.sh` (unchanged, reused) then creates `:latest`, `:<version>`, `:<sha>` in both registries. arm64 failure => amd64-only tags; stale arm64 never re-attached. Adds `workflow_dispatch` (was missing). QEMU step now `platforms: arm64`. 2. **haproxy pin** (`Dockerfile`): was `3.0.11-1+deb13u3`. Debian already ships `3.0.11-1+deb13u4` (amd64 and arm64); u3 is still installable, so the build passes today but ships the superseded revision and would hard-fail once u3 leaves the archive. Now `ARG HAPROXY_UPSTREAM=3.0.11` + an apt preference `Pin: version 3.0.11-*` so apt takes the newest Debian revision of that upstream version; the build fails unless dpkg and `haproxy -v` both report 3.0.11. A 3.0->3.1 / 3.0.12 bump still needs a reviewed ARG change + the `haproxy -c` gate. 3. `VERSION` 2026.11.2 -> 2026.11.3 so the publish does not overwrite the `:2026.11.2` rollback tag. Dockerfile needed no other arch changes (apt haproxy/certbot/socat, pip wheels, no hard-coded binaries). The existing build gate (11 unit suites + `haproxy -c` scenarios) runs inside the Dockerfile, so it runs for amd64 exactly as before AND for arm64 under QEMU. ## Verified locally (throwaway registry, nothing published) - amd64 rootfs diff vs main: only the haproxy binary + dpkg metadata (u3 -> u4) plus nondeterministic noise (logs, machine-id, pip cache, pyc, test tmp dirs). No other file differs. - Both platforms build; arm64 image runs `haproxy -vv` (3.0.11-1+deb13u4, same feature list as amd64 incl. QUIC), python imports, `validate-rendered-config.py` passes on arm64. - Index assembled by the real script lists amd64+arm64 for 3 tags x 2 repos; forced arm64 failure (with a stale digest supplied) yields an amd64-only index; `scripts/test-assemble-multiarch-index.py` 12/12. ## Merge / first run Merging triggers a publish (push to main). Merge with `[skip ci]` in the merge title, then run `workflow_dispatch` manually. Record rollback digests first (see PR comment / report). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_0185ukXjXyosSkunDsdWz3mb
jknapp added 1 commit 2026-11-12 01:42:35 +00:00
- build-push.yaml: one job on the x86 runner; amd64 and arm64 (QEMU,
  continue-on-error) are pushed by digest to Gitea+GHCR, then
  scripts/assemble-multiarch-index.sh creates :latest/:<version>/:<sha>
  (same template as coraza-spoa). arm64 failure publishes amd64-only; a
  stale arm64 digest is never re-attached. Adds workflow_dispatch.
- Dockerfile: pin the reviewed UPSTREAM version (HAPROXY_UPSTREAM=3.0.11) via
  an apt preference so the newest Debian security revision is taken
  (3.0.11-1+deb13u4 today), and fail the build unless dpkg and `haproxy -v`
  both report that upstream version. The exact +deb13uN pin froze the image
  on the superseded u3 and would have hard-failed once u3 left the archive.
- The existing build gate (unit suites + haproxy -c) is unchanged and runs
  for each platform.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0185ukXjXyosSkunDsdWz3mb
jknapp merged commit 46ea498db3 into main 2026-11-12 02:04:33 +00:00
jknapp deleted branch feat/hmb-multiarch-and-haproxy-pin 2026-11-12 02:04:33 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: cloud-hosting-platform/haproxy-manager-base#19