Skip to content

Commit aa4afa7

Browse files
committed
build: docker exporter should instead use oci with containerd
Signed-off-by: Justin Chadwell <me@jedevc.com>
1 parent 167cd16 commit aa4afa7

3 files changed

Lines changed: 45 additions & 9 deletions

File tree

build/build.go

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ func toRepoOnly(in string) (string, error) {
363363
return strings.Join(out, ","), nil
364364
}
365365

366-
func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Options, bopts gateway.BuildOpts, configDir string, pw progress.Writer, dl dockerLoadCallback) (solveOpt *client.SolveOpt, release func(), err error) {
366+
func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Options, bopts gateway.BuildOpts, configDir string, pw progress.Writer, docker *dockerutil.Client) (solveOpt *client.SolveOpt, release func(), err error) {
367367
nodeDriver := node.Driver
368368
defers := make([]func(), 0, 2)
369369
releaseF := func() {
@@ -531,14 +531,27 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Op
531531
return nil, nil, notSupported(nodeDriver, driver.OCIExporter)
532532
}
533533
if e.Type == "docker" {
534-
if len(opt.Platforms) > 1 || len(attests) > 0 {
535-
return nil, nil, errors.Errorf("docker exporter does not currently support exporting manifest lists")
534+
features, err := docker.Features(ctx, e.Attrs["context"])
535+
if err != nil {
536+
return nil, nil, err
537+
}
538+
if features[dockerutil.OCIImporter] && e.Output == nil {
539+
// rely on oci importer if available (which supports
540+
// multi-platform images), otherwise fall back to docker
541+
opt.Exports[i].Type = "oci"
542+
} else if len(opt.Platforms) > 1 || len(attests) > 0 {
543+
if !features[dockerutil.OCIImporter] {
544+
return nil, nil, errors.Errorf("docker exporter does not currently support exporting manifest lists")
545+
}
546+
if e.Output != nil {
547+
return nil, nil, errors.Errorf("docker exporter does not support exporting manifest lists, use the oci exporter instead")
548+
}
536549
}
537550
if e.Output == nil {
538551
if nodeDriver.IsMobyDriver() {
539552
e.Type = "image"
540553
} else {
541-
w, cancel, err := dl(e.Attrs["context"])
554+
w, cancel, err := docker.LoadImage(ctx, e.Attrs["context"], pw)
542555
if err != nil {
543556
return nil, nil, err
544557
}
@@ -733,9 +746,7 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
733746
hasMobyDriver = true
734747
}
735748
opt.Platforms = np.platforms
736-
so, release, err := toSolveOpt(ctx, node, multiDriver, opt, np.bopts, configDir, w, func(name string) (io.WriteCloser, func(), error) {
737-
return docker.LoadImage(ctx, name, w)
738-
})
749+
so, release, err := toSolveOpt(ctx, node, multiDriver, opt, np.bopts, configDir, w, docker)
739750
if err != nil {
740751
return nil, err
741752
}
@@ -1543,8 +1554,6 @@ func notSupported(d driver.Driver, f driver.Feature) error {
15431554
return errors.Errorf("%s feature is currently not supported for %s driver. Please switch to a different driver (eg. \"docker buildx create --use\")", f, d.Factory().Name())
15441555
}
15451556

1546-
type dockerLoadCallback func(name string) (io.WriteCloser, func(), error)
1547-
15481557
func noDefaultLoad() bool {
15491558
v, ok := os.LookupEnv("BUILDX_NO_DEFAULT_LOAD")
15501559
if !ok {

util/dockerutil/client.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,28 @@ func (c *Client) LoadImage(ctx context.Context, name string, status progress.Wri
6363
}, nil
6464
}
6565

66+
func (c *Client) Features(ctx context.Context, name string) (map[Feature]bool, error) {
67+
dapi, err := c.API(name)
68+
if err != nil {
69+
return nil, err
70+
}
71+
info, err := dapi.Info(ctx)
72+
if err != nil {
73+
return nil, err
74+
}
75+
76+
features := make(map[Feature]bool)
77+
for _, v := range info.DriverStatus {
78+
switch v[0] {
79+
case "driver-type":
80+
if v[1] == "io.containerd.snapshotter.v1" {
81+
features[OCIImporter] = true
82+
}
83+
}
84+
}
85+
return features, nil
86+
}
87+
6688
type waitingWriter struct {
6789
*io.PipeWriter
6890
f func()

util/dockerutil/features.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package dockerutil
2+
3+
type Feature string
4+
5+
const OCIImporter Feature = "OCI importer"

0 commit comments

Comments
 (0)