Add support for multiple exporters (#235)

Buildkit 0.13 introduced support for [multiple
exporters](https://docs.docker.com/build/exporters/#multiple-exporters).
We currently return an error in these situations.

Instead, inspect the builder's version when loading the node and relax
this error if we see it's running at least 0.13.

Fixes https://github.com/pulumi/pulumi-docker-build/issues/21.
This commit is contained in:
Bryce Lampe
2024-12-10 09:05:36 -08:00
committed by GitHub
parent 2907567484
commit 195fbfc784
15 changed files with 466 additions and 267 deletions

View File

@@ -21,6 +21,7 @@ import (
"sync"
"time"
"github.com/blang/semver"
"github.com/docker/buildx/builder"
"github.com/docker/buildx/store/storeutil"
"github.com/docker/cli/cli/command"
@@ -35,9 +36,12 @@ type host struct {
config *Config
builders map[string]*cachedBuilder
auths map[string]cfgtypes.AuthConfig
// True if the buildkit daemon is at least v0.13.
supportsMultipleExports bool
}
func newHost(config *Config) (*host, error) {
func newHost(ctx context.Context, config *Config) (*host, error) {
docker, err := newDockerCLI(config)
if err != nil {
return nil, err
@@ -47,11 +51,13 @@ func newHost(config *Config) (*host, error) {
if err != nil {
return nil, err
}
h := &host{
cli: docker,
config: config,
builders: map[string]*cachedBuilder{},
auths: auths,
cli: docker,
config: config,
builders: map[string]*cachedBuilder{},
auths: auths,
supportsMultipleExports: false, // Determined when we boot the builder.
}
return h, err
}
@@ -151,10 +157,22 @@ func (h *host) builderFor(build Build) (*cachedBuilder, error) {
// Attempt to load nodes in order to determine the builder's driver. Ignore
// errors for "exec" builds because it's possible to request builders with
// drivers that are unknown to us.
nodes, err := b.LoadNodes(context.Background())
nodes, err := b.LoadNodes(context.Background(), builder.WithData())
if err != nil && !build.ShouldExec() {
return nil, fmt.Errorf("loading nodes: %w", err)
}
// Attempt to determine our builder's buildkit version.
for idx := range nodes {
if nodes[idx].Version == "" {
continue
}
v, err := semver.ParseTolerant(nodes[idx].Version)
if err != nil {
return nil, fmt.Errorf("parsing buildkit version %q: %w", nodes[idx].Version, err)
}
h.supportsMultipleExports = v.GE(semver.MustParse("0.13.0"))
break
}
cached := &cachedBuilder{name: b.Name, driver: b.Driver, nodes: nodes}
h.builders[opts.Builder] = cached