api: remove / internalize LegacyDiskUsage

These fields have been removed from the API specification, and the struct
was only needed to produce legacy responses (server), or to unmarshal
legacy responses in the client.

As the API module only provides API definitions for the current API version,
we should remove these legacy structs, and keep them internal to the daemon
and client.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2025-11-07 17:14:33 +01:00
parent 4dc87c55c7
commit ed428234bd
8 changed files with 104 additions and 87 deletions

View File

@@ -75,9 +75,11 @@ keywords: "API, Docker, rcli, REST, documentation"
`BuildCacheUsage` fields with brief system disk usage data for each system object type.
The endpoint supports the `?verbose=1` query to return verbose system disk usage information.
* Deprecated: `GET /system/df` response fields `LayersSize`, `Images`, `Containers`,
`Volumes`, and `BuildCache` are deprecated in favor of the type specific usage fields.
The legacy fields will not be populated for new API versions that specify the `verbose`
query.
`Volumes`, and `BuildCache` have been removed in favor of the-type specific usage fields.
API v1.52 returns both the legacy and current fields to help existing integrations
to transition to the new response. The legacy fields are not populated if the
`verbose` query parameter is used. Starting with API v1.53, the legacy fields
will no longer be returned.
## v1.51 API changes

View File

@@ -24,27 +24,8 @@ const (
// DiskUsage contains response of Engine API:
// GET "/system/df"
type DiskUsage struct {
LegacyDiskUsage
ImageUsage *image.DiskUsage `json:"ImageUsage,omitempty"`
ContainerUsage *container.DiskUsage `json:"ContainerUsage,omitempty"`
VolumeUsage *volume.DiskUsage `json:"VolumeUsage,omitempty"`
BuildCacheUsage *build.DiskUsage `json:"BuildCacheUsage,omitempty"`
}
type LegacyDiskUsage struct {
// Deprecated: kept to maintain backwards compatibility with API < v1.52, use [ImagesDiskUsage.TotalSize] instead.
LayersSize int64 `json:"LayersSize,omitempty"`
// Deprecated: kept to maintain backwards compatibility with API < v1.52, use [ImagesDiskUsage.Items] instead.
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,omitzero"`
// Deprecated: kept to maintain backwards compatibility with API < v1.52, use [VolumesDiskUsage.Items] instead.
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,omitzero"`
}

View File

@@ -6,7 +6,6 @@ import (
"fmt"
"net/url"
"slices"
"strings"
"github.com/moby/moby/api/types/build"
"github.com/moby/moby/api/types/container"
@@ -149,14 +148,19 @@ func (cli *Client) DiskUsage(ctx context.Context, options DiskUsageOptions) (Dis
return DiskUsageResult{}, err
}
var du system.DiskUsage
if err := json.NewDecoder(resp.Body).Decode(&du); err != nil {
return DiskUsageResult{}, fmt.Errorf("Error retrieving disk usage: %v", err)
if versions.LessThan(cli.version, "1.52") {
// Generate result from a legacy response.
var du legacyDiskUsage
if err := json.NewDecoder(resp.Body).Decode(&du); err != nil {
return DiskUsageResult{}, fmt.Errorf("retrieving disk usage: %v", err)
}
return diskUsageResultFromLegacyAPI(&du), nil
}
// Generate result from a legacy response.
if versions.LessThan(cli.version, "1.52") {
return diskUsageResultFromLegacyAPI(&du), nil
var du system.DiskUsage
if err := json.NewDecoder(resp.Body).Decode(&du); err != nil {
return DiskUsageResult{}, fmt.Errorf("retrieving disk usage: %v", err)
}
var r DiskUsageResult
@@ -215,7 +219,16 @@ func (cli *Client) DiskUsage(ctx context.Context, options DiskUsageOptions) (Dis
return r, nil
}
func diskUsageResultFromLegacyAPI(du *system.DiskUsage) DiskUsageResult {
// legacyDiskUsage is the response as was used by API < v1.52.
type legacyDiskUsage struct {
LayersSize int64 `json:"LayersSize,omitempty"`
Images []image.Summary `json:"Images,omitzero"`
Containers []container.Summary `json:"Containers,omitzero"`
Volumes []volume.Volume `json:"Volumes,omitzero"`
BuildCache []build.CacheRecord `json:"BuildCache,omitzero"`
}
func diskUsageResultFromLegacyAPI(du *legacyDiskUsage) DiskUsageResult {
return DiskUsageResult{
Images: imageDiskUsageFromLegacyAPI(du),
Containers: containerDiskUsageFromLegacyAPI(du),
@@ -224,7 +237,7 @@ func diskUsageResultFromLegacyAPI(du *system.DiskUsage) DiskUsageResult {
}
}
func imageDiskUsageFromLegacyAPI(du *system.DiskUsage) ImagesDiskUsage {
func imageDiskUsageFromLegacyAPI(du *legacyDiskUsage) ImagesDiskUsage {
idu := ImagesDiskUsage{
TotalSize: du.LayersSize,
TotalCount: int64(len(du.Images)),
@@ -250,7 +263,7 @@ func imageDiskUsageFromLegacyAPI(du *system.DiskUsage) ImagesDiskUsage {
return idu
}
func containerDiskUsageFromLegacyAPI(du *system.DiskUsage) ContainersDiskUsage {
func containerDiskUsageFromLegacyAPI(du *legacyDiskUsage) ContainersDiskUsage {
cdu := ContainersDiskUsage{
TotalCount: int64(len(du.Containers)),
Items: du.Containers,
@@ -259,8 +272,8 @@ func containerDiskUsageFromLegacyAPI(du *system.DiskUsage) ContainersDiskUsage {
var used int64
for _, c := range cdu.Items {
cdu.TotalSize += c.SizeRw
switch strings.ToLower(c.State) {
case "running", "paused", "restarting":
switch c.State {
case container.StateRunning, container.StatePaused, container.StateRestarting:
cdu.ActiveCount++
used += c.SizeRw
}
@@ -270,7 +283,7 @@ func containerDiskUsageFromLegacyAPI(du *system.DiskUsage) ContainersDiskUsage {
return cdu
}
func buildCacheDiskUsageFromLegacyAPI(du *system.DiskUsage) BuildCacheDiskUsage {
func buildCacheDiskUsageFromLegacyAPI(du *legacyDiskUsage) BuildCacheDiskUsage {
bdu := BuildCacheDiskUsage{
TotalCount: int64(len(du.BuildCache)),
Items: du.BuildCache,
@@ -294,7 +307,7 @@ func buildCacheDiskUsageFromLegacyAPI(du *system.DiskUsage) BuildCacheDiskUsage
return bdu
}
func volumeDiskUsageFromLegacyAPI(du *system.DiskUsage) VolumesDiskUsage {
func volumeDiskUsageFromLegacyAPI(du *legacyDiskUsage) VolumesDiskUsage {
vdu := VolumesDiskUsage{
TotalCount: int64(len(du.Volumes)),
Items: du.Volumes,

View File

@@ -139,11 +139,9 @@ func TestLegacyDiskUsage(t *testing.T) {
return nil, err
}
return mockJSONResponse(http.StatusOK, nil, system.DiskUsage{
LegacyDiskUsage: system.LegacyDiskUsage{
LayersSize: 4096,
Images: []image.Summary{},
},
return mockJSONResponse(http.StatusOK, nil, &legacyDiskUsage{
LayersSize: 4096,
Images: []image.Summary{},
})(req)
}))
assert.NilError(t, err)

View File

@@ -0,0 +1,27 @@
package system
import (
buildtypes "github.com/moby/moby/api/types/build"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/system"
"github.com/moby/moby/api/types/volume"
)
// diskUsageCompat is used to provide API responses with backward-compatibility
// for API < v1.52, which used a different format. For API v1.52, we return
// both "old" and "new" responses if the client did not explicitly opt in to
// using the new format (through the use of the "verbose" query-parameter).
type diskUsageCompat struct {
*legacyDiskUsage
*system.DiskUsage
}
// legacyDiskUsage is the response as was used by API < v1.52.
type legacyDiskUsage struct {
LayersSize int64 `json:"LayersSize,omitempty"`
Images []image.Summary `json:"Images,omitzero"`
Containers []container.Summary `json:"Containers,omitzero"`
Volumes []volume.Volume `json:"Volumes,omitzero"`
BuildCache []buildtypes.CacheRecord `json:"BuildCache,omitzero"`
}

View File

@@ -216,32 +216,34 @@ func (s *systemRouter) getDiskUsage(ctx context.Context, w http.ResponseWriter,
}
diskUsage.BuildCache = buildCacheUsage
var legacy system.LegacyDiskUsage
var legacy legacyDiskUsage
if legacyFields {
if diskUsage.Images != nil {
legacy.LayersSize = diskUsage.Images.TotalSize //nolint: staticcheck,SA1019: kept to maintain backwards compatibility with API < v1.52.
legacy.Images = nonNilSlice(diskUsage.Images.Items) //nolint: staticcheck,SA1019: kept to maintain backwards compatibility with API < v1.52.
legacy.LayersSize = diskUsage.Images.TotalSize
legacy.Images = nonNilSlice(diskUsage.Images.Items)
}
if diskUsage.Containers != nil {
legacy.Containers = nonNilSlice(diskUsage.Containers.Items) //nolint: staticcheck,SA1019: kept to maintain backwards compatibility with API < v1.52.
legacy.Containers = nonNilSlice(diskUsage.Containers.Items)
}
if diskUsage.Volumes != nil {
legacy.Volumes = nonNilSlice(diskUsage.Volumes.Items) //nolint: staticcheck,SA1019: kept to maintain backwards compatibility with API < v1.52.
legacy.Volumes = nonNilSlice(diskUsage.Volumes.Items)
}
if diskUsage.BuildCache != nil {
legacy.BuildCache = nonNilSlice(diskUsage.BuildCache.Items) //nolint: staticcheck,SA1019: kept to maintain backwards compatibility with API < v1.52.
legacy.BuildCache = nonNilSlice(diskUsage.BuildCache.Items)
}
}
if versions.LessThan(version, "1.52") {
return httputils.WriteJSON(w, http.StatusOK, legacy)
return httputils.WriteJSON(w, http.StatusOK, &legacy)
}
return httputils.WriteJSON(w, http.StatusOK, &system.DiskUsage{
LegacyDiskUsage: legacy,
ImageUsage: diskUsage.Images,
ContainerUsage: diskUsage.Containers,
VolumeUsage: diskUsage.Volumes,
BuildCacheUsage: diskUsage.BuildCache,
return httputils.WriteJSON(w, http.StatusOK, &diskUsageCompat{
legacyDiskUsage: &legacy,
DiskUsage: &system.DiskUsage{
ImageUsage: diskUsage.Images,
ContainerUsage: diskUsage.Containers,
VolumeUsage: diskUsage.Volumes,
BuildCacheUsage: diskUsage.BuildCache,
},
})
}

View File

@@ -24,27 +24,8 @@ const (
// DiskUsage contains response of Engine API:
// GET "/system/df"
type DiskUsage struct {
LegacyDiskUsage
ImageUsage *image.DiskUsage `json:"ImageUsage,omitempty"`
ContainerUsage *container.DiskUsage `json:"ContainerUsage,omitempty"`
VolumeUsage *volume.DiskUsage `json:"VolumeUsage,omitempty"`
BuildCacheUsage *build.DiskUsage `json:"BuildCacheUsage,omitempty"`
}
type LegacyDiskUsage struct {
// Deprecated: kept to maintain backwards compatibility with API < v1.52, use [ImagesDiskUsage.TotalSize] instead.
LayersSize int64 `json:"LayersSize,omitempty"`
// Deprecated: kept to maintain backwards compatibility with API < v1.52, use [ImagesDiskUsage.Items] instead.
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,omitzero"`
// Deprecated: kept to maintain backwards compatibility with API < v1.52, use [VolumesDiskUsage.Items] instead.
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,omitzero"`
}

View File

@@ -6,7 +6,6 @@ import (
"fmt"
"net/url"
"slices"
"strings"
"github.com/moby/moby/api/types/build"
"github.com/moby/moby/api/types/container"
@@ -149,14 +148,19 @@ func (cli *Client) DiskUsage(ctx context.Context, options DiskUsageOptions) (Dis
return DiskUsageResult{}, err
}
var du system.DiskUsage
if err := json.NewDecoder(resp.Body).Decode(&du); err != nil {
return DiskUsageResult{}, fmt.Errorf("Error retrieving disk usage: %v", err)
if versions.LessThan(cli.version, "1.52") {
// Generate result from a legacy response.
var du legacyDiskUsage
if err := json.NewDecoder(resp.Body).Decode(&du); err != nil {
return DiskUsageResult{}, fmt.Errorf("retrieving disk usage: %v", err)
}
return diskUsageResultFromLegacyAPI(&du), nil
}
// Generate result from a legacy response.
if versions.LessThan(cli.version, "1.52") {
return diskUsageResultFromLegacyAPI(&du), nil
var du system.DiskUsage
if err := json.NewDecoder(resp.Body).Decode(&du); err != nil {
return DiskUsageResult{}, fmt.Errorf("retrieving disk usage: %v", err)
}
var r DiskUsageResult
@@ -215,7 +219,16 @@ func (cli *Client) DiskUsage(ctx context.Context, options DiskUsageOptions) (Dis
return r, nil
}
func diskUsageResultFromLegacyAPI(du *system.DiskUsage) DiskUsageResult {
// legacyDiskUsage is the response as was used by API < v1.52.
type legacyDiskUsage struct {
LayersSize int64 `json:"LayersSize,omitempty"`
Images []image.Summary `json:"Images,omitzero"`
Containers []container.Summary `json:"Containers,omitzero"`
Volumes []volume.Volume `json:"Volumes,omitzero"`
BuildCache []build.CacheRecord `json:"BuildCache,omitzero"`
}
func diskUsageResultFromLegacyAPI(du *legacyDiskUsage) DiskUsageResult {
return DiskUsageResult{
Images: imageDiskUsageFromLegacyAPI(du),
Containers: containerDiskUsageFromLegacyAPI(du),
@@ -224,7 +237,7 @@ func diskUsageResultFromLegacyAPI(du *system.DiskUsage) DiskUsageResult {
}
}
func imageDiskUsageFromLegacyAPI(du *system.DiskUsage) ImagesDiskUsage {
func imageDiskUsageFromLegacyAPI(du *legacyDiskUsage) ImagesDiskUsage {
idu := ImagesDiskUsage{
TotalSize: du.LayersSize,
TotalCount: int64(len(du.Images)),
@@ -250,7 +263,7 @@ func imageDiskUsageFromLegacyAPI(du *system.DiskUsage) ImagesDiskUsage {
return idu
}
func containerDiskUsageFromLegacyAPI(du *system.DiskUsage) ContainersDiskUsage {
func containerDiskUsageFromLegacyAPI(du *legacyDiskUsage) ContainersDiskUsage {
cdu := ContainersDiskUsage{
TotalCount: int64(len(du.Containers)),
Items: du.Containers,
@@ -259,8 +272,8 @@ func containerDiskUsageFromLegacyAPI(du *system.DiskUsage) ContainersDiskUsage {
var used int64
for _, c := range cdu.Items {
cdu.TotalSize += c.SizeRw
switch strings.ToLower(c.State) {
case "running", "paused", "restarting":
switch c.State {
case container.StateRunning, container.StatePaused, container.StateRestarting:
cdu.ActiveCount++
used += c.SizeRw
}
@@ -270,7 +283,7 @@ func containerDiskUsageFromLegacyAPI(du *system.DiskUsage) ContainersDiskUsage {
return cdu
}
func buildCacheDiskUsageFromLegacyAPI(du *system.DiskUsage) BuildCacheDiskUsage {
func buildCacheDiskUsageFromLegacyAPI(du *legacyDiskUsage) BuildCacheDiskUsage {
bdu := BuildCacheDiskUsage{
TotalCount: int64(len(du.BuildCache)),
Items: du.BuildCache,
@@ -294,7 +307,7 @@ func buildCacheDiskUsageFromLegacyAPI(du *system.DiskUsage) BuildCacheDiskUsage
return bdu
}
func volumeDiskUsageFromLegacyAPI(du *system.DiskUsage) VolumesDiskUsage {
func volumeDiskUsageFromLegacyAPI(du *legacyDiskUsage) VolumesDiskUsage {
vdu := VolumesDiskUsage{
TotalCount: int64(len(du.Volumes)),
Items: du.Volumes,