diff --git a/build/opt.go b/build/opt.go index 78aa7c533e69..c32eb0ceea68 100644 --- a/build/opt.go +++ b/build/opt.go @@ -491,6 +491,10 @@ func toSolveOpt(ctx context.Context, np *noderesolver.ResolvedNode, multiDriver } if e.Type == "image" && nodeDriver.IsMobyDriver() { opt.Exports[i].Type = "moby" + // The containerd image store resolves images by manifest or index digest. + if nodeDriver.Features(ctx)[driver.PreferImageDigest] { + opt.Exports[i].Attrs["prefer-image-digest"] = "true" + } if e.Attrs["push"] != "" { if ok, _ := strconv.ParseBool(e.Attrs["push"]); ok { if ok, _ := strconv.ParseBool(e.Attrs["push-by-digest"]); ok { diff --git a/commands/build.go b/commands/build.go index 6c310cd6f190..04d20bea6e41 100644 --- a/commands/build.go +++ b/commands/build.go @@ -463,7 +463,7 @@ func runBuild(ctx context.Context, dockerCli command.Cli, debugOpts debuggerOpti return nil } -// getImageID returns the image ID - the digest of the image config +// getImageID returns the image identifier selected for the export destination. func getImageID(resp map[string]string) string { dgst := resp[exptypes.ExporterImageDigestKey] if v, ok := resp[exptypes.ExporterImageConfigDigestKey]; ok { diff --git a/driver/docker/driver.go b/driver/docker/driver.go index 787f323d5175..402509b613b7 100644 --- a/driver/docker/driver.go +++ b/driver/docker/driver.go @@ -92,12 +92,13 @@ func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool { c.Close() } d.features.list = map[driver.Feature]bool{ - driver.OCIExporter: useContainerdSnapshotter, - driver.DockerExporter: useContainerdSnapshotter, - driver.CacheExport: useContainerdSnapshotter, - driver.MultiPlatform: useContainerdSnapshotter, - driver.DirectPush: useContainerdSnapshotter, - driver.DefaultLoad: true, + driver.OCIExporter: useContainerdSnapshotter, + driver.DockerExporter: useContainerdSnapshotter, + driver.CacheExport: useContainerdSnapshotter, + driver.MultiPlatform: useContainerdSnapshotter, + driver.DirectPush: useContainerdSnapshotter, + driver.PreferImageDigest: useContainerdSnapshotter, + driver.DefaultLoad: true, } }) return d.features.list diff --git a/driver/features.go b/driver/features.go index c12d9c7490f0..dec8623ce4e7 100644 --- a/driver/features.go +++ b/driver/features.go @@ -8,5 +8,6 @@ const DockerExporter Feature = "Docker exporter" const CacheExport Feature = "Cache export" const MultiPlatform Feature = "Multi-platform build" const DirectPush Feature = "Direct push" +const PreferImageDigest Feature = "Prefer image digest" const DefaultLoad Feature = "Automatically load images to the Docker Engine image store" diff --git a/tests/build.go b/tests/build.go index d3a69500e086..1ed34642e193 100644 --- a/tests/build.go +++ b/tests/build.go @@ -682,12 +682,19 @@ func testImageIDOutput(t *testing.T, sb integration.Sandbox) { err = json.Unmarshal(dt, &md) require.NoError(t, err) - require.NotEmpty(t, md.ConfigDigest) require.NotEmpty(t, md.Digest) + if !isMobyContainerdSnapWorker(sb) { + require.NotEmpty(t, md.ConfigDigest) + } // verify the image ID output is correct - // XXX: improve this by checking that it's one of the two expected digests depending on the scenario. require.Contains(t, []digest.Digest{digest.Digest(md.ConfigDigest), digest.Digest(md.Digest)}, dgst) + + if sb.DockerAddress() != "" { + cmd = dockerCmd(sb, withArgs("image", "inspect", imageID)) + out, err := cmd.CombinedOutput() + require.NoError(t, err, string(out)) + } } func testBuildMobyFromLocalImage(t *testing.T, sb integration.Sandbox) {