implement docker system df

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2022-09-01 10:30:34 +02:00
parent 5dd50a381a
commit 8d0dc69027
No known key found for this signature in database
GPG key ID: 9858809D6F8F6E7E
3 changed files with 52 additions and 8 deletions

View file

@ -116,7 +116,7 @@ func (s *systemRouter) getDiskUsage(ctx context.Context, w http.ResponseWriter,
var getContainers, getImages, getVolumes, getBuildCache bool
typeStrs, ok := r.Form["type"]
if versions.LessThan(version, "1.42") || !ok {
getContainers, getImages, getVolumes, getBuildCache = true, true, true, true
getContainers, getImages, getVolumes, getBuildCache = true, true, true, s.builder != nil
} else {
for _, typ := range typeStrs {
switch types.DiskUsageObject(typ) {

View file

@ -2,22 +2,26 @@ package containerd
import (
"context"
"errors"
"github.com/containerd/containerd"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/snapshots"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/container"
"github.com/docker/docker/daemon/images"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/image"
"github.com/docker/docker/layer"
"github.com/pkg/errors"
"golang.org/x/sync/singleflight"
)
// ImageService implements daemon.ImageService
type ImageService struct {
client *containerd.Client
snapshotter string
usage singleflight.Group
}
// NewService creates a new ImageService.
@ -101,12 +105,53 @@ func (i *ImageService) ReleaseLayer(rwlayer layer.RWLayer) error {
// LayerDiskUsage returns the number of bytes used by layer stores
// called from disk_usage.go
func (i *ImageService) LayerDiskUsage(ctx context.Context) (int64, error) {
return 0, errdefs.NotImplemented(errors.New("not implemented"))
ch := i.usage.DoChan("LayerDiskUsage", func() (interface{}, error) {
var allLayersSize int64
snapshotter := i.client.SnapshotService(i.snapshotter)
snapshotter.Walk(ctx, func(ctx context.Context, info snapshots.Info) error {
usage, err := snapshotter.Usage(ctx, info.Name)
if err != nil {
return err
}
allLayersSize += usage.Size
return nil
})
return allLayersSize, nil
})
select {
case <-ctx.Done():
return 0, ctx.Err()
case res := <-ch:
if res.Err != nil {
return 0, res.Err
}
return res.Val.(int64), nil
}
}
// ImageDiskUsage returns information about image data disk usage.
func (i *ImageService) ImageDiskUsage(ctx context.Context) ([]*types.ImageSummary, error) {
return nil, errdefs.NotImplemented(errors.New("not implemented"))
ch := i.usage.DoChan("ImageDiskUsage", func() (interface{}, error) {
// Get all top images with extra attributes
imgs, err := i.Images(ctx, types.ImageListOptions{
Filters: filters.NewArgs(),
SharedSize: true,
ContainerCount: true,
})
if err != nil {
return nil, errors.Wrap(err, "failed to retrieve image list")
}
return imgs, nil
})
select {
case <-ctx.Done():
return nil, ctx.Err()
case res := <-ch:
if res.Err != nil {
return nil, res.Err
}
return res.Val.([]*types.ImageSummary), nil
}
}
// UpdateConfig values

View file

@ -2,7 +2,6 @@ package images // import "github.com/docker/docker/daemon/images"
import (
"context"
"fmt"
"os"
"github.com/containerd/containerd/content"
@ -245,15 +244,15 @@ func (i *ImageService) getLayerRefs() map[layer.ChainID]int {
func (i *ImageService) ImageDiskUsage(ctx context.Context) ([]*types.ImageSummary, error) {
ch := i.usage.DoChan("ImageDiskUsage", func() (interface{}, error) {
// Get all top images with extra attributes
images, err := i.Images(ctx, types.ImageListOptions{
imgs, err := i.Images(ctx, types.ImageListOptions{
Filters: filters.NewArgs(),
SharedSize: true,
ContainerCount: true,
})
if err != nil {
return nil, fmt.Errorf("failed to retrieve image list: %v", err)
return nil, errors.Wrap(err, "failed to retrieve image list")
}
return images, nil
return imgs, nil
})
select {
case <-ctx.Done():