diff --git a/cache/manager.go b/cache/manager.go index d2e26249..c64519de 100644 --- a/cache/manager.go +++ b/cache/manager.go @@ -2,6 +2,7 @@ package cache import ( "context" + "strings" "sync" "time" @@ -34,7 +35,7 @@ type Accessor interface { } type Controller interface { - DiskUsage(ctx context.Context) ([]*client.UsageInfo, error) + DiskUsage(ctx context.Context, info client.DiskUsageInfo) ([]*client.UsageInfo, error) Prune(ctx context.Context) (map[string]int64, error) GC(ctx context.Context) error } @@ -251,7 +252,7 @@ func (cm *cacheManager) GetMutable(ctx context.Context, id string) (MutableRef, return rec.mref(), nil } -func (cm *cacheManager) DiskUsage(ctx context.Context) ([]*client.UsageInfo, error) { +func (cm *cacheManager) DiskUsage(ctx context.Context, opt client.DiskUsageInfo) ([]*client.UsageInfo, error) { cm.mu.Lock() type cacheUsageInfo struct { @@ -275,6 +276,7 @@ func (cm *cacheManager) DiskUsage(ctx context.Context) ([]*client.UsageInfo, err cr.mu.Unlock() continue } + usageCount, lastUsedAt := getLastUsed(cr.md) c := &cacheUsageInfo{ refs: len(cr.refs), @@ -313,6 +315,10 @@ func (cm *cacheManager) DiskUsage(ctx context.Context) ([]*client.UsageInfo, err var du []*client.UsageInfo for id, cr := range m { + if opt.Filter != "" && !strings.HasPrefix(id, opt.Filter) { + continue + } + c := &client.UsageInfo{ ID: id, Mutable: cr.mutable, diff --git a/cache/manager_test.go b/cache/manager_test.go index 37f04124..fc1b150d 100644 --- a/cache/manager_test.go +++ b/cache/manager_test.go @@ -11,6 +11,7 @@ import ( "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/snapshot/naive" "github.com/moby/buildkit/cache/metadata" + "github.com/moby/buildkit/client" "github.com/moby/buildkit/snapshot" "github.com/pkg/errors" "github.com/stretchr/testify/require" @@ -265,7 +266,7 @@ func getCacheManager(t *testing.T, tmpdir string) Manager { } func checkDiskUsage(t *testing.T, ctx context.Context, cm Manager, inuse, unused int) { - du, err := cm.DiskUsage(ctx) + du, err := cm.DiskUsage(ctx, client.DiskUsageInfo{}) require.NoError(t, err) var inuseActual, unusedActual int for _, r := range du { diff --git a/client/diskusage.go b/client/diskusage.go index abd1d89d..fe97f773 100644 --- a/client/diskusage.go +++ b/client/diskusage.go @@ -22,8 +22,14 @@ type UsageInfo struct { Description string } -func (c *Client) DiskUsage(ctx context.Context) ([]*UsageInfo, error) { - resp, err := c.controlClient().DiskUsage(ctx, &controlapi.DiskUsageRequest{}) +func (c *Client) DiskUsage(ctx context.Context, opts ...DiskUsageOption) ([]*UsageInfo, error) { + info := &DiskUsageInfo{} + for _, o := range opts { + o(info) + } + + req := &controlapi.DiskUsageRequest{Filter: info.Filter} + resp, err := c.controlClient().DiskUsage(ctx, req) if err != nil { return nil, errors.Wrap(err, "failed to get diskusage") } @@ -45,8 +51,23 @@ func (c *Client) DiskUsage(ctx context.Context) ([]*UsageInfo, error) { } sort.Slice(du, func(i, j int) bool { + if du[i].Size == du[j].Size { + return du[i].ID > du[j].ID + } return du[i].Size > du[j].Size }) return du, nil } + +type DiskUsageOption func(*DiskUsageInfo) + +type DiskUsageInfo struct { + Filter string +} + +func WithFilter(f string) DiskUsageOption { + return func(di *DiskUsageInfo) { + di.Filter = f + } +} diff --git a/cmd/buildctl/diskusage.go b/cmd/buildctl/diskusage.go index 2653f7a6..be5e79a1 100644 --- a/cmd/buildctl/diskusage.go +++ b/cmd/buildctl/diskusage.go @@ -1,7 +1,6 @@ package main import ( - "context" "fmt" "io" "os" @@ -9,6 +8,7 @@ import ( units "github.com/docker/go-units" "github.com/moby/buildkit/client" + "github.com/moby/buildkit/util/appcontext" "github.com/urfave/cli" ) @@ -17,6 +17,10 @@ var diskUsageCommand = cli.Command{ Usage: "disk usage", Action: diskUsage, Flags: []cli.Flag{ + cli.StringFlag{ + Name: "filter, f", + Usage: "Filter snapshot ID", + }, cli.BoolFlag{ Name: "verbose, v", Usage: "Verbose output", @@ -25,12 +29,12 @@ var diskUsageCommand = cli.Command{ } func diskUsage(clicontext *cli.Context) error { - client, err := resolveClient(clicontext) + c, err := resolveClient(clicontext) if err != nil { return err } - du, err := client.DiskUsage(context.TODO()) + du, err := c.DiskUsage(appcontext.Context(), client.WithFilter(clicontext.String("filter"))) if err != nil { return err } @@ -43,7 +47,9 @@ func diskUsage(clicontext *cli.Context) error { printTable(tw, du) } - printSummary(tw, du) + if clicontext.String("filter") == "" { + printSummary(tw, du) + } return nil } diff --git a/control/control.go b/control/control.go index a74433e2..dbf87969 100644 --- a/control/control.go +++ b/control/control.go @@ -51,8 +51,10 @@ func (c *Controller) Register(server *grpc.Server) error { return nil } -func (c *Controller) DiskUsage(ctx context.Context, _ *controlapi.DiskUsageRequest) (*controlapi.DiskUsageResponse, error) { - du, err := c.opt.CacheManager.DiskUsage(ctx) +func (c *Controller) DiskUsage(ctx context.Context, r *controlapi.DiskUsageRequest) (*controlapi.DiskUsageResponse, error) { + du, err := c.opt.CacheManager.DiskUsage(ctx, client.DiskUsageInfo{ + Filter: r.Filter, + }) if err != nil { return nil, err } diff --git a/control/control_standalone_test.go b/control/control_standalone_test.go index 80831868..7188828b 100644 --- a/control/control_standalone_test.go +++ b/control/control_standalone_test.go @@ -13,6 +13,7 @@ import ( "github.com/containerd/containerd/namespaces" "github.com/moby/buildkit/cache" "github.com/moby/buildkit/cache/metadata" + "github.com/moby/buildkit/client" "github.com/moby/buildkit/snapshot" "github.com/moby/buildkit/snapshot/blobmapping" "github.com/moby/buildkit/source" @@ -93,7 +94,7 @@ func TestControl(t *testing.T) { lm.Unmount() assert.NoError(t, err) - du, err := cm.DiskUsage(ctx) + du, err := cm.DiskUsage(ctx, client.DiskUsageInfo{}) assert.NoError(t, err) // for _, d := range du { @@ -148,7 +149,7 @@ func TestControl(t *testing.T) { err = snap.Release(ctx) assert.NoError(t, err) - du2, err := cm.DiskUsage(ctx) + du2, err := cm.DiskUsage(ctx, client.DiskUsageInfo{}) assert.NoError(t, err) assert.Equal(t, 1, len(du2)-len(du))