diff --git a/builder/builder-next/exporter/wrapper.go b/builder/builder-next/exporter/wrapper.go index c78e261af6..31a79a02d5 100644 --- a/builder/builder-next/exporter/wrapper.go +++ b/builder/builder-next/exporter/wrapper.go @@ -82,21 +82,33 @@ func (i *imageExporterInstanceWrapper) Export(ctx context.Context, src *exporter } if i.callbacks.Named != nil { - for _, name := range strings.Split(out[string(exptypes.OptKeyName)], ",") { - ref, err := reference.ParseNormalizedNamed(name) - if err != nil { - // Shouldn't happen, but log if it does and continue. - log.G(ctx).WithFields(log.Fields{ - "name": name, - "error": err, - }).Warn("image named with invalid reference produced by buildkit") - continue - } - - namedTagged := reference.TagNameOnly(ref).(reference.NamedTagged) - i.callbacks.Named(ctx, namedTagged, desc) - } + i.processNamedCallback(ctx, out, desc) } return out, ref, nil } + +func (i *imageExporterInstanceWrapper) processNamedCallback(ctx context.Context, out map[string]string, desc ocispec.Descriptor) { + // TODO(vvoland): Change to exptypes.ExporterImageNameKey when BuildKit v0.21 is vendored. + imageName := out["image.name"] + if imageName == "" { + log.G(ctx).Warn("image named with empty image.name produced by buildkit") + return + } + + for _, name := range strings.Split(imageName, ",") { + ref, err := reference.ParseNormalizedNamed(name) + if err != nil { + // Shouldn't happen, but log if it does and continue. + log.G(ctx).WithFields(log.Fields{ + "name": name, + "error": err, + }).Warn("image named with invalid reference produced by buildkit") + continue + } + + if namedTagged, ok := reference.TagNameOnly(ref).(reference.NamedTagged); ok { + i.callbacks.Named(ctx, namedTagged, desc) + } + } +} diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index 77bfbbec52..7aac687867 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -6209,7 +6209,9 @@ func (s *DockerCLIBuildSuite) TestBuildEmitsEvents(t *testing.T) { name: "no tag", args: []string{}, check: func(t *testing.T, stdout string) { - assert.Check(t, is.Contains(stdout, "image create")) + if assert.Check(t, is.Contains(stdout, "image create")) { + assert.Check(t, strings.Count(stdout, "image create") == 1) + } assert.Check(t, !strings.Contains(stdout, "image tag")) }, }, @@ -6217,14 +6219,20 @@ func (s *DockerCLIBuildSuite) TestBuildEmitsEvents(t *testing.T) { name: "with tag", args: []string{"-t", "testbuildemitsimagetagevent"}, check: func(t *testing.T, stdout string) { - assert.Check(t, is.Contains(stdout, "image create")) - assert.Check(t, is.Contains(stdout, "image tag")) + if assert.Check(t, is.Contains(stdout, "image create")) { + assert.Check(t, strings.Count(stdout, "image create") == 1) + } + if assert.Check(t, is.Contains(stdout, "image tag")) { + assert.Check(t, strings.Count(stdout, "image tag") == 1) + } assert.Check(t, is.Contains(stdout, "testbuildemitsimagetagevent")) }, }, } { t.Run(fmt.Sprintf("buildkit=%v/%s", builder.buildkit, tc.name), func(t *testing.T) { - skip.If(t, DaemonIsWindows, "Buildkit is not supported on Windows") + if builder.buildkit { + skip.If(t, DaemonIsWindows, "Buildkit is not supported on Windows") + } time.Sleep(time.Second) before := time.Now()