diff --git a/cmd/dockerd/daemon.go b/cmd/dockerd/daemon.go index 16b25e44c8..6bdf0175ea 100644 --- a/cmd/dockerd/daemon.go +++ b/cmd/dockerd/daemon.go @@ -450,6 +450,7 @@ func newRouterOptions(ctx context.Context, config *config.Config, d *daemon.Daem ContainerdNamespace: config.ContainerdNamespace, Callbacks: exporter.BuildkitCallbacks{ Exported: d.ImageExportedByBuildkit, + Named: d.ImageNamedByBuildkit, }, }) if err != nil { diff --git a/daemon/build.go b/daemon/build.go index 613342efbb..f80f622a0a 100644 --- a/daemon/build.go +++ b/daemon/build.go @@ -3,6 +3,8 @@ package daemon import ( "context" + "github.com/distribution/reference" + "github.com/docker/docker/api/types/events" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -11,5 +13,14 @@ import ( // When no tag is given, buildkit doesn't call the image service so it has no // way of knowing the image was created. func (daemon *Daemon) ImageExportedByBuildkit(ctx context.Context, id string, desc ocispec.Descriptor) { - daemon.imageService.LogImageEvent(id, id, "create") + daemon.imageService.LogImageEvent(id, id, events.ActionCreate) +} + +// ImageNamedByBuildkit is a callback that is called when an image is tagged by buildkit. +// Note: It is only called if the buildkit didn't call the image service itself to perform the tagging. +// Currently this only happens when the containerd image store is used. +func (daemon *Daemon) ImageNamedByBuildkit(ctx context.Context, ref reference.NamedTagged, desc ocispec.Descriptor) { + id := desc.Digest.String() + name := reference.FamiliarString(ref) + daemon.imageService.LogImageEvent(id, name, events.ActionTag) } diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index 3f8364723c..66e30e296b 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -6193,40 +6193,70 @@ func (s *DockerCLIBuildSuite) TestBuildIidFileCleanupOnFail(c *testing.T) { assert.Equal(c, os.IsNotExist(err), true) } -func (s *DockerCLIBuildSuite) TestBuildEmitsImageCreateEvent(t *testing.T) { - for _, tc := range []struct { +func (s *DockerCLIBuildSuite) TestBuildEmitsEvents(t *testing.T) { + for _, builder := range []struct { buildkit bool }{ {buildkit: false}, {buildkit: true}, } { - tc := tc - t.Run(fmt.Sprintf("buildkit=%v", tc.buildkit), func(t *testing.T) { - skip.If(t, DaemonIsWindows, "Buildkit is not supported on Windows") + builder := builder + for _, tc := range []struct { + name string + args []string + check func(t *testing.T, stdout string) + }{ + { + name: "no tag", + args: []string{}, + check: func(t *testing.T, stdout string) { + assert.Check(t, is.Contains(stdout, "image create")) + assert.Check(t, !strings.Contains(stdout, "image tag")) + }, + }, + { + 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")) + assert.Check(t, is.Contains(stdout, "testbuildemitsimagetagevent")) + }, + }, + } { + tc := tc + 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") - before := time.Now() + time.Sleep(time.Second) + before := time.Now() - b := cli.Docker(cli.Args("build"), - build.WithoutCache, - build.WithDockerfile("FROM busybox\nRUN echo hi >/hello"), - build.WithBuildkit(tc.buildkit), - ) - b.Assert(t, icmd.Success) - t.Log(b.Stdout()) - t.Log(b.Stderr()) + args := []string{"build"} + args = append(args, tc.args...) - cmd := cli.Docker( - cli.Args("events", - "--filter", "action=create,type=image", - "--since", before.Format(time.RFC3339), - ), - cli.WithTimeout(time.Millisecond*300), - cli.WithEnvironmentVariables("DOCKER_API_VERSION=v1.46"), // FIXME(thaJeztah): integration-cli runs docker CLI 17.06; we're "upgrading" the API version to a version it doesn't support here ;) - ) + b := cli.Docker(cli.Args(args...), + build.WithoutCache, + build.WithDockerfile("FROM busybox\nRUN echo hi >/hello"), + build.WithBuildkit(builder.buildkit), + ) + b.Assert(t, icmd.Success) + t.Log(b.Stdout()) + t.Log(b.Stderr()) - t.Log(cmd.Stdout()) + cmd := cli.Docker( + cli.Args("events", + "--filter", "type=image", + "--since", before.Format(time.RFC3339), + ), + cli.WithTimeout(time.Millisecond*300), + cli.WithEnvironmentVariables("DOCKER_API_VERSION=v1.46"), // FIXME(thaJeztah): integration-cli runs docker CLI 17.06; we're "upgrading" the API version to a version it doesn't support here ;) + ) - assert.Check(t, is.Contains(cmd.Stdout(), "image create")) - }) + stdout := cmd.Stdout() + t.Log(stdout) + + tc.check(t, stdout) + }) + } } }