diff --git a/api/server/backend/build/backend.go b/api/server/backend/build/backend.go index 11b6d20a12..0d81c0138a 100644 --- a/api/server/backend/build/backend.go +++ b/api/server/backend/build/backend.go @@ -3,12 +3,15 @@ package build // import "github.com/docker/docker/api/server/backend/build" import ( "context" "fmt" + "strconv" "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/backend" + "github.com/docker/docker/api/types/events" "github.com/docker/docker/builder" buildkit "github.com/docker/docker/builder/builder-next" + daemonevents "github.com/docker/docker/daemon/events" "github.com/docker/docker/image" "github.com/docker/docker/pkg/stringid" "github.com/pkg/errors" @@ -31,11 +34,12 @@ type Backend struct { builder Builder imageComponent ImageComponent buildkit *buildkit.Builder + eventsService *daemonevents.Events } // NewBackend creates a new build backend from components -func NewBackend(components ImageComponent, builder Builder, buildkit *buildkit.Builder) (*Backend, error) { - return &Backend{imageComponent: components, builder: builder, buildkit: buildkit}, nil +func NewBackend(components ImageComponent, builder Builder, buildkit *buildkit.Builder, es *daemonevents.Events) (*Backend, error) { + return &Backend{imageComponent: components, builder: builder, buildkit: buildkit, eventsService: es}, nil } // RegisterGRPC registers buildkit controller to the grpc server. @@ -100,6 +104,11 @@ func (b *Backend) PruneCache(ctx context.Context, opts types.BuildCachePruneOpti if err != nil { return nil, errors.Wrap(err, "failed to prune build cache") } + b.eventsService.Log("prune", events.BuilderEventType, events.Actor{ + Attributes: map[string]string{ + "reclaimed": strconv.FormatInt(buildCacheSize, 10), + }, + }) return &types.BuildCachePruneReport{SpaceReclaimed: uint64(buildCacheSize), CachesDeleted: cacheIDs}, nil } diff --git a/api/swagger.yaml b/api/swagger.yaml index 6ebdd04946..fb66f4fd0d 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -8131,13 +8131,13 @@ paths: Various objects within Docker report events when something happens to them. - Containers report these events: `attach`, `commit`, `copy`, `create`, `destroy`, `detach`, `die`, `exec_create`, `exec_detach`, `exec_start`, `exec_die`, `export`, `health_status`, `kill`, `oom`, `pause`, `rename`, `resize`, `restart`, `start`, `stop`, `top`, `unpause`, and `update` + Containers report these events: `attach`, `commit`, `copy`, `create`, `destroy`, `detach`, `die`, `exec_create`, `exec_detach`, `exec_start`, `exec_die`, `export`, `health_status`, `kill`, `oom`, `pause`, `rename`, `resize`, `restart`, `start`, `stop`, `top`, `unpause`, `update`, and `prune` - Images report these events: `delete`, `import`, `load`, `pull`, `push`, `save`, `tag`, and `untag` + Images report these events: `delete`, `import`, `load`, `pull`, `push`, `save`, `tag`, `untag`, and `prune` - Volumes report these events: `create`, `mount`, `unmount`, and `destroy` + Volumes report these events: `create`, `mount`, `unmount`, `destroy`, and `prune` - Networks report these events: `create`, `connect`, `disconnect`, `destroy`, `update`, and `remove` + Networks report these events: `create`, `connect`, `disconnect`, `destroy`, `update`, `remove`, and `prune` The Docker daemon reports these events: `reload` @@ -8149,6 +8149,8 @@ paths: Configs report these events: `create`, `update`, and `remove` + The Builder reports `prune` events + operationId: "SystemEvents" produces: - "application/json" diff --git a/api/types/events/events.go b/api/types/events/events.go index 027c6edb72..aa8fba8154 100644 --- a/api/types/events/events.go +++ b/api/types/events/events.go @@ -1,6 +1,8 @@ package events // import "github.com/docker/docker/api/types/events" const ( + // BuilderEventType is the event type that the builder generates + BuilderEventType = "builder" // ContainerEventType is the event type that containers generate ContainerEventType = "container" // DaemonEventType is the event type that daemon generate diff --git a/cmd/dockerd/daemon.go b/cmd/dockerd/daemon.go index f8fd53b72e..842e7f4eb8 100644 --- a/cmd/dockerd/daemon.go +++ b/cmd/dockerd/daemon.go @@ -299,7 +299,7 @@ func newRouterOptions(config *config.Config, d *daemon.Daemon) (routerOptions, e return opts, err } - bb, err := buildbackend.NewBackend(d.ImageService(), manager, bk) + bb, err := buildbackend.NewBackend(d.ImageService(), manager, bk, d.EventsService) if err != nil { return opts, errors.Wrap(err, "failed to create buildmanager") } diff --git a/daemon/images/image_prune.go b/daemon/images/image_prune.go index aa8019b9a4..d353f98da0 100644 --- a/daemon/images/image_prune.go +++ b/daemon/images/image_prune.go @@ -3,11 +3,13 @@ package images // import "github.com/docker/docker/daemon/images" import ( "context" "fmt" + "strconv" "sync/atomic" "time" "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/events" "github.com/docker/docker/api/types/filters" timetypes "github.com/docker/docker/api/types/time" "github.com/docker/docker/errdefs" @@ -159,7 +161,11 @@ deleteImagesLoop: if canceled { logrus.Debugf("ImagesPrune operation cancelled: %#v", *rep) } - + i.eventsService.Log("prune", events.ImageEventType, events.Actor{ + Attributes: map[string]string{ + "reclaimed": strconv.FormatUint(rep.SpaceReclaimed, 10), + }, + }) return rep, nil } diff --git a/daemon/prune.go b/daemon/prune.go index b1bcd5b79c..493aba4909 100644 --- a/daemon/prune.go +++ b/daemon/prune.go @@ -4,10 +4,12 @@ import ( "context" "fmt" "regexp" + "strconv" "sync/atomic" "time" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/events" "github.com/docker/docker/api/types/filters" timetypes "github.com/docker/docker/api/types/time" "github.com/docker/docker/errdefs" @@ -84,7 +86,9 @@ func (daemon *Daemon) ContainersPrune(ctx context.Context, pruneFilters filters. rep.ContainersDeleted = append(rep.ContainersDeleted, c.ID) } } - + daemon.EventsService.Log("prune", events.ContainerEventType, events.Actor{ + Attributes: map[string]string{"reclaimed": strconv.FormatUint(rep.SpaceReclaimed, 10)}, + }) return rep, nil } @@ -210,7 +214,9 @@ func (daemon *Daemon) NetworksPrune(ctx context.Context, pruneFilters filters.Ar return rep, nil default: } - + daemon.EventsService.Log("prune", events.NetworkEventType, events.Actor{ + Attributes: map[string]string{"reclaimed": "0"}, + }) return rep, nil } diff --git a/docs/api/version-history.md b/docs/api/version-history.md index d1bcadf0db..e30babe862 100644 --- a/docs/api/version-history.md +++ b/docs/api/version-history.md @@ -17,6 +17,10 @@ keywords: "API, Docker, rcli, REST, documentation" [Docker Engine API v1.41](https://docs.docker.com/engine/api/v1.41/) documentation +* `GET /events` now returns `prune` events after pruning resources have completed. + Prune events are returned for `container`, `network`, `volume`, `image`, and + `builder`, and have a `reclaimed` attribute, indicating the amount of space + reclaimed (in bytes). * `GET /info` now returns a `CgroupVersion` field, containing the cgroup version. * `GET /info` now returns a `DefaultAddressPools` field, containing a list of custom default address pools for local networks, which can be specified in the diff --git a/volume/service/service.go b/volume/service/service.go index 8dbfa283c8..b185471a39 100644 --- a/volume/service/service.go +++ b/volume/service/service.go @@ -2,6 +2,7 @@ package service // import "github.com/docker/docker/volume/service" import ( "context" + "strconv" "sync/atomic" "github.com/docker/docker/api/types" @@ -238,6 +239,9 @@ func (s *VolumesService) Prune(ctx context.Context, filter filters.Args) (*types rep.SpaceReclaimed += uint64(vSize) rep.VolumesDeleted = append(rep.VolumesDeleted, v.Name()) } + s.eventLogger.LogVolumeEvent("", "prune", map[string]string{ + "reclaimed": strconv.FormatInt(int64(rep.SpaceReclaimed), 10), + }) return rep, nil }