Merge pull request #3136 from ctalledo/reworked-fix-for-moby-45458

Output correct image ID when using Docker with the containerd-snapshotter
This commit is contained in:
Tõnis Tiigi 2025-05-01 16:59:42 -07:00 committed by GitHub
commit 9a48aca461
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 21 additions and 2 deletions

View File

@ -525,7 +525,6 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opts map[
} }
} }
} }
node := dp.Node().Driver node := dp.Node().Driver
if node.IsMobyDriver() { if node.IsMobyDriver() {
for _, e := range so.Exports { for _, e := range so.Exports {
@ -561,6 +560,14 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opts map[
} }
} }
} }
// if prefer-image-digest is set in the solver options, remove the image
// config digest from the exporter's response
for _, e := range so.Exports {
if e.Attrs["prefer-image-digest"] == "true" {
delete(rr.ExporterResponse, exptypes.ExporterImageConfigDigestKey)
break
}
}
return nil return nil
}) })
} }

View File

@ -237,6 +237,11 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt *O
opt.Exports[i].Output = func(_ map[string]string) (io.WriteCloser, error) { opt.Exports[i].Output = func(_ map[string]string) (io.WriteCloser, error) {
return w, nil return w, nil
} }
// if docker is using the containerd snapshotter, prefer to export the image digest
// (rather than the image config digest). See https://github.com/moby/moby/issues/45458.
if features[dockerutil.OCIImporter] {
opt.Exports[i].Attrs["prefer-image-digest"] = "true"
}
} }
} else if !nodeDriver.Features(ctx)[driver.DockerExporter] { } else if !nodeDriver.Features(ctx)[driver.DockerExporter] {
return nil, nil, notSupported(driver.DockerExporter, nodeDriver, "https://docs.docker.com/go/build-exporters/") return nil, nil, notSupported(driver.DockerExporter, nodeDriver, "https://docs.docker.com/go/build-exporters/")

View File

@ -399,18 +399,25 @@ func testImageIDOutput(t *testing.T, sb integration.Sandbox) {
require.Equal(t, dgst.String(), strings.TrimSpace(stdout.String())) require.Equal(t, dgst.String(), strings.TrimSpace(stdout.String()))
// read the md.json file
dt, err = os.ReadFile(filepath.Join(targetDir, "md.json")) dt, err = os.ReadFile(filepath.Join(targetDir, "md.json"))
require.NoError(t, err) require.NoError(t, err)
type mdT struct { type mdT struct {
Digest string `json:"containerimage.digest"`
ConfigDigest string `json:"containerimage.config.digest"` ConfigDigest string `json:"containerimage.config.digest"`
} }
var md mdT var md mdT
err = json.Unmarshal(dt, &md) err = json.Unmarshal(dt, &md)
require.NoError(t, err) require.NoError(t, err)
require.NotEmpty(t, md.ConfigDigest) require.NotEmpty(t, md.ConfigDigest)
require.Equal(t, dgst, digest.Digest(md.ConfigDigest)) require.NotEmpty(t, md.Digest)
// 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)
} }
func testBuildMobyFromLocalImage(t *testing.T, sb integration.Sandbox) { func testBuildMobyFromLocalImage(t *testing.T, sb integration.Sandbox) {