From 002992418115f9efaa858a8bf5fc72d4b2f51248 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Thu, 6 Nov 2025 10:34:56 +0100 Subject: [PATCH] api/types/system: change legacyDiskUsage to a non-pointer slice Signed-off-by: Sebastiaan van Stijn --- api/types/system/disk_usage.go | 8 +-- client/system_disk_usage.go | 32 ++-------- client/system_disk_usage_test.go | 2 +- daemon/disk_usage.go | 7 ++- daemon/internal/builder-next/builder.go | 6 +- daemon/server/backend/disk_usage.go | 8 +-- daemon/server/router/system/backend.go | 2 +- daemon/server/router/system/system_routes.go | 59 ++++++------------- .../moby/moby/api/types/system/disk_usage.go | 8 +-- .../moby/moby/client/system_disk_usage.go | 32 ++-------- 10 files changed, 48 insertions(+), 116 deletions(-) diff --git a/api/types/system/disk_usage.go b/api/types/system/disk_usage.go index 2c9b1fee7d..53d7a499d8 100644 --- a/api/types/system/disk_usage.go +++ b/api/types/system/disk_usage.go @@ -37,14 +37,14 @@ type LegacyDiskUsage struct { LayersSize int64 `json:"LayersSize,omitempty"` // Deprecated: kept to maintain backwards compatibility with API < v1.52, use [ImagesDiskUsage.Items] instead. - Images []*image.Summary `json:"Images,omitempty"` + Images []image.Summary `json:"Images,omitzero"` // Deprecated: kept to maintain backwards compatibility with API < v1.52, use [ContainersDiskUsage.Items] instead. - Containers []*container.Summary `json:"Containers,omitempty"` + Containers []container.Summary `json:"Containers,omitzero"` // Deprecated: kept to maintain backwards compatibility with API < v1.52, use [VolumesDiskUsage.Items] instead. - Volumes []*volume.Volume `json:"Volumes,omitempty"` + Volumes []volume.Volume `json:"Volumes,omitzero"` // Deprecated: kept to maintain backwards compatibility with API < v1.52, use [BuildCacheDiskUsage.Items] instead. - BuildCache []*build.CacheRecord `json:"BuildCache,omitempty"` + BuildCache []build.CacheRecord `json:"BuildCache,omitzero"` } diff --git a/client/system_disk_usage.go b/client/system_disk_usage.go index a179d86f62..563c60d5b3 100644 --- a/client/system_disk_usage.go +++ b/client/system_disk_usage.go @@ -171,13 +171,7 @@ func (cli *Client) DiskUsage(ctx context.Context, options DiskUsageOptions) (Dis } if options.Verbose { - r.Images.Items = slices.Collect(func(yield func(image.Summary) bool) { - for _, i := range du.Images { - if !yield(*i) { - return - } - } - }) + r.Images.Items = du.Images } } @@ -194,13 +188,7 @@ func (cli *Client) DiskUsage(ctx context.Context, options DiskUsageOptions) (Dis } } else if du.Containers != nil && options.Verbose { // Fallback for legacy response. - r.Containers.Items = slices.Collect(func(yield func(container.Summary) bool) { - for _, c := range du.Containers { - if !yield(*c) { - return - } - } - }) + r.Containers.Items = du.Containers } if du.BuildCacheUsage != nil { @@ -216,13 +204,7 @@ func (cli *Client) DiskUsage(ctx context.Context, options DiskUsageOptions) (Dis } } else if du.BuildCache != nil && options.Verbose { // Fallback for legacy response. - r.BuildCache.Items = slices.Collect(func(yield func(build.CacheRecord) bool) { - for _, b := range du.BuildCache { - if !yield(*b) { - return - } - } - }) + r.BuildCache.Items = du.BuildCache } if du.VolumeUsage != nil { @@ -238,13 +220,7 @@ func (cli *Client) DiskUsage(ctx context.Context, options DiskUsageOptions) (Dis } } else if du.Volumes != nil && options.Verbose { // Fallback for legacy response. - r.Volumes.Items = slices.Collect(func(yield func(volume.Volume) bool) { - for _, v := range du.Volumes { - if !yield(*v) { - return - } - } - }) + r.Volumes.Items = du.Volumes } return r, nil diff --git a/client/system_disk_usage_test.go b/client/system_disk_usage_test.go index e9917753be..5e483ca686 100644 --- a/client/system_disk_usage_test.go +++ b/client/system_disk_usage_test.go @@ -140,7 +140,7 @@ func TestLegacyDiskUsage(t *testing.T) { return mockJSONResponse(http.StatusOK, nil, system.DiskUsage{ LegacyDiskUsage: system.LegacyDiskUsage{ LayersSize: 4096, - Images: []*image.Summary{}, + Images: []image.Summary{}, }, })(req) })) diff --git a/daemon/disk_usage.go b/daemon/disk_usage.go index 7e09f73531..c1d27d1882 100644 --- a/daemon/disk_usage.go +++ b/daemon/disk_usage.go @@ -8,6 +8,7 @@ import ( "github.com/moby/moby/v2/daemon/internal/filters" "github.com/moby/moby/v2/daemon/server/backend" "github.com/moby/moby/v2/daemon/server/imagebackend" + "github.com/moby/moby/v2/internal/sliceutil" "github.com/pkg/errors" "golang.org/x/sync/errgroup" ) @@ -51,7 +52,7 @@ func (daemon *Daemon) containerDiskUsage(ctx context.Context, verbose bool) (*ba du.ActiveCount = activeCount if verbose { - du.Items = containers + du.Items = sliceutil.Deref(containers) } return du, nil @@ -96,7 +97,7 @@ func (daemon *Daemon) imageDiskUsage(ctx context.Context, verbose bool) (*backen du.ActiveCount = activeCount if verbose { - du.Items = images + du.Items = sliceutil.Deref(images) } return du, nil @@ -130,7 +131,7 @@ func (daemon *Daemon) localVolumesSize(ctx context.Context, verbose bool) (*back du.ActiveCount = activeCount if verbose { - du.Items = volumes + du.Items = sliceutil.Deref(volumes) } return du, nil diff --git a/daemon/internal/builder-next/builder.go b/daemon/internal/builder-next/builder.go index b85aad4e3e..550753faee 100644 --- a/daemon/internal/builder-next/builder.go +++ b/daemon/internal/builder-next/builder.go @@ -150,15 +150,15 @@ func (b *Builder) Cancel(ctx context.Context, id string) error { } // DiskUsage returns a report about space used by build cache -func (b *Builder) DiskUsage(ctx context.Context) ([]*build.CacheRecord, error) { +func (b *Builder) DiskUsage(ctx context.Context) ([]build.CacheRecord, error) { duResp, err := b.controller.DiskUsage(ctx, &controlapi.DiskUsageRequest{}) if err != nil { return nil, err } - var items []*build.CacheRecord + var items []build.CacheRecord for _, r := range duResp.Record { - items = append(items, &build.CacheRecord{ + items = append(items, build.CacheRecord{ ID: r.ID, Parents: r.Parents, Type: r.RecordType, diff --git a/daemon/server/backend/disk_usage.go b/daemon/server/backend/disk_usage.go index 1798e2c6aa..448e0a49b0 100644 --- a/daemon/server/backend/disk_usage.go +++ b/daemon/server/backend/disk_usage.go @@ -37,7 +37,7 @@ type BuildCacheDiskUsage struct { TotalCount int64 TotalSize int64 Reclaimable int64 - Items []*build.CacheRecord + Items []build.CacheRecord } // ContainerDiskUsage contains disk usage for containers. @@ -46,7 +46,7 @@ type ContainerDiskUsage struct { TotalCount int64 TotalSize int64 Reclaimable int64 - Items []*container.Summary + Items []container.Summary } // ImageDiskUsage contains disk usage for images. @@ -55,7 +55,7 @@ type ImageDiskUsage struct { TotalCount int64 TotalSize int64 Reclaimable int64 - Items []*image.Summary + Items []image.Summary } // VolumeDiskUsage contains disk usage for volumes. @@ -64,5 +64,5 @@ type VolumeDiskUsage struct { TotalCount int64 TotalSize int64 Reclaimable int64 - Items []*volume.Volume + Items []volume.Volume } diff --git a/daemon/server/router/system/backend.go b/daemon/server/router/system/backend.go index 381ca1b63c..3d1c12f1f9 100644 --- a/daemon/server/router/system/backend.go +++ b/daemon/server/router/system/backend.go @@ -32,7 +32,7 @@ type ClusterBackend interface { // BuildBackend provides build specific system information. type BuildBackend interface { - DiskUsage(context.Context) ([]*build.CacheRecord, error) + DiskUsage(context.Context) ([]build.CacheRecord, error) } // StatusProvider provides methods to get the swarm status of the current node. diff --git a/daemon/server/router/system/system_routes.go b/daemon/server/router/system/system_routes.go index 9a8e10a032..4a5317c217 100644 --- a/daemon/server/router/system/system_routes.go +++ b/daemon/server/router/system/system_routes.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "net/http" - "slices" "strconv" "time" @@ -197,7 +196,7 @@ func (s *systemRouter) getDiskUsage(ctx context.Context, w http.ResponseWriter, }) } - var buildCache []*buildtypes.CacheRecord + var buildCache []buildtypes.CacheRecord if getBuildCache { eg.Go(func() error { var err error @@ -205,11 +204,6 @@ func (s *systemRouter) getDiskUsage(ctx context.Context, w http.ResponseWriter, if err != nil { return errors.Wrap(err, "error getting build cache usage") } - if buildCache == nil { - // Ensure empty `BuildCache` field is represented as empty JSON array(`[]`) - // instead of `null` to be consistent with `Images`, `Containers` etc. - buildCache = []*buildtypes.CacheRecord{} - } return nil }) } @@ -228,16 +222,10 @@ func (s *systemRouter) getDiskUsage(ctx context.Context, w http.ResponseWriter, } if legacyFields { - v.LayersSize = systemDiskUsage.Images.TotalSize //nolint: staticcheck,SA1019: v.LayersSize is deprecated: kept to maintain backwards compatibility with API < v1.52, use [ImagesDiskUsage.TotalSize] instead. - v.Images = systemDiskUsage.Images.Items //nolint: staticcheck,SA1019: v.Images is deprecated: kept to maintain backwards compatibility with API < v1.52, use [ImagesDiskUsage.Items] instead. + v.LayersSize = systemDiskUsage.Images.TotalSize //nolint: staticcheck,SA1019: v.LayersSize is deprecated: kept to maintain backwards compatibility with API < v1.52, use [ImagesDiskUsage.TotalSize] instead. + v.Images = nonNilSlice(systemDiskUsage.Images.Items) //nolint: staticcheck,SA1019: v.Images is deprecated: kept to maintain backwards compatibility with API < v1.52, use [ImagesDiskUsage.Items] instead. } else if verbose { - v.ImageUsage.Items = slices.Collect(func(yield func(image.Summary) bool) { - for _, i := range systemDiskUsage.Images.Items { - if !yield(*i) { - return - } - } - }) + v.ImageUsage.Items = systemDiskUsage.Images.Items } } if systemDiskUsage != nil && systemDiskUsage.Containers != nil { @@ -249,15 +237,9 @@ func (s *systemRouter) getDiskUsage(ctx context.Context, w http.ResponseWriter, } if legacyFields { - v.Containers = systemDiskUsage.Containers.Items //nolint: staticcheck,SA1019: v.Containers is deprecated: kept to maintain backwards compatibility with API < v1.52, use [ContainersDiskUsage.Items] instead. + v.Containers = nonNilSlice(systemDiskUsage.Containers.Items) //nolint: staticcheck,SA1019: v.Containers is deprecated: kept to maintain backwards compatibility with API < v1.52, use [ContainersDiskUsage.Items] instead. } else if verbose { - v.ContainerUsage.Items = slices.Collect(func(yield func(container.Summary) bool) { - for _, c := range systemDiskUsage.Containers.Items { - if !yield(*c) { - return - } - } - }) + v.ContainerUsage.Items = systemDiskUsage.Containers.Items } } if systemDiskUsage != nil && systemDiskUsage.Volumes != nil { @@ -269,15 +251,9 @@ func (s *systemRouter) getDiskUsage(ctx context.Context, w http.ResponseWriter, } if legacyFields { - v.Volumes = systemDiskUsage.Volumes.Items //nolint: staticcheck,SA1019: v.Volumes is deprecated: kept to maintain backwards compatibility with API < v1.52, use [VolumesDiskUsage.Items] instead. + v.Volumes = nonNilSlice(systemDiskUsage.Volumes.Items) //nolint: staticcheck,SA1019: v.Volumes is deprecated: kept to maintain backwards compatibility with API < v1.52, use [VolumesDiskUsage.Items] instead. } else if verbose { - v.VolumeUsage.Items = slices.Collect(func(yield func(volume.Volume) bool) { - for _, v := range systemDiskUsage.Volumes.Items { - if !yield(*v) { - return - } - } - }) + v.VolumeUsage.Items = systemDiskUsage.Volumes.Items } } if getBuildCache { @@ -306,20 +282,23 @@ func (s *systemRouter) getDiskUsage(ctx context.Context, w http.ResponseWriter, v.BuildCacheUsage.Reclaimable = reclaimable if legacyFields { - v.BuildCache = buildCache //nolint: staticcheck,SA1019: v.BuildCache is deprecated: kept to maintain backwards compatibility with API < v1.52, use [BuildCacheDiskUsage.Items] instead. + v.BuildCache = nonNilSlice(buildCache) //nolint: staticcheck,SA1019: v.BuildCache is deprecated: kept to maintain backwards compatibility with API < v1.52, use [BuildCacheDiskUsage.Items] instead. } else if verbose { - v.BuildCacheUsage.Items = slices.Collect(func(yield func(buildtypes.CacheRecord) bool) { - for _, b := range buildCache { - if !yield(*b) { - return - } - } - }) + v.BuildCacheUsage.Items = buildCache } } return httputils.WriteJSON(w, http.StatusOK, v) } +// nonNilSlice is used for the legacy fields, which are either omitted +// entirely, or (if set), must return an empty slice in the response. +func nonNilSlice[T any](s []T) []T { + if s == nil { + return []T{} + } + return s +} + type invalidRequestError struct { Err error } diff --git a/vendor/github.com/moby/moby/api/types/system/disk_usage.go b/vendor/github.com/moby/moby/api/types/system/disk_usage.go index 2c9b1fee7d..53d7a499d8 100644 --- a/vendor/github.com/moby/moby/api/types/system/disk_usage.go +++ b/vendor/github.com/moby/moby/api/types/system/disk_usage.go @@ -37,14 +37,14 @@ type LegacyDiskUsage struct { LayersSize int64 `json:"LayersSize,omitempty"` // Deprecated: kept to maintain backwards compatibility with API < v1.52, use [ImagesDiskUsage.Items] instead. - Images []*image.Summary `json:"Images,omitempty"` + Images []image.Summary `json:"Images,omitzero"` // Deprecated: kept to maintain backwards compatibility with API < v1.52, use [ContainersDiskUsage.Items] instead. - Containers []*container.Summary `json:"Containers,omitempty"` + Containers []container.Summary `json:"Containers,omitzero"` // Deprecated: kept to maintain backwards compatibility with API < v1.52, use [VolumesDiskUsage.Items] instead. - Volumes []*volume.Volume `json:"Volumes,omitempty"` + Volumes []volume.Volume `json:"Volumes,omitzero"` // Deprecated: kept to maintain backwards compatibility with API < v1.52, use [BuildCacheDiskUsage.Items] instead. - BuildCache []*build.CacheRecord `json:"BuildCache,omitempty"` + BuildCache []build.CacheRecord `json:"BuildCache,omitzero"` } diff --git a/vendor/github.com/moby/moby/client/system_disk_usage.go b/vendor/github.com/moby/moby/client/system_disk_usage.go index a179d86f62..563c60d5b3 100644 --- a/vendor/github.com/moby/moby/client/system_disk_usage.go +++ b/vendor/github.com/moby/moby/client/system_disk_usage.go @@ -171,13 +171,7 @@ func (cli *Client) DiskUsage(ctx context.Context, options DiskUsageOptions) (Dis } if options.Verbose { - r.Images.Items = slices.Collect(func(yield func(image.Summary) bool) { - for _, i := range du.Images { - if !yield(*i) { - return - } - } - }) + r.Images.Items = du.Images } } @@ -194,13 +188,7 @@ func (cli *Client) DiskUsage(ctx context.Context, options DiskUsageOptions) (Dis } } else if du.Containers != nil && options.Verbose { // Fallback for legacy response. - r.Containers.Items = slices.Collect(func(yield func(container.Summary) bool) { - for _, c := range du.Containers { - if !yield(*c) { - return - } - } - }) + r.Containers.Items = du.Containers } if du.BuildCacheUsage != nil { @@ -216,13 +204,7 @@ func (cli *Client) DiskUsage(ctx context.Context, options DiskUsageOptions) (Dis } } else if du.BuildCache != nil && options.Verbose { // Fallback for legacy response. - r.BuildCache.Items = slices.Collect(func(yield func(build.CacheRecord) bool) { - for _, b := range du.BuildCache { - if !yield(*b) { - return - } - } - }) + r.BuildCache.Items = du.BuildCache } if du.VolumeUsage != nil { @@ -238,13 +220,7 @@ func (cli *Client) DiskUsage(ctx context.Context, options DiskUsageOptions) (Dis } } else if du.Volumes != nil && options.Verbose { // Fallback for legacy response. - r.Volumes.Items = slices.Collect(func(yield func(volume.Volume) bool) { - for _, v := range du.Volumes { - if !yield(*v) { - return - } - } - }) + r.Volumes.Items = du.Volumes } return r, nil