Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Target platforms not being considered for "frontend.lint" request #5693

Open
4 tasks done
GabriFedi97 opened this issue Jan 31, 2025 · 6 comments · May be fixed by docker/buildx#2984
Open
4 tasks done

Target platforms not being considered for "frontend.lint" request #5693

GabriFedi97 opened this issue Jan 31, 2025 · 6 comments · May be fixed by docker/buildx#2984

Comments

@GabriFedi97
Copy link

GabriFedi97 commented Jan 31, 2025

Contributing guidelines and issue reporting guide

Well-formed report checklist

  • I have found a bug that the documentation does not mention anything about my problem
  • I have found a bug that there are no open or closed issues that are related to my problem
  • I have provided version/information about my environment and done my best to provide a reproducer

Description of bug

Bug description

When the validation of the Dockerfile is performed according to the frontend.lint request, the existence assestment of the declared base image is performed against the upstream container registry. This operation ignores the actual target platforms that are part of the request and fall back to the (sigle) default platform of the underlaying host or builder instance.
This has an impact on the buildx build --check and buildx bake --check feature for cross-platform build requests as the checks don't honour the actual target platforms specified in the request.

There is already an opened issue in the docker/buildx GitHub project, but I thought it was worth opening a ticket also here since the bug belongs to buildkit.

Reproduction

  1. Create a builder instance with platform linux/riscv64
docker buildx create --driver=docker-container --name=buildkit-riscv64 --driver-opt image=moby/buildkit@sha256:2abbfccea9734baf68b7892f1a5feb541825dd0ffe049872d7c4b7deb2cff2b4 --bootstrap --use
  1. Create simple Dockerfile with the following content:
FROM postgres:17.2-bookworm
  1. Create docker-bake.hcl file with he following content:
target "default" {
  platforms = ["linux/amd64"]
}
  1. Run both buildx build and buildx bake to reproduce the issue:
$ docker buildx build --platform=linux/amd64  --check  --debug .
[+] Building 0.9s (3/3) FINISHED                                                        docker-container:buildkit-riscv64
 => [internal] load build definition from Dockerfile                                                                 0.0s
 => => transferring dockerfile: 64B                                                                                  0.0s
 => ERROR [internal] load metadata for docker.io/library/postgres:17.2-bookworm                                      0.9s
 => Verifying build result                                                                                           0.0s
 => WARN: Requested platform "linux/amd64" does not match result platform "linux/riscv64"                            0.0s
------
 > [internal] load metadata for docker.io/library/postgres:17.2-bookworm:
------

 1 warning found (use docker --debug to expand):
 - Requested platform "linux/amd64" does not match result platform "linux/riscv64"
ERROR: postgres:17.2-bookworm: failed to resolve source metadata for docker.io/library/postgres:17.2-bookworm: no match for platform in manifest: not found
Dockerfile:1
--------------------
   1 | >>> FROM postgres:17.2-bookworm
--------------------

91945 v0.20.1-desktop.2 /Users/gabrielefedi/.docker/cli-plugins/docker-buildx buildx build --platform=linux/amd64 --check --debug .
github.com/docker/buildx/commands.printResult
	github.com/docker/buildx/commands/build.go:957
github.com/docker/buildx/commands.runBuild
	github.com/docker/buildx/commands/build.go:396
github.com/docker/buildx/commands.buildCmd.func1
	github.com/docker/buildx/commands/build.go:580
github.com/docker/cli/cli-plugins/plugin.RunPlugin.func1.1.2
	github.com/docker/cli@v27.5.0+incompatible/cli-plugins/plugin/plugin.go:64
github.com/spf13/cobra.(*Command).execute
	github.com/spf13/cobra@v1.8.1/command.go:985
github.com/spf13/cobra.(*Command).ExecuteC
	github.com/spf13/cobra@v1.8.1/command.go:1117
github.com/spf13/cobra.(*Command).Execute
	github.com/spf13/cobra@v1.8.1/command.go:1041
github.com/docker/cli/cli-plugins/plugin.RunPlugin
	github.com/docker/cli@v27.5.0+incompatible/cli-plugins/plugin/plugin.go:79
main.runPlugin
	github.com/docker/buildx/cmd/buildx/main.go:66
main.run
	github.com/docker/buildx/cmd/buildx/main.go:80
main.main
	github.com/docker/buildx/cmd/buildx/main.go:90
runtime.main
	runtime/proc.go:272
runtime.goexit
	runtime/asm_arm64.s:1223
$ docker buildx bake --check
[+] Building 0.5s (4/4) FINISHED                                                        docker-container:buildkit-riscv64
 => [internal] load local bake definitions                                                                           0.0s
 => => reading docker-bake.hcl 50B / 50B                                                                             0.0s
 => [internal] load build definition from Dockerfile                                                                 0.0s
 => => transferring dockerfile: 64B                                                                                  0.0s
 => ERROR [internal] load metadata for docker.io/library/postgres:17.2-bookworm                                      0.2s
 => Verifying build result                                                                                           0.0s
 => WARN: Requested platform "linux/amd64" does not match result platform "linux/riscv64"                            0.0s
------
 > [internal] load metadata for docker.io/library/postgres:17.2-bookworm:
------

 1 warning found (use docker --debug to expand):
 - Requested platform "linux/amd64" does not match result platform "linux/riscv64"
default

error: postgres:17.2-bookworm: failed to resolve source metadata for docker.io/library/postgres:17.2-bookworm: no match for platform in manifest: not found
Dockerfile:1
--------------------
   1 | >>> FROM postgres:17.2-bookworm
--------------------

The same thing doesn't happen if the actual build operation is requested, without --check.

Version information

docker buildx version && docker buildx inspect
github.com/docker/buildx v0.20.1-desktop.2 aaf7c2bc7f9ec3afee1cec77d671845a4b57a0c8
Name:          buildkit-riscv64
Driver:        docker-container
Last Activity: 2025-01-31 10:05:34 +0000 UTC

Nodes:
Name:                  buildkit-riscv640
Endpoint:              desktop-linux
Driver Options:        image="moby/buildkit@sha256:2abbfccea9734baf68b7892f1a5feb541825dd0ffe049872d7c4b7deb2cff2b4"
Status:                running
BuildKit daemon flags: --allow-insecure-entitlement=network.host
BuildKit version:      v0.19.0
Platforms:             linux/riscv64, linux/amd64, linux/amd64/v2, linux/arm64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
Labels:
 org.mobyproject.buildkit.worker.executor:         oci
 org.mobyproject.buildkit.worker.hostname:         9bef3a10d0b7
 org.mobyproject.buildkit.worker.network:          host
 org.mobyproject.buildkit.worker.oci.process-mode: sandbox
 org.mobyproject.buildkit.worker.selinux.enabled:  false
 org.mobyproject.buildkit.worker.snapshotter:      overlayfs
GC Policy rule#0:
 All:            false
 Filters:        type==source.local,type==exec.cachemount,type==source.git.checkout
 Keep Duration:  48h0m0s
 Max Used Space: 488.3MiB
GC Policy rule#1:
 All:            false
 Keep Duration:  1440h0m0s
 Reserved Space: 9.313GiB
 Max Used Space: 93.13GiB
 Min Free Space: 69.85GiB
GC Policy rule#2:
 All:            false
 Reserved Space: 9.313GiB
 Max Used Space: 93.13GiB
 Min Free Space: 69.85GiB
GC Policy rule#3:
 All:            true
 Reserved Space: 9.313GiB
 Max Used Space: 93.13GiB
 Min Free Space: 69.85GiB
@GabriFedi97
Copy link
Author

As part of my investigation the issue is that the lint sub request is not performed iterating over the target platforms and the convertOpt.TargetPlatform is never populated from the bc.TargetPlatforms values.
The LintResults return value should be able to store multiple errors, one per TargetPlatform, but this probably requires the LintResults.Error field to become a slice and this would break the API used by buildx build/bake clients when invoked with --check.
I'd be happy to contribute to this fix and propose a patch.

@tonistiigi
Copy link
Member

docker/buildx#2888 is also likely same

@jsternberg
Copy link
Collaborator

I think we can likely just concatenate the results. It seems the Error field is for a build error so I'm not sure we need to parameterize that. I'll work on fixing this.

This is also reproducible by just putting --platform linux/arm64 on an amd64 machine and --platform linux/amd64 on an arm64 machine.

@jsternberg jsternberg self-assigned this Feb 10, 2025
@jsternberg
Copy link
Collaborator

Looking into this more, this doesn't seem to be an issue with TargetPlatform not being set. Setting TargetPlatform doesn't change the result.

The linter here is checking that the exporter key has been set on the result and it matches the expected result. For the lint and outline methods, the exporter key never gets set so it ends up defaulting to the current machine. There's probably two solutions to this.

  1. Properly set the exporter key. This normally gets set here: https://github.com/moby/buildkit/blob/master/frontend/dockerui/build.go#L114. I don't think this is correct because the result doesn't have a platform and I don't think that makes sense.
  2. Do not run this lint when there isn't an actual result. I think the purpose of this lint is to check that the actual result matches what was supposed to be built. I don't think this is valid when the result doesn't exist because it wasn't part of the run.

@jsternberg
Copy link
Collaborator

I think this is actually a problem in buildx. It seems to be setting some of the frontend attributes that this linter check relies on inside of the build callback instead of before the build is executed so the relevant lint check doesn't know that it's supposed to be skipped. This only happens when using buildx or buildctl (both of them make this same mistake).

@jsternberg
Copy link
Collaborator

Discussed this with @tonistiigi a bit and we're going to find a way to fix this on the buildkit side. We're likely going to update the verifier so it doesn't rely on the captured frontend opts and instead can identify the result comes from a subrequest through some metadata.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment