-
Notifications
You must be signed in to change notification settings - Fork 577
Description
Contributing guidelines
- I've read the contributing guidelines and wholeheartedly agree
I've found a bug and checked that ...
- ... the documentation does not mention anything about my problem
- ... there are no open or closed issues that are related to my problem
Description
When running docker buildx build --platform linux/amd64 --platform linux/arm64 --type=docker .
against a docker:dind
container, I sometimes get:
ERROR: failed to build: docker exporter does not currently support exporting manifest lists
But this happens intermittently, and only under load, which seems to imply that the error message is incorrect. Maybe the builder isn't fully initialized or something, but it's returning an error message implying that the driver is incompatible. This can't be given that most of the time the same test passes just fine and I am using the default builder driver every time.
Per @thaJeztah:
Looks like it does feature detection here;
Lines 224 to 233 in 1d7cda1
features := docker.Features(ctx, e.Attrs["context"]) if features[dockerutil.OCIImporter] && e.Output == nil { // rely on oci importer if available (which supports // multi-platform images), otherwise fall back to docker opt.Exports[i].Type = "oci" } else if len(opt.Platforms) > 1 || len(attests) > 0 { if e.Output != nil { return nil, nil, errors.Errorf("docker exporter does not support exporting manifest lists, use the oci exporter instead") } return nil, nil, errors.Errorf("docker exporter does not currently support exporting manifest lists")
Looking at that code, it uses a sync.Once, and discards errors (if ... err == nil), so if it has a failure when trying to detect features the first time, it will discard the error, and considers it “not supported” for the duration of the buildx instance ;
buildx/util/dockerutil/client.go
Lines 76 to 93 in 461bd9e
func (c *Client) Features(ctx context.Context, name string) map[Feature]bool { c.featuresOnce.Do(func() { c.featuresCache = c.features(ctx, name) }) return c.featuresCache } func (c *Client) features(ctx context.Context, name string) map[Feature]bool { features := make(map[Feature]bool) if dapi, err := c.API(name); err == nil { if info, err := dapi.Info(ctx); err == nil { for _, v := range info.DriverStatus { switch v[0] { case "driver-type": if v[1] == "io.containerd.snapshotter.v1" { features[OCIImporter] = true } }
If the only way to check whether a builder is ready for use is a retry-loop then this will result in the builder's feature getting stripped away for the lifetime of the builder which is bad.
Expected behaviour
The result of features detection should only be cached if the builder is fully initialized
Actual behaviour
If an error occurs while communicating with a builder, a feature is marked as "not available" forever
Buildx version
github.com/docker/buildx v0.25.0 faaea65
Docker info
Builders list
NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
default docker
\_ default \_ default running v0.22.0 linux/amd64 (+3), linux/arm64, linux/arm (+2), linux/ppc64le, (2 more)
desktop-linux* docker
\_ desktop-linux \_ desktop-linux running v0.22.0 linux/amd64 (+3), linux/arm64, linux/arm (+2), linux/ppc64le, (2 more)
Configuration
N/A
Build logs
Additional info
No response