Fix bare platform strings resolving to the runner host's OS

Closes #39622 (closed)

What does this MR do?

Split out of !6990 (merged) (minimum viable change: this is an independent, pre-existing bug, unrelated to Podman) -- discovered while verifying that fix locally against real Podman, but reproducible with plain Docker too.

parsePlatform (executors/docker/internal/pull/manager.go) calls platforms.Parse with no guard. For a bare architecture specifier with no OS component (e.g. arm64, exactly how a docker image platform value is commonly written, and how the existing TestDockerCommandWithPlatform test already uses it), that library resolves the missing OS using the host's own runtime.GOOS rather than a container OS. That's harmless on Linux and Windows hosts (both are also valid container OSes), but GitLab Runner also officially ships and documents macOS binaries (docs/install/osx.md), and macOS never runs native containers -- it's always Linux underneath. Any runner on macOS setting a bare-arch platform value fails every pull with:

Error response from daemon: no image found in manifest list for architecture "arm64", variant "", OS "darwin"

Confirmed this isn't hypothetical by calling platforms.Parse("arm64") directly on a real macOS machine -- it returns OS:darwin.

This bug predates all of !6990 (merged) -- it was introduced by the original moby/moby v29 SDK migration (952dffe4629f7a6de87903db6a9d82e3035cdf6b), which is the same commit that added the parsePlatform/platform-aware inspect functionality in the first place.

Fixed by normalizing any resolved OS that isn't linux or windows to linux, since no third container OS exists.

Testing

  • TestNormalizeContainerOS tests the normalization logic directly with explicit OS strings, so it fails deterministically regardless of which OS the test itself runs on -- unlike testing via parsePlatform directly, whose result depends on the host running the test (e.g. this bug is invisible on Linux CI, since Linux is already both the host and the intended target OS).
  • TestParsePlatformNeverReturnsDarwin covers the full parsePlatform call path.
  • go test ./executors/docker/internal/pull/... passes.
  • make lint passes with 0 issues.
Edited by Lachlan Grant

Merge request reports

Loading