chore(tests): fix test fixture build on modern ARM Mac (#4666)

BUILDPLATFORM is automatically set to the host's platform in new Docker,
so having it defined as an arg results in it being overridden by this
automatic value. Since it was always assigned to a literal string in the
test files, just use that string.

Additionally, image platform is better pulled from the manifest, not the
image config, in containerd store, so try that first.

Additionally, python3 is on PATH on new macs by default, but not python.

Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com>
This commit is contained in:
Will Murphy 2026-03-11 09:37:40 -04:00 committed by GitHub
parent 75455f050a
commit 7158535fe6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 70 additions and 11 deletions

View File

@ -22,7 +22,7 @@ tools-check:
# docker buildx build --platform linux/amd64 -t $(TOOL_IMAGE) .
tools:
@(docker inspect $(TOOL_IMAGE) > /dev/null && make tools-check) || (docker build -t $(TOOL_IMAGE) . && sha256sum Dockerfile > Dockerfile.sha256)
@(docker image inspect $(TOOL_IMAGE) > /dev/null 2>&1 && make tools-check) || (docker build -t $(TOOL_IMAGE) . && sha256sum Dockerfile > Dockerfile.sha256)
build: tools
mkdir -p $(BIN)
@ -31,7 +31,7 @@ build: tools
verify: tools
@rm -f $(VERIFY_FILE)
docker run -i -v $(shell pwd):/mount -w /mount/project $(TOOL_IMAGE) make verify > $(VERIFY_FILE)
@python ./differ expected_verify $(VERIFY_FILE)
@python3 ./differ expected_verify $(VERIFY_FILE)
debug:
docker run -i --rm -v $(shell pwd):/mount -w /mount/project $(TOOL_IMAGE) bash

View File

@ -1,10 +1,9 @@
# syntax=docker/dockerfile:1
ARG OSXCROSS_VERSION=13.1
ARG BUILDPLATFORM=linux/amd64
FROM --platform=$BUILDPLATFORM crazymax/osxcross:${OSXCROSS_VERSION}-ubuntu AS osxcross
FROM --platform=linux/amd64 crazymax/osxcross:${OSXCROSS_VERSION}-ubuntu AS osxcross
FROM --platform=$BUILDPLATFORM ubuntu:22.04
FROM --platform=linux/amd64 ubuntu:22.04
RUN apt update -y && apt install -y \
curl wget \

View File

@ -19,7 +19,7 @@ tools-check:
@sha256sum -c Dockerfile.sha256 || (echo "Tools Dockerfile has changed" && exit 1)
tools:
@(docker inspect $(TOOL_IMAGE) > /dev/null && make tools-check) || (docker build -t $(TOOL_IMAGE) . && sha256sum Dockerfile > Dockerfile.sha256)
@(docker image inspect $(TOOL_IMAGE) > /dev/null 2>&1 && make tools-check) || (docker build --platform linux/amd64 -t $(TOOL_IMAGE) . && sha256sum Dockerfile > Dockerfile.sha256)
build: tools
@mkdir -p $(BIN)

View File

@ -127,23 +127,83 @@ func pullDockerImage(imageReference, platform string) error {
}
func checkArchitecturesMatch(imageReference, platform string) (bool, string, error) {
// first check if the image exists locally
cmd := exec.Command("docker", "image", "inspect", imageReference)
out, err := cmd.CombinedOutput()
if err := cmd.Run(); err != nil {
return false, "", err
}
// prefer the manifest list for platform info — with Docker's containerd image store,
// platform metadata lives on the manifest list entry, not in the image config.
if found, err := platformInManifest(imageReference, platform); err == nil {
return found, platform, nil
}
// fall back to image config for older Docker daemons that don't support "docker manifest inspect"
gotPlatform, err := platformFromImageInspect(imageReference)
if err != nil {
return false, "", err
}
return gotPlatform == platform, gotPlatform, nil
}
func platformFromImageInspect(imageReference string) (string, error) {
cmd := exec.Command("docker", "image", "inspect", imageReference)
out, err := cmd.CombinedOutput()
if err != nil {
return "", err
}
var inspect []imageInspect
if err := json.Unmarshal(out, &inspect); err != nil {
return false, "", fmt.Errorf("unable to unmarshal image inspect: %w", err)
return "", fmt.Errorf("unable to unmarshal image inspect: %w", err)
}
if len(inspect) != 1 {
return false, "", fmt.Errorf("expected 1 image inspect, got %d", len(inspect))
return "", fmt.Errorf("expected 1 image inspect, got %d", len(inspect))
}
gotPlatform := inspect[0].Platform()
return gotPlatform == platform, gotPlatform, nil
return inspect[0].Platform(), nil
}
type manifestList struct {
Manifests []manifestEntry `json:"manifests"`
}
type manifestEntry struct {
Platform manifestPlatform `json:"platform"`
}
type manifestPlatform struct {
Architecture string `json:"architecture"`
OS string `json:"os"`
}
// platformInManifest checks whether the wanted platform is available in the image's manifest list.
// With Docker's containerd image store, all images are distributed via manifest lists (indexes),
// and platform metadata may only be on the index entry — not in the image config that
// "docker image inspect" reads. "docker manifest inspect" reads the index directly.
func platformInManifest(imageReference, wantPlatform string) (bool, error) {
cmd := exec.Command("docker", "manifest", "inspect", imageReference)
out, err := cmd.CombinedOutput()
if err != nil {
return false, fmt.Errorf("manifest inspect failed: %w", err)
}
var ml manifestList
if err := json.Unmarshal(out, &ml); err != nil {
return false, fmt.Errorf("unable to unmarshal manifest: %w", err)
}
for _, m := range ml.Manifests {
p := fmt.Sprintf("%s/%s", m.Platform.OS, m.Platform.Architecture)
if p == wantPlatform {
return true, nil
}
}
return false, nil
}
func copyBinariesFromDockerImages(config config.BinaryFromImage, destination string) (err error) {