diff --git a/daemon/containerd/image_list.go b/daemon/containerd/image_list.go index a317673752..1320b3bc96 100644 --- a/daemon/containerd/image_list.go +++ b/daemon/containerd/image_list.go @@ -3,7 +3,10 @@ package containerd import ( "context" + "github.com/containerd/containerd" + "github.com/containerd/containerd/snapshots" "github.com/docker/docker/api/types" + "github.com/opencontainers/image-spec/identity" ) // Images returns a filtered list of images. @@ -13,6 +16,8 @@ func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions) return nil, err } + snapshotter := i.client.SnapshotService(containerd.DefaultSnapshotter) + var ret []*types.ImageSummary for _, img := range imgs { size, err := img.Size(ctx) @@ -20,13 +25,18 @@ func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions) return nil, err } + virtualSize, err := computeVirtualSize(ctx, img, snapshotter) + if err != nil { + return nil, err + } + ret = append(ret, &types.ImageSummary{ RepoDigests: []string{img.Name() + "@" + img.Target().Digest.String()}, // "hello-world@sha256:bfea6278a0a267fad2634554f4f0c6f31981eea41c553fdf5a83e95a41d40c38"}, RepoTags: []string{img.Name()}, Containers: -1, ParentID: "", SharedSize: -1, - VirtualSize: 10, + VirtualSize: virtualSize, ID: img.Target().Digest.String(), Created: img.Metadata().CreatedAt.Unix(), Size: size, @@ -35,3 +45,19 @@ func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions) return ret, nil } + +func computeVirtualSize(ctx context.Context, image containerd.Image, snapshotter snapshots.Snapshotter) (int64, error) { + var virtualSize int64 + diffIDs, err := image.RootFS(ctx) + if err != nil { + return virtualSize, err + } + for _, chainID := range identity.ChainIDs(diffIDs) { + usage, err := snapshotter.Usage(ctx, chainID.String()) + if err != nil { + return virtualSize, err + } + virtualSize += usage.Size + } + return virtualSize, nil +}