Skip to content

fix(cni): select embedded CNI plugins by arch (arm64 macOS dispatch)#119

Merged
luthermonson merged 1 commit into
mainfrom
fix/cni-arm64
Jul 15, 2026
Merged

fix(cni): select embedded CNI plugins by arch (arm64 macOS dispatch)#119
luthermonson merged 1 commit into
mainfrom
fix/cni-arm64

Conversation

@luthermonson

Copy link
Copy Markdown
Contributor

Summary

Second darwin/arm64 asset-selection bug (sibling of #118). Caught live: no Linux job can run on an Apple Silicon Mac runner — every one dies at container network setup with:

CNI setup ... plugin type="loopback" failed (add): ... exec format error

Root cause: on macOS, ephemerd runs Linux container jobs inside an arm64 Linux VM. The macOS build cross-compiles ephemerd-linux for arm64 and downloads the arm64 CNI plugins — but the amd64 tarball also lingers in pkg/cni/embed/ (CI cache / runner Dockerfile). //go:embed all:embed bundles both, and findTarball() returned the first entry, which sorts to amd64. So the arm64 VM got amd64 CNI binaries → exec format error → all Linux jobs fail.

The runner assets already stash non-matching arches to avoid exactly this; CNI didn't.

Change

findTarball() now selects cni-plugins-linux-<GOARCH>-*.tgz by the compiled arch of the in-VM ephemerd-linux (arm64 on Apple Silicon, amd64 on Linux/Windows-VM). Pure selection logic extracted to select.go with a table test; a clear error lists what's embedded when no arch matches.

Test plan

  • TestSelectCNITarball — arm64 picks arm64 when both are embedded (the actual bug), amd64 picks amd64, gitkeep skipped, no-match/empty error
  • cross-builds clean: linux/arm64, linux/amd64, darwin/arm64
  • end-to-end: a Linux job on a Mac runner completes (verifiable once this is in a release and the mini upgrades)

Note

Discovered while bringing up the first mayfly-managed Mac mini runner. The mini's Linux dispatch is currently disabled (daemon booted out) to stop it claiming+failing org Linux jobs; it comes back once this ships in a release.

On Apple Silicon, ephemerd boots an arm64 Linux VM to run Linux
container jobs. The macOS build cross-compiles ephemerd-linux for arm64
and downloads the arm64 CNI plugins, but the amd64 tarball also lingers
in pkg/cni/embed/ (CI cache / Dockerfile). `//go:embed all:embed`
bundles both, and findTarball() returned the first entry — amd64. Every
container's CNI setup then failed inside the arm64 VM with:

  plugin type="loopback" ... exec format error

so no Linux job could run on a Mac runner.

Select the archive by runtime.GOARCH (the compiled arch of the in-VM
ephemerd-linux) instead of grabbing whichever tarball sorts first. The
runners already stash non-matching arches for this reason; CNI now does
the equivalent at extract time. Pure selection logic lives in select.go
with a table test; a clear error lists what's embedded when no arch
matches.
@luthermonson
luthermonson merged commit 3bf7490 into main Jul 15, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant