Skip to content

Commit f07242f

Browse files
committed
containerd: include present content size in disk usage calculations
The present content size is included in the image size usage and should be included in the total size that the layer takes up on disk. This prevents an issue where the reclaimable amount reported by the CLI was a negative number. This also updates the `/system/df` endpoint to use a new type that computes information that was previously computed by the CLI. Computing these in the server should require less work from the CLI and ensure the calculations are more accurate because the CLI doesn't have to reconstruct the numbers. Signed-off-by: Jonathan A. Sternberg <[email protected]>
1 parent 2e25c2b commit f07242f

16 files changed

Lines changed: 227 additions & 99 deletions

File tree

api/server/router/system/backend.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"time"
66

77
"github.com/docker/docker/api/types"
8+
"github.com/docker/docker/api/types/build"
89
"github.com/docker/docker/api/types/events"
910
"github.com/docker/docker/api/types/filters"
1011
"github.com/docker/docker/api/types/registry"
@@ -29,7 +30,7 @@ type DiskUsageOptions struct {
2930
type Backend interface {
3031
SystemInfo(context.Context) (*system.Info, error)
3132
SystemVersion(context.Context) (types.Version, error)
32-
SystemDiskUsage(ctx context.Context, opts DiskUsageOptions) (*types.DiskUsage, error)
33+
SystemDiskUsage(ctx context.Context, opts DiskUsageOptions) (*system.DiskUsage, error)
3334
SubscribeToEvents(since, until time.Time, ef filters.Args) ([]events.Message, chan interface{})
3435
UnsubscribeFromEvents(chan interface{})
3536
AuthenticateToRegistry(ctx context.Context, authConfig *registry.AuthConfig) (string, string, error)
@@ -43,7 +44,7 @@ type ClusterBackend interface {
4344

4445
// BuildBackend provides build specific system information.
4546
type BuildBackend interface {
46-
DiskUsage(context.Context) ([]*types.BuildCache, error)
47+
DiskUsage(context.Context) ([]*build.CacheRecord, error)
4748
}
4849

4950
// StatusProvider provides methods to get the swarm status of the current node.

api/server/router/system/system_routes.go

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/docker/docker/api/server/httputils"
1515
"github.com/docker/docker/api/server/router/build"
1616
"github.com/docker/docker/api/types"
17+
buildtypes "github.com/docker/docker/api/types/build"
1718
"github.com/docker/docker/api/types/events"
1819
"github.com/docker/docker/api/types/filters"
1920
"github.com/docker/docker/api/types/registry"
@@ -170,7 +171,7 @@ func (s *systemRouter) getDiskUsage(ctx context.Context, w http.ResponseWriter,
170171

171172
eg, ctx := errgroup.WithContext(ctx)
172173

173-
var systemDiskUsage *types.DiskUsage
174+
var systemDiskUsage *system.DiskUsage
174175
if getContainers || getImages || getVolumes {
175176
eg.Go(func() error {
176177
var err error
@@ -183,7 +184,7 @@ func (s *systemRouter) getDiskUsage(ctx context.Context, w http.ResponseWriter,
183184
})
184185
}
185186

186-
var buildCache []*types.BuildCache
187+
var buildCache []*buildtypes.CacheRecord
187188
if getBuildCache {
188189
eg.Go(func() error {
189190
var err error
@@ -194,7 +195,7 @@ func (s *systemRouter) getDiskUsage(ctx context.Context, w http.ResponseWriter,
194195
if buildCache == nil {
195196
// Ensure empty `BuildCache` field is represented as empty JSON array(`[]`)
196197
// instead of `null` to be consistent with `Images`, `Containers` etc.
197-
buildCache = []*types.BuildCache{}
198+
buildCache = []*buildtypes.CacheRecord{}
198199
}
199200
return nil
200201
})
@@ -219,23 +220,42 @@ func (s *systemRouter) getDiskUsage(ctx context.Context, w http.ResponseWriter,
219220
b.Parent = "" //nolint:staticcheck // ignore SA1019 (Parent field is deprecated)
220221
}
221222
}
222-
if versions.LessThan(version, "1.44") {
223-
for _, b := range systemDiskUsage.Images {
223+
if versions.LessThan(version, "1.44") && systemDiskUsage != nil && systemDiskUsage.Images != nil {
224+
for _, b := range systemDiskUsage.Images.Items {
224225
b.VirtualSize = b.Size //nolint:staticcheck // ignore SA1019: field is deprecated, but still set on API < v1.44.
225226
}
226227
}
227228

228-
du := types.DiskUsage{
229-
BuildCache: buildCache,
230-
BuilderSize: builderSize,
229+
du := system.DiskUsage{}
230+
if getBuildCache {
231+
du.BuildCache = &buildtypes.CacheDiskUsage{
232+
TotalSize: builderSize,
233+
Items: buildCache,
234+
}
231235
}
232236
if systemDiskUsage != nil {
233-
du.LayersSize = systemDiskUsage.LayersSize
234237
du.Images = systemDiskUsage.Images
235238
du.Containers = systemDiskUsage.Containers
236239
du.Volumes = systemDiskUsage.Volumes
237240
}
238-
return httputils.WriteJSON(w, http.StatusOK, du)
241+
242+
// Use the old struct for the API return value.
243+
var v types.DiskUsage
244+
if du.Images != nil {
245+
v.LayersSize = du.Images.TotalSize
246+
v.Images = du.Images.Items
247+
}
248+
if du.Containers != nil {
249+
v.Containers = du.Containers.Items
250+
}
251+
if du.Volumes != nil {
252+
v.Volumes = du.Volumes.Items
253+
}
254+
if du.BuildCache != nil {
255+
v.BuildCache = du.BuildCache.Items
256+
}
257+
v.BuilderSize = builderSize
258+
return httputils.WriteJSON(w, http.StatusOK, v)
239259
}
240260

241261
type invalidRequestError struct {

api/types/build/cache.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package build
2+
3+
import "time"
4+
5+
// CacheRecord contains information about a build cache record.
6+
type CacheRecord struct {
7+
// ID is the unique ID of the build cache record.
8+
ID string
9+
// Parent is the ID of the parent build cache record.
10+
//
11+
// Deprecated: deprecated in API v1.42 and up, as it was deprecated in BuildKit; use Parents instead.
12+
Parent string `json:"Parent,omitempty"`
13+
// Parents is the list of parent build cache record IDs.
14+
Parents []string `json:" Parents,omitempty"`
15+
// Type is the cache record type.
16+
Type string
17+
// Description is a description of the build-step that produced the build cache.
18+
Description string
19+
// InUse indicates if the build cache is in use.
20+
InUse bool
21+
// Shared indicates if the build cache is shared.
22+
Shared bool
23+
// Size is the amount of disk space used by the build cache (in bytes).
24+
Size int64
25+
// CreatedAt is the date and time at which the build cache was created.
26+
CreatedAt time.Time
27+
// LastUsedAt is the date and time at which the build cache was last used.
28+
LastUsedAt *time.Time
29+
UsageCount int
30+
}

api/types/build/disk_usage.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package build
2+
3+
// CacheDiskUsage contains disk usage for the build cache.
4+
type CacheDiskUsage struct {
5+
TotalSize int64
6+
Reclaimable int64
7+
Items []*CacheRecord
8+
}

api/types/container/disk_usage.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package container
2+
3+
// DiskUsage contains disk usage for containers.
4+
type DiskUsage struct {
5+
TotalSize int64
6+
Reclaimable int64
7+
Items []*Summary
8+
}

api/types/image/disk_usage.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package image
2+
3+
// DiskUsage contains disk usage for images.
4+
type DiskUsage struct {
5+
TotalSize int64
6+
Reclaimable int64
7+
Items []*Summary
8+
}

api/types/system/disk_usage.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package system
2+
3+
import (
4+
"github.com/docker/docker/api/types/build"
5+
"github.com/docker/docker/api/types/container"
6+
"github.com/docker/docker/api/types/image"
7+
"github.com/docker/docker/api/types/volume"
8+
)
9+
10+
// DiskUsage contains response of Engine API for API 1.49 and greater:
11+
// GET "/system/df"
12+
type DiskUsage struct {
13+
Images *image.DiskUsage
14+
Containers *container.DiskUsage
15+
Volumes *volume.DiskUsage
16+
BuildCache *build.CacheDiskUsage
17+
}

api/types/types.go

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
package types // import "github.com/docker/docker/api/types"
22

33
import (
4-
"time"
5-
4+
"github.com/docker/docker/api/types/build"
65
"github.com/docker/docker/api/types/container"
76
"github.com/docker/docker/api/types/filters"
87
"github.com/docker/docker/api/types/image"
@@ -141,31 +140,9 @@ type BuildResult struct {
141140
}
142141

143142
// BuildCache contains information about a build cache record.
144-
type BuildCache struct {
145-
// ID is the unique ID of the build cache record.
146-
ID string
147-
// Parent is the ID of the parent build cache record.
148-
//
149-
// Deprecated: deprecated in API v1.42 and up, as it was deprecated in BuildKit; use Parents instead.
150-
Parent string `json:"Parent,omitempty"`
151-
// Parents is the list of parent build cache record IDs.
152-
Parents []string `json:" Parents,omitempty"`
153-
// Type is the cache record type.
154-
Type string
155-
// Description is a description of the build-step that produced the build cache.
156-
Description string
157-
// InUse indicates if the build cache is in use.
158-
InUse bool
159-
// Shared indicates if the build cache is shared.
160-
Shared bool
161-
// Size is the amount of disk space used by the build cache (in bytes).
162-
Size int64
163-
// CreatedAt is the date and time at which the build cache was created.
164-
CreatedAt time.Time
165-
// LastUsedAt is the date and time at which the build cache was last used.
166-
LastUsedAt *time.Time
167-
UsageCount int
168-
}
143+
//
144+
// Deprecated: deprecated in API 1.49. Use [build.CacheRecord] instead.
145+
type BuildCache = build.CacheRecord
169146

170147
// BuildCachePruneOptions hold parameters to prune the build cache
171148
type BuildCachePruneOptions struct {

api/types/volume/disk_usage.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package volume
2+
3+
// DiskUsage contains disk usage for volumes.
4+
type DiskUsage struct {
5+
TotalSize int64
6+
Reclaimable int64
7+
Items []*Volume
8+
}

builder/builder-next/builder.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/containerd/platforms"
1515
"github.com/docker/docker/api/types"
1616
"github.com/docker/docker/api/types/backend"
17+
"github.com/docker/docker/api/types/build"
1718
"github.com/docker/docker/api/types/container"
1819
"github.com/docker/docker/api/types/network"
1920
timetypes "github.com/docker/docker/api/types/time"
@@ -149,15 +150,15 @@ func (b *Builder) Cancel(ctx context.Context, id string) error {
149150
}
150151

151152
// DiskUsage returns a report about space used by build cache
152-
func (b *Builder) DiskUsage(ctx context.Context) ([]*types.BuildCache, error) {
153+
func (b *Builder) DiskUsage(ctx context.Context) ([]*build.CacheRecord, error) {
153154
duResp, err := b.controller.DiskUsage(ctx, &controlapi.DiskUsageRequest{})
154155
if err != nil {
155156
return nil, err
156157
}
157158

158-
var items []*types.BuildCache
159+
var items []*build.CacheRecord
159160
for _, r := range duResp.Record {
160-
items = append(items, &types.BuildCache{
161+
items = append(items, &build.CacheRecord{
161162
ID: r.ID,
162163
Parent: r.Parent, //nolint:staticcheck // ignore SA1019 (Parent field is deprecated)
163164
Parents: r.Parents,

0 commit comments

Comments
 (0)