API: add "prune" events
This patch adds a new "prune" event type to indicate that pruning of a resource type completed. This event-type can be used on systems that want to perform actions after resources have been cleaned up. For example, Docker Desktop performs an fstrim after resources are deleted (https://github.com/linuxkit/linuxkit/tree/v0.7/pkg/trim-after-delete). While the current (remove, destroy) events can provide information on _most_ resources, there is currently no event triggered after the BuildKit build-cache is cleaned. Prune events have a `reclaimed` attribute, indicating the amount of space that was reclaimed (in bytes). The attribute can be used, for example, to use as a threshold for performing fstrim actions. Reclaimed space for `network` events will always be 0, but the field is added to be consistent with prune events for other resources. To test this patch: Create some resources: for i in foo bar baz; do \ docker network create network_$i \ && docker volume create volume_$i \ && docker run -d --name container_$i -v volume_$i:/volume busybox sh -c 'truncate -s 5M somefile; truncate -s 5M /volume/file' \ && docker tag busybox:latest image_$i; \ done; docker pull alpine docker pull nginx:alpine echo -e "FROM busybox\nRUN truncate -s 50M bigfile" | DOCKER_BUILDKIT=1 docker build - Start listening for "prune" events in another shell: docker events --filter event=prune Prune containers, networks, volumes, and build-cache: docker system prune -af --volumes See the events that are returned: docker events --filter event=prune 2020-07-25T12:12:09.268491000Z container prune (reclaimed=15728640) 2020-07-25T12:12:09.447890400Z network prune (reclaimed=0) 2020-07-25T12:12:09.452323000Z volume prune (reclaimed=15728640) 2020-07-25T12:12:09.517236200Z image prune (reclaimed=21568540) 2020-07-25T12:12:09.566662600Z builder prune (reclaimed=52428841) Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
624154fe63
commit
51c7992928
8 changed files with 43 additions and 10 deletions
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue