blob: b96e626f45288e3e121f09083c09c9667c9f1cc6 [file] [log] [blame]
package daemon // import "github.com/docker/docker/daemon"
import (
"context"
"fmt"
"github.com/docker/docker/api/server/router/system"
"github.com/docker/docker/api/types"
"golang.org/x/sync/errgroup"
)
// ContainerDiskUsage returns information about container data disk usage.
func (daemon *Daemon) ContainerDiskUsage(ctx context.Context) ([]*types.Container, error) {
ch := daemon.usage.DoChan("ContainerDiskUsage", func() (interface{}, error) {
// Retrieve container list
containers, err := daemon.Containers(&types.ContainerListOptions{
Size: true,
All: true,
})
if err != nil {
return nil, fmt.Errorf("failed to retrieve container list: %v", err)
}
return containers, nil
})
select {
case <-ctx.Done():
return nil, ctx.Err()
case res := <-ch:
if res.Err != nil {
return nil, res.Err
}
return res.Val.([]*types.Container), nil
}
}
// SystemDiskUsage returns information about the daemon data disk usage.
// Callers must not mutate contents of the returned fields.
func (daemon *Daemon) SystemDiskUsage(ctx context.Context, opts system.DiskUsageOptions) (*types.DiskUsage, error) {
eg, ctx := errgroup.WithContext(ctx)
var containers []*types.Container
if opts.Containers {
eg.Go(func() error {
var err error
containers, err = daemon.ContainerDiskUsage(ctx)
return err
})
}
var (
images []*types.ImageSummary
layersSize int64
)
if opts.Images {
eg.Go(func() error {
var err error
images, err = daemon.imageService.ImageDiskUsage(ctx)
return err
})
eg.Go(func() error {
var err error
layersSize, err = daemon.imageService.LayerDiskUsage(ctx)
return err
})
}
var volumes []*types.Volume
if opts.Volumes {
eg.Go(func() error {
var err error
volumes, err = daemon.volumes.LocalVolumesSize(ctx)
return err
})
}
if err := eg.Wait(); err != nil {
return nil, err
}
return &types.DiskUsage{
LayersSize: layersSize,
Containers: containers,
Volumes: volumes,
Images: images,
}, nil
}