فهرست منبع

implement docker system df

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
Nicolas De Loof 2 سال پیش
والد
کامیت
8d0dc69027
3فایلهای تغییر یافته به همراه52 افزوده شده و 8 حذف شده
  1. 1 1
      api/server/router/system/system_routes.go
  2. 48 3
      daemon/containerd/service.go
  3. 3 4
      daemon/images/service.go

+ 1 - 1
api/server/router/system/system_routes.go

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

+ 48 - 3
daemon/containerd/service.go

@@ -2,22 +2,26 @@ package containerd
 
 
 import (
 import (
 	"context"
 	"context"
-	"errors"
 
 
 	"github.com/containerd/containerd"
 	"github.com/containerd/containerd"
 	"github.com/containerd/containerd/plugin"
 	"github.com/containerd/containerd/plugin"
+	"github.com/containerd/containerd/snapshots"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/daemon/images"
 	"github.com/docker/docker/daemon/images"
 	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/layer"
 	"github.com/docker/docker/layer"
+	"github.com/pkg/errors"
+	"golang.org/x/sync/singleflight"
 )
 )
 
 
 // ImageService implements daemon.ImageService
 // ImageService implements daemon.ImageService
 type ImageService struct {
 type ImageService struct {
 	client      *containerd.Client
 	client      *containerd.Client
 	snapshotter string
 	snapshotter string
+	usage       singleflight.Group
 }
 }
 
 
 // NewService creates a new ImageService.
 // 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
 // LayerDiskUsage returns the number of bytes used by layer stores
 // called from disk_usage.go
 // called from disk_usage.go
 func (i *ImageService) LayerDiskUsage(ctx context.Context) (int64, error) {
 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.
 // ImageDiskUsage returns information about image data disk usage.
 func (i *ImageService) ImageDiskUsage(ctx context.Context) ([]*types.ImageSummary, error) {
 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
 // UpdateConfig values

+ 3 - 4
daemon/images/service.go

@@ -2,7 +2,6 @@ package images // import "github.com/docker/docker/daemon/images"
 
 
 import (
 import (
 	"context"
 	"context"
-	"fmt"
 	"os"
 	"os"
 
 
 	"github.com/containerd/containerd/content"
 	"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) {
 func (i *ImageService) ImageDiskUsage(ctx context.Context) ([]*types.ImageSummary, error) {
 	ch := i.usage.DoChan("ImageDiskUsage", func() (interface{}, error) {
 	ch := i.usage.DoChan("ImageDiskUsage", func() (interface{}, error) {
 		// Get all top images with extra attributes
 		// Get all top images with extra attributes
-		images, err := i.Images(ctx, types.ImageListOptions{
+		imgs, err := i.Images(ctx, types.ImageListOptions{
 			Filters:        filters.NewArgs(),
 			Filters:        filters.NewArgs(),
 			SharedSize:     true,
 			SharedSize:     true,
 			ContainerCount: true,
 			ContainerCount: true,
 		})
 		})
 		if err != nil {
 		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 {
 	select {
 	case <-ctx.Done():
 	case <-ctx.Done():