mirror of
https://github.com/moby/moby.git
synced 2026-01-11 10:41:43 +00:00
api/types/system: add type specific usage fields to DiskUsage
This change adds type specific fields to `GET /system/df` endpoint with high level information of disk usage. This change also introduces `verbose` query to the endpoint so that detailed information is by default excluded unless queried to reduce memory consumption. The previous top level `DiskUsage` fields (`Images`, `Containers`, `Volumes` and `BuildCache`) are now deprecated and kept for backwards compatibility. Co-authored-by: Claude <noreply@anthropic.com> Signed-off-by: Austin Vazquez <austin.vazquez@docker.com>
This commit is contained in:
@@ -71,6 +71,13 @@ keywords: "API, Docker, rcli, REST, documentation"
|
||||
part of the `Resource` requirements.
|
||||
* `GET /containers/{id}/stats` now returns an `os_type` field to allow platform-
|
||||
specific handling of the stats.
|
||||
* `GET /system/df` returns `ImagesUsage`, `ContainersUsage`, `VolumesUsage`, and
|
||||
`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.
|
||||
|
||||
## v1.51 API changes
|
||||
|
||||
|
||||
@@ -2059,6 +2059,47 @@ definitions:
|
||||
x-nullable: true
|
||||
$ref: "#/definitions/OCIDescriptor"
|
||||
|
||||
ImagesDiskUsage:
|
||||
type: "object"
|
||||
description: |
|
||||
ImagesDiskUsage represents system data usage for image resources.
|
||||
properties:
|
||||
ActiveImages:
|
||||
description: |
|
||||
Count of active images.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 1
|
||||
TotalImages:
|
||||
description: |
|
||||
Count of all images.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 4
|
||||
Reclaimable:
|
||||
description: |
|
||||
Disk space that can be reclaimed by removing unused images.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 12345678
|
||||
TotalSize:
|
||||
description: |
|
||||
Disk space in use by images.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 98765432
|
||||
Items:
|
||||
description: |
|
||||
List of image summaries.
|
||||
type: "array"
|
||||
x-omitempty: true
|
||||
items:
|
||||
x-nullable: true
|
||||
x-go-type:
|
||||
type: Summary
|
||||
import:
|
||||
package: github.com/moby/moby/api/types/image
|
||||
|
||||
AuthConfig:
|
||||
type: "object"
|
||||
properties:
|
||||
@@ -2201,6 +2242,47 @@ definitions:
|
||||
is set to `-1` if the reference-count is not available.
|
||||
x-nullable: false
|
||||
|
||||
VolumesDiskUsage:
|
||||
type: "object"
|
||||
description: |
|
||||
VolumesDiskUsage represents system data usage for volume resources.
|
||||
properties:
|
||||
ActiveVolumes:
|
||||
description: |
|
||||
Count of active volumes.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 1
|
||||
TotalVolumes:
|
||||
description: |
|
||||
Count of all volumes.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 4
|
||||
Reclaimable:
|
||||
description: |
|
||||
Disk space that can be reclaimed by removing inactive volumes.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 12345678
|
||||
TotalSize:
|
||||
description: |
|
||||
Disk space in use by volumes.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 98765432
|
||||
Items:
|
||||
description: |
|
||||
List of volumes.
|
||||
type: "array"
|
||||
x-omitempty: true
|
||||
items:
|
||||
x-nullable: true
|
||||
x-go-type:
|
||||
type: Volume
|
||||
import:
|
||||
package: github.com/moby/moby/api/types/volume
|
||||
|
||||
VolumeCreateRequest:
|
||||
description: "Volume configuration"
|
||||
type: "object"
|
||||
@@ -2628,6 +2710,8 @@ definitions:
|
||||
type: "string"
|
||||
x-omitempty: false
|
||||
example: "02:42:ac:13:00:02"
|
||||
x-go-type:
|
||||
type: HardwareAddr
|
||||
IPv4Address:
|
||||
type: "string"
|
||||
x-omitempty: false
|
||||
@@ -2772,6 +2856,47 @@ definitions:
|
||||
type: "integer"
|
||||
example: 26
|
||||
|
||||
BuildCacheDiskUsage:
|
||||
type: "object"
|
||||
description: |
|
||||
BuildCacheDiskUsage represents system data usage for build cache resources.
|
||||
properties:
|
||||
ActiveBuildCacheRecords:
|
||||
description: |
|
||||
Count of active build cache records.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 1
|
||||
TotalBuildCacheRecords:
|
||||
description: |
|
||||
Count of all build cache records.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 4
|
||||
Reclaimable:
|
||||
description: |
|
||||
Disk space that can be reclaimed by removing inactive build cache records.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 12345678
|
||||
TotalSize:
|
||||
description: |
|
||||
Disk space in use by build cache records.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 98765432
|
||||
Items:
|
||||
description: |
|
||||
List of build cache records.
|
||||
type: "array"
|
||||
x-omitempty: true
|
||||
items:
|
||||
x-nullable: true
|
||||
x-go-type:
|
||||
type: CacheRecord
|
||||
import:
|
||||
package: github.com/moby/moby/api/types/build
|
||||
|
||||
ImageID:
|
||||
type: "object"
|
||||
description: "Image ID or Digest"
|
||||
@@ -2914,6 +3039,8 @@ definitions:
|
||||
MAC address for the endpoint on this network. The network driver might ignore this parameter.
|
||||
type: "string"
|
||||
example: "02:42:ac:11:00:04"
|
||||
x-go-type:
|
||||
type: HardwareAddr
|
||||
Aliases:
|
||||
type: "array"
|
||||
items:
|
||||
@@ -5453,6 +5580,47 @@ definitions:
|
||||
type: "integer"
|
||||
example: 0
|
||||
|
||||
ContainersDiskUsage:
|
||||
type: "object"
|
||||
description: |
|
||||
ContainersDiskUsage provides system data usage information for container resources.
|
||||
properties:
|
||||
ActiveContainers:
|
||||
description: |
|
||||
Count of active containers.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 1
|
||||
TotalContainers:
|
||||
description: |
|
||||
Count of all containers.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 4
|
||||
Reclaimable:
|
||||
description: |
|
||||
Disk space that can be reclaimed by removing inactive containers.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 12345678
|
||||
TotalSize:
|
||||
description: |
|
||||
Disk space in use by containers.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 98765432
|
||||
Items:
|
||||
description: |
|
||||
List of container summaries.
|
||||
type: "array"
|
||||
x-omitempty: true
|
||||
items:
|
||||
x-nullable: true
|
||||
x-go-type:
|
||||
type: Summary
|
||||
import:
|
||||
package: github.com/moby/moby/api/types/container
|
||||
|
||||
Driver:
|
||||
description: "Driver represents a driver (network, logging, secrets)."
|
||||
type: "object"
|
||||
@@ -10332,106 +10500,14 @@ paths:
|
||||
type: "object"
|
||||
title: "SystemDataUsageResponse"
|
||||
properties:
|
||||
LayersSize:
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
Images:
|
||||
type: "array"
|
||||
items:
|
||||
$ref: "#/definitions/ImageSummary"
|
||||
Containers:
|
||||
type: "array"
|
||||
items:
|
||||
$ref: "#/definitions/ContainerSummary"
|
||||
Volumes:
|
||||
type: "array"
|
||||
items:
|
||||
$ref: "#/definitions/Volume"
|
||||
BuildCache:
|
||||
type: "array"
|
||||
items:
|
||||
$ref: "#/definitions/BuildCache"
|
||||
example:
|
||||
LayersSize: 1092588
|
||||
Images:
|
||||
-
|
||||
Id: "sha256:2b8fd9751c4c0f5dd266fcae00707e67a2545ef34f9a29354585f93dac906749"
|
||||
ParentId: ""
|
||||
RepoTags:
|
||||
- "busybox:latest"
|
||||
RepoDigests:
|
||||
- "busybox@sha256:a59906e33509d14c036c8678d687bd4eec81ed7c4b8ce907b888c607f6a1e0e6"
|
||||
Created: 1466724217
|
||||
Size: 1092588
|
||||
SharedSize: 0
|
||||
Labels: {}
|
||||
Containers: 1
|
||||
Containers:
|
||||
-
|
||||
Id: "e575172ed11dc01bfce087fb27bee502db149e1a0fad7c296ad300bbff178148"
|
||||
Names:
|
||||
- "/top"
|
||||
Image: "busybox"
|
||||
ImageID: "sha256:2b8fd9751c4c0f5dd266fcae00707e67a2545ef34f9a29354585f93dac906749"
|
||||
Command: "top"
|
||||
Created: 1472592424
|
||||
Ports: []
|
||||
SizeRootFs: 1092588
|
||||
Labels: {}
|
||||
State: "exited"
|
||||
Status: "Exited (0) 56 minutes ago"
|
||||
HostConfig:
|
||||
NetworkMode: "default"
|
||||
NetworkSettings:
|
||||
Networks:
|
||||
bridge:
|
||||
IPAMConfig: null
|
||||
Links: null
|
||||
Aliases: null
|
||||
NetworkID: "d687bc59335f0e5c9ee8193e5612e8aee000c8c62ea170cfb99c098f95899d92"
|
||||
EndpointID: "8ed5115aeaad9abb174f68dcf135b49f11daf597678315231a32ca28441dec6a"
|
||||
Gateway: "172.18.0.1"
|
||||
IPAddress: "172.18.0.2"
|
||||
IPPrefixLen: 16
|
||||
IPv6Gateway: ""
|
||||
GlobalIPv6Address: ""
|
||||
GlobalIPv6PrefixLen: 0
|
||||
MacAddress: "02:42:ac:12:00:02"
|
||||
Mounts: []
|
||||
Volumes:
|
||||
-
|
||||
Name: "my-volume"
|
||||
Driver: "local"
|
||||
Mountpoint: "/var/lib/docker/volumes/my-volume/_data"
|
||||
Labels: null
|
||||
Scope: "local"
|
||||
Options: null
|
||||
UsageData:
|
||||
Size: 10920104
|
||||
RefCount: 2
|
||||
BuildCache:
|
||||
-
|
||||
ID: "hw53o5aio51xtltp5xjp8v7fx"
|
||||
Parents: []
|
||||
Type: "regular"
|
||||
Description: "pulled from docker.io/library/debian@sha256:234cb88d3020898631af0ccbbcca9a66ae7306ecd30c9720690858c1b007d2a0"
|
||||
InUse: false
|
||||
Shared: true
|
||||
Size: 0
|
||||
CreatedAt: "2021-06-28T13:31:01.474619385Z"
|
||||
LastUsedAt: "2021-07-07T22:02:32.738075951Z"
|
||||
UsageCount: 26
|
||||
-
|
||||
ID: "ndlpt0hhvkqcdfkputsk4cq9c"
|
||||
Parents: ["ndlpt0hhvkqcdfkputsk4cq9c"]
|
||||
Type: "regular"
|
||||
Description: "mount / from exec /bin/sh -c echo 'Binary::apt::APT::Keep-Downloaded-Packages \"true\";' > /etc/apt/apt.conf.d/keep-cache"
|
||||
InUse: false
|
||||
Shared: true
|
||||
Size: 51
|
||||
CreatedAt: "2021-06-28T13:31:03.002625487Z"
|
||||
LastUsedAt: "2021-07-07T22:02:32.773909517Z"
|
||||
UsageCount: 26
|
||||
ImagesDiskUsage:
|
||||
$ref: "#/definitions/ImagesDiskUsage"
|
||||
ContainersDiskUsage:
|
||||
$ref: "#/definitions/ContainersDiskUsage"
|
||||
VolumesDiskUsage:
|
||||
$ref: "#/definitions/VolumesDiskUsage"
|
||||
BuildCacheDiskUsage:
|
||||
$ref: "#/definitions/BuildCacheDiskUsage"
|
||||
500:
|
||||
description: "server error"
|
||||
schema:
|
||||
@@ -10446,6 +10522,12 @@ paths:
|
||||
items:
|
||||
type: "string"
|
||||
enum: ["container", "image", "volume", "build-cache"]
|
||||
- name: "verbose"
|
||||
in: "query"
|
||||
description: |
|
||||
Show detailed information on space usage.
|
||||
type: "boolean"
|
||||
default: false
|
||||
tags: ["System"]
|
||||
/images/{name}/get:
|
||||
get:
|
||||
|
||||
278
api/swagger.yaml
278
api/swagger.yaml
@@ -2059,6 +2059,47 @@ definitions:
|
||||
x-nullable: true
|
||||
$ref: "#/definitions/OCIDescriptor"
|
||||
|
||||
ImagesDiskUsage:
|
||||
type: "object"
|
||||
description: |
|
||||
ImagesDiskUsage represents system data usage for image resources.
|
||||
properties:
|
||||
ActiveImages:
|
||||
description: |
|
||||
Count of active images.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 1
|
||||
TotalImages:
|
||||
description: |
|
||||
Count of all images.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 4
|
||||
Reclaimable:
|
||||
description: |
|
||||
Disk space that can be reclaimed by removing unused images.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 12345678
|
||||
TotalSize:
|
||||
description: |
|
||||
Disk space in use by images.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 98765432
|
||||
Items:
|
||||
description: |
|
||||
List of image summaries.
|
||||
type: "array"
|
||||
x-omitempty: true
|
||||
items:
|
||||
x-nullable: true
|
||||
x-go-type:
|
||||
type: Summary
|
||||
import:
|
||||
package: github.com/moby/moby/api/types/image
|
||||
|
||||
AuthConfig:
|
||||
type: "object"
|
||||
properties:
|
||||
@@ -2201,6 +2242,47 @@ definitions:
|
||||
is set to `-1` if the reference-count is not available.
|
||||
x-nullable: false
|
||||
|
||||
VolumesDiskUsage:
|
||||
type: "object"
|
||||
description: |
|
||||
VolumesDiskUsage represents system data usage for volume resources.
|
||||
properties:
|
||||
ActiveVolumes:
|
||||
description: |
|
||||
Count of active volumes.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 1
|
||||
TotalVolumes:
|
||||
description: |
|
||||
Count of all volumes.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 4
|
||||
Reclaimable:
|
||||
description: |
|
||||
Disk space that can be reclaimed by removing inactive volumes.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 12345678
|
||||
TotalSize:
|
||||
description: |
|
||||
Disk space in use by volumes.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 98765432
|
||||
Items:
|
||||
description: |
|
||||
List of volumes.
|
||||
type: "array"
|
||||
x-omitempty: true
|
||||
items:
|
||||
x-nullable: true
|
||||
x-go-type:
|
||||
type: Volume
|
||||
import:
|
||||
package: github.com/moby/moby/api/types/volume
|
||||
|
||||
VolumeCreateRequest:
|
||||
description: "Volume configuration"
|
||||
type: "object"
|
||||
@@ -2774,6 +2856,47 @@ definitions:
|
||||
type: "integer"
|
||||
example: 26
|
||||
|
||||
BuildCacheDiskUsage:
|
||||
type: "object"
|
||||
description: |
|
||||
BuildCacheDiskUsage represents system data usage for build cache resources.
|
||||
properties:
|
||||
ActiveBuildCacheRecords:
|
||||
description: |
|
||||
Count of active build cache records.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 1
|
||||
TotalBuildCacheRecords:
|
||||
description: |
|
||||
Count of all build cache records.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 4
|
||||
Reclaimable:
|
||||
description: |
|
||||
Disk space that can be reclaimed by removing inactive build cache records.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 12345678
|
||||
TotalSize:
|
||||
description: |
|
||||
Disk space in use by build cache records.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 98765432
|
||||
Items:
|
||||
description: |
|
||||
List of build cache records.
|
||||
type: "array"
|
||||
x-omitempty: true
|
||||
items:
|
||||
x-nullable: true
|
||||
x-go-type:
|
||||
type: CacheRecord
|
||||
import:
|
||||
package: github.com/moby/moby/api/types/build
|
||||
|
||||
ImageID:
|
||||
type: "object"
|
||||
description: "Image ID or Digest"
|
||||
@@ -5457,6 +5580,47 @@ definitions:
|
||||
type: "integer"
|
||||
example: 0
|
||||
|
||||
ContainersDiskUsage:
|
||||
type: "object"
|
||||
description: |
|
||||
ContainersDiskUsage provides system data usage information for container resources.
|
||||
properties:
|
||||
ActiveContainers:
|
||||
description: |
|
||||
Count of active containers.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 1
|
||||
TotalContainers:
|
||||
description: |
|
||||
Count of all containers.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 4
|
||||
Reclaimable:
|
||||
description: |
|
||||
Disk space that can be reclaimed by removing inactive containers.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 12345678
|
||||
TotalSize:
|
||||
description: |
|
||||
Disk space in use by containers.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 98765432
|
||||
Items:
|
||||
description: |
|
||||
List of container summaries.
|
||||
type: "array"
|
||||
x-omitempty: true
|
||||
items:
|
||||
x-nullable: true
|
||||
x-go-type:
|
||||
type: Summary
|
||||
import:
|
||||
package: github.com/moby/moby/api/types/container
|
||||
|
||||
Driver:
|
||||
description: "Driver represents a driver (network, logging, secrets)."
|
||||
type: "object"
|
||||
@@ -10336,106 +10500,14 @@ paths:
|
||||
type: "object"
|
||||
title: "SystemDataUsageResponse"
|
||||
properties:
|
||||
LayersSize:
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
Images:
|
||||
type: "array"
|
||||
items:
|
||||
$ref: "#/definitions/ImageSummary"
|
||||
Containers:
|
||||
type: "array"
|
||||
items:
|
||||
$ref: "#/definitions/ContainerSummary"
|
||||
Volumes:
|
||||
type: "array"
|
||||
items:
|
||||
$ref: "#/definitions/Volume"
|
||||
BuildCache:
|
||||
type: "array"
|
||||
items:
|
||||
$ref: "#/definitions/BuildCache"
|
||||
example:
|
||||
LayersSize: 1092588
|
||||
Images:
|
||||
-
|
||||
Id: "sha256:2b8fd9751c4c0f5dd266fcae00707e67a2545ef34f9a29354585f93dac906749"
|
||||
ParentId: ""
|
||||
RepoTags:
|
||||
- "busybox:latest"
|
||||
RepoDigests:
|
||||
- "busybox@sha256:a59906e33509d14c036c8678d687bd4eec81ed7c4b8ce907b888c607f6a1e0e6"
|
||||
Created: 1466724217
|
||||
Size: 1092588
|
||||
SharedSize: 0
|
||||
Labels: {}
|
||||
Containers: 1
|
||||
Containers:
|
||||
-
|
||||
Id: "e575172ed11dc01bfce087fb27bee502db149e1a0fad7c296ad300bbff178148"
|
||||
Names:
|
||||
- "/top"
|
||||
Image: "busybox"
|
||||
ImageID: "sha256:2b8fd9751c4c0f5dd266fcae00707e67a2545ef34f9a29354585f93dac906749"
|
||||
Command: "top"
|
||||
Created: 1472592424
|
||||
Ports: []
|
||||
SizeRootFs: 1092588
|
||||
Labels: {}
|
||||
State: "exited"
|
||||
Status: "Exited (0) 56 minutes ago"
|
||||
HostConfig:
|
||||
NetworkMode: "default"
|
||||
NetworkSettings:
|
||||
Networks:
|
||||
bridge:
|
||||
IPAMConfig: null
|
||||
Links: null
|
||||
Aliases: null
|
||||
NetworkID: "d687bc59335f0e5c9ee8193e5612e8aee000c8c62ea170cfb99c098f95899d92"
|
||||
EndpointID: "8ed5115aeaad9abb174f68dcf135b49f11daf597678315231a32ca28441dec6a"
|
||||
Gateway: "172.18.0.1"
|
||||
IPAddress: "172.18.0.2"
|
||||
IPPrefixLen: 16
|
||||
IPv6Gateway: ""
|
||||
GlobalIPv6Address: ""
|
||||
GlobalIPv6PrefixLen: 0
|
||||
MacAddress: "02:42:ac:12:00:02"
|
||||
Mounts: []
|
||||
Volumes:
|
||||
-
|
||||
Name: "my-volume"
|
||||
Driver: "local"
|
||||
Mountpoint: "/var/lib/docker/volumes/my-volume/_data"
|
||||
Labels: null
|
||||
Scope: "local"
|
||||
Options: null
|
||||
UsageData:
|
||||
Size: 10920104
|
||||
RefCount: 2
|
||||
BuildCache:
|
||||
-
|
||||
ID: "hw53o5aio51xtltp5xjp8v7fx"
|
||||
Parents: []
|
||||
Type: "regular"
|
||||
Description: "pulled from docker.io/library/debian@sha256:234cb88d3020898631af0ccbbcca9a66ae7306ecd30c9720690858c1b007d2a0"
|
||||
InUse: false
|
||||
Shared: true
|
||||
Size: 0
|
||||
CreatedAt: "2021-06-28T13:31:01.474619385Z"
|
||||
LastUsedAt: "2021-07-07T22:02:32.738075951Z"
|
||||
UsageCount: 26
|
||||
-
|
||||
ID: "ndlpt0hhvkqcdfkputsk4cq9c"
|
||||
Parents: ["ndlpt0hhvkqcdfkputsk4cq9c"]
|
||||
Type: "regular"
|
||||
Description: "mount / from exec /bin/sh -c echo 'Binary::apt::APT::Keep-Downloaded-Packages \"true\";' > /etc/apt/apt.conf.d/keep-cache"
|
||||
InUse: false
|
||||
Shared: true
|
||||
Size: 51
|
||||
CreatedAt: "2021-06-28T13:31:03.002625487Z"
|
||||
LastUsedAt: "2021-07-07T22:02:32.773909517Z"
|
||||
UsageCount: 26
|
||||
ImagesDiskUsage:
|
||||
$ref: "#/definitions/ImagesDiskUsage"
|
||||
ContainersDiskUsage:
|
||||
$ref: "#/definitions/ContainersDiskUsage"
|
||||
VolumesDiskUsage:
|
||||
$ref: "#/definitions/VolumesDiskUsage"
|
||||
BuildCacheDiskUsage:
|
||||
$ref: "#/definitions/BuildCacheDiskUsage"
|
||||
500:
|
||||
description: "server error"
|
||||
schema:
|
||||
@@ -10450,6 +10522,12 @@ paths:
|
||||
items:
|
||||
type: "string"
|
||||
enum: ["container", "image", "volume", "build-cache"]
|
||||
- name: "verbose"
|
||||
in: "query"
|
||||
description: |
|
||||
Show detailed information on space usage.
|
||||
type: "boolean"
|
||||
default: false
|
||||
tags: ["System"]
|
||||
/images/{name}/get:
|
||||
get:
|
||||
|
||||
40
api/types/system/build_cache_disk_usage.go
Normal file
40
api/types/system/build_cache_disk_usage.go
Normal file
@@ -0,0 +1,40 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package system
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"github.com/moby/moby/api/types/build"
|
||||
)
|
||||
|
||||
// BuildCacheDiskUsage BuildCacheDiskUsage represents system data usage for build cache resources.
|
||||
//
|
||||
// swagger:model BuildCacheDiskUsage
|
||||
type BuildCacheDiskUsage struct {
|
||||
|
||||
// Count of active build cache records.
|
||||
//
|
||||
// Example: 1
|
||||
ActiveBuildCacheRecords int64 `json:"ActiveBuildCacheRecords,omitempty"`
|
||||
|
||||
// List of build cache records.
|
||||
//
|
||||
Items []*build.CacheRecord `json:"Items,omitempty"`
|
||||
|
||||
// Disk space that can be reclaimed by removing inactive build cache records.
|
||||
//
|
||||
// Example: 12345678
|
||||
Reclaimable int64 `json:"Reclaimable,omitempty"`
|
||||
|
||||
// Count of all build cache records.
|
||||
//
|
||||
// Example: 4
|
||||
TotalBuildCacheRecords int64 `json:"TotalBuildCacheRecords,omitempty"`
|
||||
|
||||
// Disk space in use by build cache records.
|
||||
//
|
||||
// Example: 98765432
|
||||
TotalSize int64 `json:"TotalSize,omitempty"`
|
||||
}
|
||||
40
api/types/system/containers_disk_usage.go
Normal file
40
api/types/system/containers_disk_usage.go
Normal file
@@ -0,0 +1,40 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package system
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"github.com/moby/moby/api/types/container"
|
||||
)
|
||||
|
||||
// ContainersDiskUsage ContainersDiskUsage provides system data usage information for container resources.
|
||||
//
|
||||
// swagger:model ContainersDiskUsage
|
||||
type ContainersDiskUsage struct {
|
||||
|
||||
// Count of active containers.
|
||||
//
|
||||
// Example: 1
|
||||
ActiveContainers int64 `json:"ActiveContainers,omitempty"`
|
||||
|
||||
// List of container summaries.
|
||||
//
|
||||
Items []*container.Summary `json:"Items,omitempty"`
|
||||
|
||||
// Disk space that can be reclaimed by removing inactive containers.
|
||||
//
|
||||
// Example: 12345678
|
||||
Reclaimable int64 `json:"Reclaimable,omitempty"`
|
||||
|
||||
// Count of all containers.
|
||||
//
|
||||
// Example: 4
|
||||
TotalContainers int64 `json:"TotalContainers,omitempty"`
|
||||
|
||||
// Disk space in use by containers.
|
||||
//
|
||||
// Example: 98765432
|
||||
TotalSize int64 `json:"TotalSize,omitempty"`
|
||||
}
|
||||
@@ -24,9 +24,27 @@ const (
|
||||
// DiskUsage contains response of Engine API:
|
||||
// GET "/system/df"
|
||||
type DiskUsage struct {
|
||||
LayersSize int64
|
||||
Images []*image.Summary
|
||||
Containers []*container.Summary
|
||||
Volumes []*volume.Volume
|
||||
BuildCache []*build.CacheRecord
|
||||
LegacyDiskUsage
|
||||
|
||||
ImageUsage *ImagesDiskUsage `json:"ImageUsage,omitempty"`
|
||||
ContainerUsage *ContainersDiskUsage `json:"ContainerUsage,omitempty"`
|
||||
VolumeUsage *VolumesDiskUsage `json:"VolumeUsage,omitempty"`
|
||||
BuildCacheUsage *BuildCacheDiskUsage `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,omitempty"`
|
||||
|
||||
// Deprecated: kept to maintain backwards compatibility with API < v1.52, use [ContainersDiskUsage.Items] instead.
|
||||
Containers []*container.Summary `json:"Containers,omitempty"`
|
||||
|
||||
// Deprecated: kept to maintain backwards compatibility with API < v1.52, use [VolumesDiskUsage.Items] instead.
|
||||
Volumes []*volume.Volume `json:"Volumes,omitempty"`
|
||||
|
||||
// Deprecated: kept to maintain backwards compatibility with API < v1.52, use [BuildCacheDiskUsage.Items] instead.
|
||||
BuildCache []*build.CacheRecord `json:"BuildCache,omitempty"`
|
||||
}
|
||||
|
||||
40
api/types/system/images_disk_usage.go
Normal file
40
api/types/system/images_disk_usage.go
Normal file
@@ -0,0 +1,40 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package system
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"github.com/moby/moby/api/types/image"
|
||||
)
|
||||
|
||||
// ImagesDiskUsage ImagesDiskUsage represents system data usage for image resources.
|
||||
//
|
||||
// swagger:model ImagesDiskUsage
|
||||
type ImagesDiskUsage struct {
|
||||
|
||||
// Count of active images.
|
||||
//
|
||||
// Example: 1
|
||||
ActiveImages int64 `json:"ActiveImages,omitempty"`
|
||||
|
||||
// List of image summaries.
|
||||
//
|
||||
Items []*image.Summary `json:"Items,omitempty"`
|
||||
|
||||
// Disk space that can be reclaimed by removing unused images.
|
||||
//
|
||||
// Example: 12345678
|
||||
Reclaimable int64 `json:"Reclaimable,omitempty"`
|
||||
|
||||
// Count of all images.
|
||||
//
|
||||
// Example: 4
|
||||
TotalImages int64 `json:"TotalImages,omitempty"`
|
||||
|
||||
// Disk space in use by images.
|
||||
//
|
||||
// Example: 98765432
|
||||
TotalSize int64 `json:"TotalSize,omitempty"`
|
||||
}
|
||||
40
api/types/system/volumes_disk_usage.go
Normal file
40
api/types/system/volumes_disk_usage.go
Normal file
@@ -0,0 +1,40 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package system
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"github.com/moby/moby/api/types/volume"
|
||||
)
|
||||
|
||||
// VolumesDiskUsage VolumesDiskUsage represents system data usage for volume resources.
|
||||
//
|
||||
// swagger:model VolumesDiskUsage
|
||||
type VolumesDiskUsage struct {
|
||||
|
||||
// Count of active volumes.
|
||||
//
|
||||
// Example: 1
|
||||
ActiveVolumes int64 `json:"ActiveVolumes,omitempty"`
|
||||
|
||||
// List of volumes.
|
||||
//
|
||||
Items []*volume.Volume `json:"Items,omitempty"`
|
||||
|
||||
// Disk space that can be reclaimed by removing inactive volumes.
|
||||
//
|
||||
// Example: 12345678
|
||||
Reclaimable int64 `json:"Reclaimable,omitempty"`
|
||||
|
||||
// Disk space in use by volumes.
|
||||
//
|
||||
// Example: 98765432
|
||||
TotalSize int64 `json:"TotalSize,omitempty"`
|
||||
|
||||
// Count of all volumes.
|
||||
//
|
||||
// Example: 4
|
||||
TotalVolumes int64 `json:"TotalVolumes,omitempty"`
|
||||
}
|
||||
@@ -4,8 +4,6 @@ import (
|
||||
"context"
|
||||
"io"
|
||||
"net"
|
||||
|
||||
"github.com/moby/moby/api/types/system"
|
||||
)
|
||||
|
||||
// APIClient is an interface that clients that talk with a docker server must implement.
|
||||
@@ -173,7 +171,7 @@ type SystemAPIClient interface {
|
||||
Events(ctx context.Context, options EventsListOptions) EventsResult
|
||||
Info(ctx context.Context, options InfoOptions) (SystemInfoResult, error)
|
||||
RegistryLogin(ctx context.Context, auth RegistryLoginOptions) (RegistryLoginResult, error)
|
||||
DiskUsage(ctx context.Context, options DiskUsageOptions) (system.DiskUsage, error)
|
||||
DiskUsage(ctx context.Context, options DiskUsageOptions) (DiskUsageResult, error)
|
||||
Ping(ctx context.Context, options PingOptions) (PingResult, error)
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,17 @@ func assertRequest(req *http.Request, expMethod string, expectedPath string) err
|
||||
return nil
|
||||
}
|
||||
|
||||
func assertRequestWithQuery(req *http.Request, expMethod string, expectedPath string, expectedQuery string) error {
|
||||
if err := assertRequest(req, expMethod, expectedPath); err != nil {
|
||||
return err
|
||||
}
|
||||
q := req.URL.Query().Encode()
|
||||
if q != expectedQuery {
|
||||
return fmt.Errorf("expected query '%s', got '%s'", expectedQuery, q)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ensureBody makes sure the response has a Body, using [http.NoBody] if
|
||||
// none is present, and returns it as a testRoundTripper.
|
||||
func ensureBody(f func(req *http.Request) (*http.Response, error)) testRoundTripper {
|
||||
|
||||
@@ -6,28 +6,248 @@ import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
// DiskUsage requests the current data usage from the daemon
|
||||
func (cli *Client) DiskUsage(ctx context.Context, options DiskUsageOptions) (system.DiskUsage, error) {
|
||||
var query url.Values
|
||||
if len(options.Types) > 0 {
|
||||
query = url.Values{}
|
||||
for _, t := range options.Types {
|
||||
query.Add("type", string(t))
|
||||
// DiskUsageOptions holds parameters for [Client.DiskUsage] operations.
|
||||
type DiskUsageOptions struct {
|
||||
// Containers controls whether container disk usage should be computed.
|
||||
Containers bool
|
||||
|
||||
// Images controls whether image disk usage should be computed.
|
||||
Images bool
|
||||
|
||||
// BuildCache controls whether build cache disk usage should be computed.
|
||||
BuildCache bool
|
||||
|
||||
// Volumes controls whether volume disk usage should be computed.
|
||||
Volumes bool
|
||||
|
||||
// Verbose enables more detailed disk usage information.
|
||||
Verbose bool
|
||||
}
|
||||
|
||||
// DiskUsageResult is the result of [Client.DiskUsage] operations.
|
||||
type DiskUsageResult struct {
|
||||
// Containers holds container disk usage information.
|
||||
Containers ContainersDiskUsage
|
||||
|
||||
// Images holds image disk usage information.
|
||||
Images ImagesDiskUsage
|
||||
|
||||
// BuildCache holds build cache disk usage information.
|
||||
BuildCache BuildCacheDiskUsage
|
||||
|
||||
// Volumes holds volume disk usage information.
|
||||
Volumes VolumesDiskUsage
|
||||
}
|
||||
|
||||
// ContainersDiskUsage contains disk usage information for containers.
|
||||
type ContainersDiskUsage struct {
|
||||
// ActiveContainers is the number of active containers.
|
||||
ActiveContainers int64
|
||||
|
||||
// TotalContainers is the total number of containers.
|
||||
TotalContainers int64
|
||||
|
||||
// Reclaimable is the amount of disk space that can be reclaimed.
|
||||
Reclaimable int64
|
||||
|
||||
// TotalSize is the total disk space used by all containers.
|
||||
TotalSize int64
|
||||
|
||||
// Items holds detailed information about each container.
|
||||
Items []container.Summary
|
||||
}
|
||||
|
||||
// ImagesDiskUsage contains disk usage information for images.
|
||||
type ImagesDiskUsage struct {
|
||||
// ActiveImages is the number of active images.
|
||||
ActiveImages int64
|
||||
|
||||
// TotalImages is the total number of images.
|
||||
TotalImages int64
|
||||
|
||||
// Reclaimable is the amount of disk space that can be reclaimed.
|
||||
Reclaimable int64
|
||||
|
||||
// TotalSize is the total disk space used by all images.
|
||||
TotalSize int64
|
||||
|
||||
// Items holds detailed information about each image.
|
||||
Items []image.Summary
|
||||
}
|
||||
|
||||
// VolumesDiskUsage contains disk usage information for volumes.
|
||||
type VolumesDiskUsage struct {
|
||||
// ActiveVolumes is the number of active volumes.
|
||||
ActiveVolumes int64
|
||||
|
||||
// TotalVolumes is the total number of volumes.
|
||||
TotalVolumes int64
|
||||
|
||||
// Reclaimable is the amount of disk space that can be reclaimed.
|
||||
Reclaimable int64
|
||||
|
||||
// TotalSize is the total disk space used by all volumes.
|
||||
TotalSize int64
|
||||
|
||||
// Items holds detailed information about each volume.
|
||||
Items []volume.Volume
|
||||
}
|
||||
|
||||
// BuildCacheDiskUsage contains disk usage information for build cache.
|
||||
type BuildCacheDiskUsage struct {
|
||||
// ActiveBuildCacheRecords is the number of active build cache records.
|
||||
ActiveBuildCacheRecords int64
|
||||
|
||||
// TotalBuildCacheRecords is the total number of build cache records.
|
||||
TotalBuildCacheRecords int64
|
||||
|
||||
// Reclaimable is the amount of disk space that can be reclaimed.
|
||||
Reclaimable int64
|
||||
|
||||
// TotalSize is the total disk space used by all build cache records.
|
||||
TotalSize int64
|
||||
|
||||
// Items holds detailed information about each build cache record.
|
||||
Items []build.CacheRecord
|
||||
}
|
||||
|
||||
// DiskUsage requests the current data usage from the daemon.
|
||||
func (cli *Client) DiskUsage(ctx context.Context, options DiskUsageOptions) (DiskUsageResult, error) {
|
||||
query := url.Values{}
|
||||
|
||||
for _, t := range []struct {
|
||||
flag bool
|
||||
sysObj system.DiskUsageObject
|
||||
}{
|
||||
{options.Containers, system.ContainerObject},
|
||||
{options.Images, system.ImageObject},
|
||||
{options.Volumes, system.VolumeObject},
|
||||
{options.BuildCache, system.BuildCacheObject},
|
||||
} {
|
||||
if t.flag {
|
||||
query.Add("type", string(t.sysObj))
|
||||
}
|
||||
}
|
||||
|
||||
if options.Verbose {
|
||||
query.Set("verbose", "1")
|
||||
}
|
||||
|
||||
resp, err := cli.get(ctx, "/system/df", query, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
if err != nil {
|
||||
return system.DiskUsage{}, err
|
||||
return DiskUsageResult{}, err
|
||||
}
|
||||
|
||||
var du system.DiskUsage
|
||||
if err := json.NewDecoder(resp.Body).Decode(&du); err != nil {
|
||||
return system.DiskUsage{}, fmt.Errorf("Error retrieving disk usage: %v", err)
|
||||
return DiskUsageResult{}, fmt.Errorf("Error retrieving disk usage: %v", err)
|
||||
}
|
||||
return du, nil
|
||||
|
||||
var (
|
||||
r DiskUsageResult
|
||||
imagesFrom = []*image.Summary{}
|
||||
containersFrom = []*container.Summary{}
|
||||
volumesFrom = []*volume.Volume{}
|
||||
buildCacheFrom = []*build.CacheRecord{}
|
||||
)
|
||||
|
||||
if du.ImageUsage != nil {
|
||||
r.Images = ImagesDiskUsage{
|
||||
ActiveImages: du.ImageUsage.ActiveImages,
|
||||
Reclaimable: du.ImageUsage.Reclaimable,
|
||||
TotalImages: du.ImageUsage.TotalImages,
|
||||
TotalSize: du.ImageUsage.TotalSize,
|
||||
}
|
||||
|
||||
if options.Verbose {
|
||||
imagesFrom = du.ImageUsage.Items
|
||||
}
|
||||
} else {
|
||||
// Fallback for legacy response.
|
||||
r.Images = ImagesDiskUsage{
|
||||
TotalSize: du.LayersSize,
|
||||
}
|
||||
|
||||
if du.Images != nil && options.Verbose {
|
||||
imagesFrom = du.Images
|
||||
}
|
||||
}
|
||||
|
||||
r.Images.Items = make([]image.Summary, len(imagesFrom))
|
||||
for i, ii := range imagesFrom {
|
||||
r.Images.Items[i] = *ii
|
||||
}
|
||||
|
||||
if du.ContainerUsage != nil {
|
||||
r.Containers = ContainersDiskUsage{
|
||||
ActiveContainers: du.ContainerUsage.ActiveContainers,
|
||||
Reclaimable: du.ContainerUsage.Reclaimable,
|
||||
TotalContainers: du.ContainerUsage.TotalContainers,
|
||||
TotalSize: du.ContainerUsage.TotalSize,
|
||||
}
|
||||
|
||||
if options.Verbose {
|
||||
containersFrom = du.ContainerUsage.Items
|
||||
}
|
||||
} else if du.Containers != nil && options.Verbose {
|
||||
// Fallback for legacy response.
|
||||
containersFrom = du.Containers
|
||||
}
|
||||
|
||||
r.Containers.Items = make([]container.Summary, len(containersFrom))
|
||||
for i, c := range containersFrom {
|
||||
r.Containers.Items[i] = *c
|
||||
}
|
||||
|
||||
if du.BuildCacheUsage != nil {
|
||||
r.BuildCache = BuildCacheDiskUsage{
|
||||
ActiveBuildCacheRecords: du.BuildCacheUsage.ActiveBuildCacheRecords,
|
||||
Reclaimable: du.BuildCacheUsage.Reclaimable,
|
||||
TotalBuildCacheRecords: du.BuildCacheUsage.TotalBuildCacheRecords,
|
||||
TotalSize: du.BuildCacheUsage.TotalSize,
|
||||
}
|
||||
|
||||
if options.Verbose {
|
||||
buildCacheFrom = du.BuildCacheUsage.Items
|
||||
}
|
||||
} else if du.BuildCache != nil && options.Verbose {
|
||||
// Fallback for legacy response.
|
||||
buildCacheFrom = du.BuildCache
|
||||
}
|
||||
|
||||
r.BuildCache.Items = make([]build.CacheRecord, len(buildCacheFrom))
|
||||
for i, b := range buildCacheFrom {
|
||||
r.BuildCache.Items[i] = *b
|
||||
}
|
||||
|
||||
if du.VolumeUsage != nil {
|
||||
r.Volumes = VolumesDiskUsage{
|
||||
ActiveVolumes: du.VolumeUsage.ActiveVolumes,
|
||||
Reclaimable: du.VolumeUsage.Reclaimable,
|
||||
TotalSize: du.VolumeUsage.TotalSize,
|
||||
TotalVolumes: du.VolumeUsage.TotalVolumes,
|
||||
}
|
||||
|
||||
if options.Verbose {
|
||||
volumesFrom = du.VolumeUsage.Items
|
||||
}
|
||||
} else if du.Volumes != nil && options.Verbose {
|
||||
// Fallback for legacy response.
|
||||
volumesFrom = du.Volumes
|
||||
}
|
||||
|
||||
r.Volumes.Items = make([]volume.Volume, len(volumesFrom))
|
||||
for i, v := range volumesFrom {
|
||||
r.Volumes.Items[i] = *v
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
package client
|
||||
|
||||
import "github.com/moby/moby/api/types/system"
|
||||
|
||||
// DiskUsageOptions holds parameters for system disk usage query.
|
||||
type DiskUsageOptions struct {
|
||||
// Types specifies what object types to include in the response. If empty,
|
||||
// all object types are returned.
|
||||
Types []system.DiskUsageObject
|
||||
}
|
||||
@@ -2,10 +2,12 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/moby/moby/api/types/image"
|
||||
"github.com/moby/moby/api/types/system"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
@@ -26,13 +28,129 @@ func TestDiskUsage(t *testing.T) {
|
||||
}
|
||||
|
||||
return mockJSONResponse(http.StatusOK, nil, system.DiskUsage{
|
||||
LayersSize: int64(100),
|
||||
Images: nil,
|
||||
Containers: nil,
|
||||
Volumes: nil,
|
||||
ImageUsage: &system.ImagesDiskUsage{
|
||||
ActiveImages: 0,
|
||||
TotalImages: 0,
|
||||
Reclaimable: 0,
|
||||
TotalSize: 4096,
|
||||
Items: []*image.Summary{},
|
||||
},
|
||||
})(req)
|
||||
}))
|
||||
assert.NilError(t, err)
|
||||
_, err = client.DiskUsage(context.Background(), DiskUsageOptions{})
|
||||
|
||||
du, err := client.DiskUsage(context.Background(), DiskUsageOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, du.Images.ActiveImages, int64(0))
|
||||
assert.Equal(t, du.Images.TotalImages, int64(0))
|
||||
assert.Equal(t, du.Images.Reclaimable, int64(0))
|
||||
assert.Equal(t, du.Images.TotalSize, int64(4096))
|
||||
assert.Equal(t, len(du.Images.Items), 0)
|
||||
}
|
||||
|
||||
func TestDiskUsageWithOptions(t *testing.T) {
|
||||
const expectedURL = "/system/df"
|
||||
|
||||
tests := []struct {
|
||||
options DiskUsageOptions
|
||||
expectedQuery string
|
||||
}{
|
||||
{
|
||||
options: DiskUsageOptions{
|
||||
Containers: true,
|
||||
},
|
||||
expectedQuery: "type=container",
|
||||
},
|
||||
{
|
||||
options: DiskUsageOptions{
|
||||
Images: true,
|
||||
},
|
||||
expectedQuery: "type=image",
|
||||
},
|
||||
{
|
||||
options: DiskUsageOptions{
|
||||
Volumes: true,
|
||||
},
|
||||
expectedQuery: "type=volume",
|
||||
},
|
||||
{
|
||||
options: DiskUsageOptions{
|
||||
BuildCache: true,
|
||||
},
|
||||
expectedQuery: "type=build-cache",
|
||||
},
|
||||
{
|
||||
options: DiskUsageOptions{
|
||||
Containers: true,
|
||||
Images: true,
|
||||
},
|
||||
expectedQuery: "type=container&type=image",
|
||||
},
|
||||
{
|
||||
options: DiskUsageOptions{
|
||||
Containers: true,
|
||||
Images: true,
|
||||
Volumes: true,
|
||||
BuildCache: true,
|
||||
},
|
||||
expectedQuery: "type=container&type=image&type=volume&type=build-cache",
|
||||
},
|
||||
{
|
||||
options: DiskUsageOptions{
|
||||
Containers: true,
|
||||
Verbose: true,
|
||||
},
|
||||
expectedQuery: "type=container&verbose=1",
|
||||
},
|
||||
{
|
||||
options: DiskUsageOptions{
|
||||
Containers: true,
|
||||
Images: true,
|
||||
Volumes: true,
|
||||
BuildCache: true,
|
||||
Verbose: true,
|
||||
},
|
||||
expectedQuery: "type=container&type=image&type=volume&type=build-cache&verbose=1",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(fmt.Sprintf("options=%+v", tt.options), func(t *testing.T) {
|
||||
client, err := NewClientWithOpts(WithMockClient(func(req *http.Request) (*http.Response, error) {
|
||||
if err := assertRequestWithQuery(req, http.MethodGet, expectedURL, tt.expectedQuery); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return mockJSONResponse(http.StatusOK, nil, system.DiskUsage{})(req)
|
||||
}))
|
||||
assert.NilError(t, err)
|
||||
_, err = client.DiskUsage(t.Context(), tt.options)
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLegacyDiskUsage(t *testing.T) {
|
||||
const expectedURL = "/system/df"
|
||||
client, err := NewClientWithOpts(WithMockClient(func(req *http.Request) (*http.Response, error) {
|
||||
if err := assertRequest(req, http.MethodGet, expectedURL); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return mockJSONResponse(http.StatusOK, nil, system.DiskUsage{
|
||||
LegacyDiskUsage: system.LegacyDiskUsage{
|
||||
LayersSize: 4096,
|
||||
Images: []*image.Summary{},
|
||||
},
|
||||
})(req)
|
||||
}))
|
||||
assert.NilError(t, err)
|
||||
|
||||
du, err := client.DiskUsage(context.Background(), DiskUsageOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, du.Images.ActiveImages, int64(0))
|
||||
assert.Equal(t, du.Images.TotalImages, int64(0))
|
||||
assert.Equal(t, du.Images.Reclaimable, int64(0))
|
||||
assert.Equal(t, du.Images.TotalSize, int64(4096))
|
||||
assert.Equal(t, len(du.Images.Items), 0)
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ import (
|
||||
"github.com/moby/buildkit/util/tracing"
|
||||
"github.com/moby/locker"
|
||||
containertypes "github.com/moby/moby/api/types/container"
|
||||
imagetypes "github.com/moby/moby/api/types/image"
|
||||
networktypes "github.com/moby/moby/api/types/network"
|
||||
registrytypes "github.com/moby/moby/api/types/registry"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
@@ -134,7 +133,7 @@ type Daemon struct {
|
||||
seccompProfilePath string
|
||||
|
||||
usageContainers singleflight.Group[struct{}, *backend.ContainerDiskUsage]
|
||||
usageImages singleflight.Group[struct{}, []*imagetypes.Summary]
|
||||
usageImages singleflight.Group[struct{}, *backend.ImageDiskUsage]
|
||||
usageVolumes singleflight.Group[struct{}, *backend.VolumeDiskUsage]
|
||||
usageLayer singleflight.Group[struct{}, int64]
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/image"
|
||||
"github.com/moby/moby/v2/daemon/internal/filters"
|
||||
"github.com/moby/moby/v2/daemon/server/backend"
|
||||
"github.com/moby/moby/v2/daemon/server/imagebackend"
|
||||
@@ -15,7 +14,7 @@ import (
|
||||
|
||||
// containerDiskUsage obtains information about container data disk usage
|
||||
// and makes sure that only one calculation is performed at the same time.
|
||||
func (daemon *Daemon) containerDiskUsage(ctx context.Context) (*backend.ContainerDiskUsage, error) {
|
||||
func (daemon *Daemon) containerDiskUsage(ctx context.Context, verbose bool) (*backend.ContainerDiskUsage, error) {
|
||||
res, _, err := daemon.usageContainers.Do(ctx, struct{}{}, func(ctx context.Context) (*backend.ContainerDiskUsage, error) {
|
||||
// Retrieve container list
|
||||
containers, err := daemon.Containers(ctx, &backend.ContainerListOptions{
|
||||
@@ -38,13 +37,23 @@ func (daemon *Daemon) containerDiskUsage(ctx context.Context) (*backend.Containe
|
||||
ctr.State == container.StateRestarting
|
||||
}
|
||||
|
||||
du := &backend.ContainerDiskUsage{Items: containers}
|
||||
for _, ctr := range du.Items {
|
||||
activeCount := int64(len(containers))
|
||||
|
||||
du := &backend.ContainerDiskUsage{TotalCount: activeCount}
|
||||
for _, ctr := range containers {
|
||||
du.TotalSize += ctr.SizeRw
|
||||
if !isActive(ctr) {
|
||||
du.Reclaimable += ctr.SizeRw
|
||||
activeCount--
|
||||
}
|
||||
}
|
||||
|
||||
du.ActiveCount = activeCount
|
||||
|
||||
if verbose {
|
||||
du.Items = containers
|
||||
}
|
||||
|
||||
return du, nil
|
||||
})
|
||||
return res, err
|
||||
@@ -52,54 +61,83 @@ func (daemon *Daemon) containerDiskUsage(ctx context.Context) (*backend.Containe
|
||||
|
||||
// imageDiskUsage obtains information about image data disk usage from image service
|
||||
// and makes sure that only one calculation is performed at the same time.
|
||||
func (daemon *Daemon) imageDiskUsage(ctx context.Context) ([]*image.Summary, error) {
|
||||
imgs, _, err := daemon.usageImages.Do(ctx, struct{}{}, func(ctx context.Context) ([]*image.Summary, error) {
|
||||
func (daemon *Daemon) imageDiskUsage(ctx context.Context, verbose bool) (*backend.ImageDiskUsage, error) {
|
||||
du, _, err := daemon.usageImages.Do(ctx, struct{}{}, func(ctx context.Context) (*backend.ImageDiskUsage, error) {
|
||||
// Get all top images with extra attributes
|
||||
imgs, err := daemon.imageService.Images(ctx, imagebackend.ListOptions{
|
||||
images, err := daemon.imageService.Images(ctx, imagebackend.ListOptions{
|
||||
Filters: filters.NewArgs(),
|
||||
SharedSize: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to retrieve image list")
|
||||
}
|
||||
return imgs, nil
|
||||
|
||||
reclaimable, _, err := daemon.usageLayer.Do(ctx, struct{}{}, func(ctx context.Context) (int64, error) {
|
||||
return daemon.imageService.ImageDiskUsage(ctx)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to calculate image disk usage")
|
||||
}
|
||||
|
||||
activeCount := int64(len(images))
|
||||
|
||||
du := &backend.ImageDiskUsage{TotalCount: activeCount, TotalSize: reclaimable}
|
||||
for _, i := range images {
|
||||
if i.Containers == 0 {
|
||||
activeCount--
|
||||
if i.Size == -1 || i.SharedSize == -1 {
|
||||
continue
|
||||
}
|
||||
reclaimable -= i.Size - i.SharedSize
|
||||
}
|
||||
}
|
||||
|
||||
du.Reclaimable = reclaimable
|
||||
du.ActiveCount = activeCount
|
||||
|
||||
if verbose {
|
||||
du.Items = images
|
||||
}
|
||||
|
||||
return du, nil
|
||||
})
|
||||
|
||||
return imgs, err
|
||||
return du, err
|
||||
}
|
||||
|
||||
// localVolumesSize obtains information about volume disk usage from volumes service
|
||||
// and makes sure that only one size calculation is performed at the same time.
|
||||
func (daemon *Daemon) localVolumesSize(ctx context.Context) (*backend.VolumeDiskUsage, error) {
|
||||
func (daemon *Daemon) localVolumesSize(ctx context.Context, verbose bool) (*backend.VolumeDiskUsage, error) {
|
||||
volumes, _, err := daemon.usageVolumes.Do(ctx, struct{}{}, func(ctx context.Context) (*backend.VolumeDiskUsage, error) {
|
||||
volumes, err := daemon.volumes.LocalVolumesSize(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
du := &backend.VolumeDiskUsage{Items: volumes}
|
||||
for _, v := range du.Items {
|
||||
activeCount := int64(len(volumes))
|
||||
|
||||
du := &backend.VolumeDiskUsage{TotalCount: activeCount}
|
||||
for _, v := range volumes {
|
||||
if v.UsageData.Size != -1 {
|
||||
if v.UsageData.RefCount == 0 {
|
||||
du.Reclaimable += v.UsageData.Size
|
||||
activeCount--
|
||||
}
|
||||
du.TotalSize += v.UsageData.Size
|
||||
}
|
||||
}
|
||||
|
||||
du.ActiveCount = activeCount
|
||||
|
||||
if verbose {
|
||||
du.Items = volumes
|
||||
}
|
||||
|
||||
return du, nil
|
||||
})
|
||||
return volumes, err
|
||||
}
|
||||
|
||||
// layerDiskUsage obtains information about layer disk usage from image service
|
||||
// and makes sure that only one size calculation is performed at the same time.
|
||||
func (daemon *Daemon) layerDiskUsage(ctx context.Context) (int64, error) {
|
||||
usage, _, err := daemon.usageLayer.Do(ctx, struct{}{}, func(ctx context.Context) (usage int64, err error) {
|
||||
return daemon.imageService.ImageDiskUsage(ctx)
|
||||
})
|
||||
return usage, err
|
||||
}
|
||||
|
||||
// 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 backend.DiskUsageOptions) (*backend.DiskUsage, error) {
|
||||
@@ -108,29 +146,21 @@ func (daemon *Daemon) SystemDiskUsage(ctx context.Context, opts backend.DiskUsag
|
||||
du := &backend.DiskUsage{}
|
||||
if opts.Containers {
|
||||
eg.Go(func() (err error) {
|
||||
du.Containers, err = daemon.containerDiskUsage(ctx)
|
||||
du.Containers, err = daemon.containerDiskUsage(ctx, opts.Verbose)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
var (
|
||||
layersSize int64
|
||||
images []*image.Summary
|
||||
)
|
||||
if opts.Images {
|
||||
eg.Go(func() (err error) {
|
||||
images, err = daemon.imageDiskUsage(ctx)
|
||||
return err
|
||||
})
|
||||
eg.Go(func() (err error) {
|
||||
layersSize, err = daemon.layerDiskUsage(ctx)
|
||||
du.Images, err = daemon.imageDiskUsage(ctx, opts.Verbose)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
if opts.Volumes {
|
||||
eg.Go(func() (err error) {
|
||||
du.Volumes, err = daemon.localVolumesSize(ctx)
|
||||
du.Volumes, err = daemon.localVolumesSize(ctx, opts.Verbose)
|
||||
return err
|
||||
})
|
||||
}
|
||||
@@ -139,22 +169,5 @@ func (daemon *Daemon) SystemDiskUsage(ctx context.Context, opts backend.DiskUsag
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if opts.Images {
|
||||
reclaimable := layersSize
|
||||
for _, i := range images {
|
||||
if i.Containers != 0 {
|
||||
if i.Size == -1 || i.SharedSize == -1 {
|
||||
continue
|
||||
}
|
||||
reclaimable -= i.Size - i.SharedSize
|
||||
}
|
||||
}
|
||||
|
||||
du.Images = &backend.ImageDiskUsage{
|
||||
TotalSize: layersSize,
|
||||
Reclaimable: reclaimable,
|
||||
Items: images,
|
||||
}
|
||||
}
|
||||
return du, nil
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@ type DiskUsageOptions struct {
|
||||
|
||||
// Volumes controls whether volume disk usage should be computed.
|
||||
Volumes bool
|
||||
|
||||
// Verbose indicates whether to include detailed information.
|
||||
Verbose bool
|
||||
}
|
||||
|
||||
// DiskUsage contains the information returned by the backend for the
|
||||
@@ -30,6 +33,8 @@ type DiskUsage struct {
|
||||
|
||||
// BuildCacheDiskUsage contains disk usage for the build cache.
|
||||
type BuildCacheDiskUsage struct {
|
||||
ActiveCount int64
|
||||
TotalCount int64
|
||||
TotalSize int64
|
||||
Reclaimable int64
|
||||
Items []*build.CacheRecord
|
||||
@@ -37,6 +42,8 @@ type BuildCacheDiskUsage struct {
|
||||
|
||||
// ContainerDiskUsage contains disk usage for containers.
|
||||
type ContainerDiskUsage struct {
|
||||
ActiveCount int64
|
||||
TotalCount int64
|
||||
TotalSize int64
|
||||
Reclaimable int64
|
||||
Items []*container.Summary
|
||||
@@ -44,6 +51,8 @@ type ContainerDiskUsage struct {
|
||||
|
||||
// ImageDiskUsage contains disk usage for images.
|
||||
type ImageDiskUsage struct {
|
||||
ActiveCount int64
|
||||
TotalCount int64
|
||||
TotalSize int64
|
||||
Reclaimable int64
|
||||
Items []*image.Summary
|
||||
@@ -51,6 +60,8 @@ type ImageDiskUsage struct {
|
||||
|
||||
// VolumeDiskUsage contains disk usage for volumes.
|
||||
type VolumeDiskUsage struct {
|
||||
ActiveCount int64
|
||||
TotalCount int64
|
||||
TotalSize int64
|
||||
Reclaimable int64
|
||||
Items []*volume.Volume
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/log"
|
||||
@@ -161,6 +162,21 @@ func (s *systemRouter) getDiskUsage(ctx context.Context, w http.ResponseWriter,
|
||||
}
|
||||
}
|
||||
|
||||
// To maintain backwards compatibility with older clients, when communicating with API versions prior to 1.52,
|
||||
// verbose mode is always enabled. For API 1.52 and onwards, if the "verbose" query parameter is not set,
|
||||
// assume legacy fields should be included.
|
||||
var verbose, legacyFields bool
|
||||
if v := r.Form.Get("verbose"); versions.GreaterThanOrEqualTo(version, "1.52") && v != "" {
|
||||
var err error
|
||||
verbose, err = strconv.ParseBool(v)
|
||||
if err != nil {
|
||||
return invalidRequestError{Err: fmt.Errorf("invalid value for verbose: %s", v)}
|
||||
}
|
||||
} else {
|
||||
// In versions prior to 1.52, legacy fields were always included.
|
||||
legacyFields, verbose = true, true
|
||||
}
|
||||
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
var systemDiskUsage *backend.DiskUsage
|
||||
@@ -171,6 +187,7 @@ func (s *systemRouter) getDiskUsage(ctx context.Context, w http.ResponseWriter,
|
||||
Containers: getContainers,
|
||||
Images: getImages,
|
||||
Volumes: getVolumes,
|
||||
Verbose: verbose,
|
||||
})
|
||||
return err
|
||||
})
|
||||
@@ -197,40 +214,80 @@ func (s *systemRouter) getDiskUsage(ctx context.Context, w http.ResponseWriter,
|
||||
return err
|
||||
}
|
||||
|
||||
var builderSize int64
|
||||
if versions.LessThan(version, "1.42") {
|
||||
for _, b := range buildCache {
|
||||
builderSize += b.Size
|
||||
}
|
||||
}
|
||||
|
||||
du := backend.DiskUsage{}
|
||||
if getBuildCache {
|
||||
du.BuildCache = &backend.BuildCacheDiskUsage{
|
||||
TotalSize: builderSize,
|
||||
Items: buildCache,
|
||||
}
|
||||
}
|
||||
if systemDiskUsage != nil {
|
||||
du.Images = systemDiskUsage.Images
|
||||
du.Containers = systemDiskUsage.Containers
|
||||
du.Volumes = systemDiskUsage.Volumes
|
||||
}
|
||||
|
||||
// Use the old struct for the API return value.
|
||||
var v system.DiskUsage
|
||||
if du.Images != nil {
|
||||
v.LayersSize = du.Images.TotalSize
|
||||
v.Images = du.Images.Items
|
||||
if systemDiskUsage != nil && systemDiskUsage.Images != nil {
|
||||
v.ImageUsage = &system.ImagesDiskUsage{
|
||||
ActiveImages: systemDiskUsage.Images.ActiveCount,
|
||||
Reclaimable: systemDiskUsage.Images.Reclaimable,
|
||||
TotalImages: systemDiskUsage.Images.TotalCount,
|
||||
TotalSize: systemDiskUsage.Images.TotalSize,
|
||||
}
|
||||
|
||||
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.
|
||||
} else if verbose {
|
||||
v.ImageUsage.Items = systemDiskUsage.Images.Items
|
||||
}
|
||||
}
|
||||
if du.Containers != nil {
|
||||
v.Containers = du.Containers.Items
|
||||
if systemDiskUsage != nil && systemDiskUsage.Containers != nil {
|
||||
v.ContainerUsage = &system.ContainersDiskUsage{
|
||||
ActiveContainers: systemDiskUsage.Containers.ActiveCount,
|
||||
Reclaimable: systemDiskUsage.Containers.Reclaimable,
|
||||
TotalContainers: systemDiskUsage.Containers.TotalCount,
|
||||
TotalSize: systemDiskUsage.Containers.TotalSize,
|
||||
}
|
||||
|
||||
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.
|
||||
} else if verbose {
|
||||
v.ContainerUsage.Items = systemDiskUsage.Containers.Items
|
||||
}
|
||||
}
|
||||
if du.Volumes != nil {
|
||||
v.Volumes = du.Volumes.Items
|
||||
if systemDiskUsage != nil && systemDiskUsage.Volumes != nil {
|
||||
v.VolumeUsage = &system.VolumesDiskUsage{
|
||||
ActiveVolumes: systemDiskUsage.Volumes.ActiveCount,
|
||||
TotalSize: systemDiskUsage.Volumes.TotalSize,
|
||||
Reclaimable: systemDiskUsage.Volumes.Reclaimable,
|
||||
TotalVolumes: systemDiskUsage.Volumes.TotalCount,
|
||||
}
|
||||
|
||||
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.
|
||||
} else if verbose {
|
||||
v.VolumeUsage.Items = systemDiskUsage.Volumes.Items
|
||||
}
|
||||
}
|
||||
if du.BuildCache != nil {
|
||||
v.BuildCache = du.BuildCache.Items
|
||||
if getBuildCache {
|
||||
v.BuildCacheUsage = &system.BuildCacheDiskUsage{
|
||||
TotalBuildCacheRecords: int64(len(buildCache)),
|
||||
}
|
||||
|
||||
activeCount := v.BuildCacheUsage.TotalBuildCacheRecords
|
||||
var totalSize, reclaimable int64
|
||||
|
||||
for _, b := range buildCache {
|
||||
if versions.LessThan(version, "1.42") {
|
||||
totalSize += b.Size
|
||||
}
|
||||
|
||||
if !b.InUse {
|
||||
activeCount--
|
||||
}
|
||||
if !b.InUse && !b.Shared {
|
||||
reclaimable += b.Size
|
||||
}
|
||||
}
|
||||
|
||||
v.BuildCacheUsage.ActiveBuildCacheRecords = activeCount
|
||||
v.BuildCacheUsage.TotalSize = totalSize
|
||||
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.
|
||||
} else if verbose {
|
||||
v.BuildCacheUsage.Items = buildCache
|
||||
}
|
||||
}
|
||||
return httputils.WriteJSON(w, http.StatusOK, v)
|
||||
}
|
||||
|
||||
@@ -95,6 +95,13 @@ generate_model types/storage <<- 'EOT'
|
||||
Storage
|
||||
EOT
|
||||
|
||||
generate_model types/system <<- 'EOT'
|
||||
BuildCacheDiskUsage
|
||||
ContainersDiskUsage
|
||||
ImagesDiskUsage
|
||||
VolumesDiskUsage
|
||||
EOT
|
||||
|
||||
generate_model types/swarm <<- 'EOT'
|
||||
ServiceCreateResponse
|
||||
ServiceUpdateResponse
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"github.com/moby/moby/api/types/build"
|
||||
containertypes "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"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/moby/moby/v2/integration/internal/container"
|
||||
@@ -30,78 +29,110 @@ func TestDiskUsage(t *testing.T) {
|
||||
defer d.Stop(t)
|
||||
apiClient := d.NewClientT(t)
|
||||
|
||||
var stepDU system.DiskUsage
|
||||
var stepDU client.DiskUsageResult
|
||||
for _, step := range []struct {
|
||||
doc string
|
||||
next func(t *testing.T, prev system.DiskUsage) system.DiskUsage
|
||||
next func(t *testing.T, prev client.DiskUsageResult) client.DiskUsageResult
|
||||
}{
|
||||
{
|
||||
doc: "empty",
|
||||
next: func(t *testing.T, _ system.DiskUsage) system.DiskUsage {
|
||||
du, err := apiClient.DiskUsage(ctx, client.DiskUsageOptions{})
|
||||
next: func(t *testing.T, _ client.DiskUsageResult) client.DiskUsageResult {
|
||||
du, err := apiClient.DiskUsage(ctx, client.DiskUsageOptions{
|
||||
Images: true,
|
||||
Containers: true,
|
||||
BuildCache: true,
|
||||
Volumes: true,
|
||||
Verbose: true,
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
|
||||
expectedLayersSize := int64(0)
|
||||
// TODO: Investigate https://github.com/moby/moby/issues/47119
|
||||
// Make 4096 (block size) also a valid value for zero usage.
|
||||
if testEnv.UsingSnapshotter() && testEnv.IsRootless() {
|
||||
if du.LayersSize == 4096 {
|
||||
expectedLayersSize = du.LayersSize
|
||||
if du.Images.TotalSize == 4096 {
|
||||
expectedLayersSize = 4096
|
||||
}
|
||||
}
|
||||
|
||||
assert.DeepEqual(t, du, system.DiskUsage{
|
||||
LayersSize: expectedLayersSize,
|
||||
Images: []*image.Summary{},
|
||||
Containers: []*containertypes.Summary{},
|
||||
Volumes: []*volume.Volume{},
|
||||
BuildCache: []*build.CacheRecord{},
|
||||
assert.DeepEqual(t, du, client.DiskUsageResult{
|
||||
Containers: client.ContainersDiskUsage{
|
||||
Items: []containertypes.Summary{},
|
||||
},
|
||||
Images: client.ImagesDiskUsage{
|
||||
TotalSize: expectedLayersSize,
|
||||
Items: []image.Summary{},
|
||||
},
|
||||
BuildCache: client.BuildCacheDiskUsage{
|
||||
Items: []build.CacheRecord{},
|
||||
},
|
||||
Volumes: client.VolumesDiskUsage{
|
||||
Items: []volume.Volume{},
|
||||
},
|
||||
})
|
||||
return du
|
||||
},
|
||||
},
|
||||
{
|
||||
doc: "after LoadBusybox",
|
||||
next: func(t *testing.T, _ system.DiskUsage) system.DiskUsage {
|
||||
next: func(t *testing.T, _ client.DiskUsageResult) client.DiskUsageResult {
|
||||
d.LoadBusybox(ctx, t)
|
||||
|
||||
du, err := apiClient.DiskUsage(ctx, client.DiskUsageOptions{})
|
||||
du, err := apiClient.DiskUsage(ctx, client.DiskUsageOptions{
|
||||
Images: true,
|
||||
Containers: true,
|
||||
BuildCache: true,
|
||||
Volumes: true,
|
||||
Verbose: true,
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, du.LayersSize > 0)
|
||||
assert.Equal(t, len(du.Images), 1)
|
||||
assert.Equal(t, len(du.Images[0].RepoTags), 1)
|
||||
assert.Check(t, is.Equal(du.Images[0].RepoTags[0], "busybox:latest"))
|
||||
|
||||
assert.Assert(t, du.Images.TotalSize > 0)
|
||||
assert.Equal(t, len(du.Images.Items), 1)
|
||||
assert.Equal(t, len(du.Images.Items[0].RepoTags), 1)
|
||||
assert.Check(t, is.Equal(du.Images.Items[0].RepoTags[0], "busybox:latest"))
|
||||
|
||||
// Image size is layer size + content size. Content size is included in layers size.
|
||||
assert.Equal(t, du.Images[0].Size, du.LayersSize)
|
||||
assert.Equal(t, du.Images.Items[0].Size, du.Images.TotalSize)
|
||||
|
||||
return du
|
||||
},
|
||||
},
|
||||
{
|
||||
doc: "after container.Run",
|
||||
next: func(t *testing.T, prev system.DiskUsage) system.DiskUsage {
|
||||
next: func(t *testing.T, prev client.DiskUsageResult) client.DiskUsageResult {
|
||||
cID := container.Run(ctx, t, apiClient)
|
||||
|
||||
du, err := apiClient.DiskUsage(ctx, client.DiskUsageOptions{})
|
||||
du, err := apiClient.DiskUsage(ctx, client.DiskUsageOptions{
|
||||
Images: true,
|
||||
Containers: true,
|
||||
BuildCache: true,
|
||||
Volumes: true,
|
||||
Verbose: true,
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, len(du.Containers), 1)
|
||||
assert.Equal(t, len(du.Containers[0].Names), 1)
|
||||
assert.Assert(t, len(prev.Images) > 0)
|
||||
assert.Check(t, du.Containers[0].Created >= prev.Images[0].Created)
|
||||
|
||||
assert.Equal(t, du.Containers.ActiveContainers, int64(1))
|
||||
assert.Equal(t, du.Containers.TotalContainers, int64(1))
|
||||
assert.Equal(t, len(du.Containers.Items), 1)
|
||||
assert.Equal(t, len(du.Containers.Items[0].Names), 1)
|
||||
assert.Assert(t, len(prev.Images.Items) > 0)
|
||||
assert.Check(t, du.Containers.Items[0].Created >= prev.Images.Items[0].Created)
|
||||
|
||||
// Additional container layer could add to the size
|
||||
assert.Check(t, du.LayersSize >= prev.LayersSize)
|
||||
assert.Check(t, du.Images.TotalSize >= prev.Images.TotalSize)
|
||||
|
||||
assert.Equal(t, len(du.Images), 1)
|
||||
assert.Equal(t, du.Images[0].Containers, prev.Images[0].Containers+1)
|
||||
assert.Equal(t, du.Images.ActiveImages, int64(1))
|
||||
assert.Equal(t, du.Images.TotalImages, int64(1))
|
||||
assert.Equal(t, len(du.Images.Items), 1)
|
||||
assert.Equal(t, du.Images.Items[0].Containers, prev.Images.Items[0].Containers+1)
|
||||
|
||||
assert.Check(t, is.Equal(du.Containers[0].ID, cID))
|
||||
assert.Check(t, is.Equal(du.Containers[0].Image, "busybox"))
|
||||
assert.Check(t, is.Equal(du.Containers[0].ImageID, prev.Images[0].ID))
|
||||
assert.Check(t, is.Equal(du.Containers.Items[0].ID, cID))
|
||||
assert.Check(t, is.Equal(du.Containers.Items[0].Image, "busybox"))
|
||||
assert.Check(t, is.Equal(du.Containers.Items[0].ImageID, prev.Images.Items[0].ID))
|
||||
|
||||
// ImageManifestDescriptor should NOT be populated.
|
||||
assert.Check(t, is.Nil(du.Containers[0].ImageManifestDescriptor))
|
||||
assert.Check(t, is.Nil(du.Containers.Items[0].ImageManifestDescriptor))
|
||||
|
||||
return du
|
||||
},
|
||||
@@ -114,143 +145,153 @@ func TestDiskUsage(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
doc string
|
||||
options client.DiskUsageOptions
|
||||
expected system.DiskUsage
|
||||
expected client.DiskUsageResult
|
||||
}{
|
||||
{
|
||||
doc: "container types",
|
||||
options: client.DiskUsageOptions{
|
||||
Types: []system.DiskUsageObject{
|
||||
system.ContainerObject,
|
||||
},
|
||||
Containers: true,
|
||||
Verbose: true,
|
||||
},
|
||||
expected: system.DiskUsage{
|
||||
expected: client.DiskUsageResult{
|
||||
Containers: stepDU.Containers,
|
||||
Images: client.ImagesDiskUsage{Items: []image.Summary{}},
|
||||
BuildCache: client.BuildCacheDiskUsage{Items: []build.CacheRecord{}},
|
||||
Volumes: client.VolumesDiskUsage{Items: []volume.Volume{}},
|
||||
},
|
||||
},
|
||||
{
|
||||
doc: "image types",
|
||||
options: client.DiskUsageOptions{
|
||||
Types: []system.DiskUsageObject{
|
||||
system.ImageObject,
|
||||
},
|
||||
Images: true,
|
||||
Verbose: true,
|
||||
},
|
||||
expected: system.DiskUsage{
|
||||
LayersSize: stepDU.LayersSize,
|
||||
expected: client.DiskUsageResult{
|
||||
Containers: client.ContainersDiskUsage{Items: []containertypes.Summary{}},
|
||||
Images: stepDU.Images,
|
||||
BuildCache: client.BuildCacheDiskUsage{Items: []build.CacheRecord{}},
|
||||
Volumes: client.VolumesDiskUsage{Items: []volume.Volume{}},
|
||||
},
|
||||
},
|
||||
{
|
||||
doc: "volume types",
|
||||
options: client.DiskUsageOptions{
|
||||
Types: []system.DiskUsageObject{
|
||||
system.VolumeObject,
|
||||
},
|
||||
Volumes: true,
|
||||
Verbose: true,
|
||||
},
|
||||
expected: system.DiskUsage{
|
||||
Volumes: stepDU.Volumes,
|
||||
expected: client.DiskUsageResult{
|
||||
Containers: client.ContainersDiskUsage{Items: []containertypes.Summary{}},
|
||||
Images: client.ImagesDiskUsage{Items: []image.Summary{}},
|
||||
BuildCache: client.BuildCacheDiskUsage{Items: []build.CacheRecord{}},
|
||||
Volumes: stepDU.Volumes,
|
||||
},
|
||||
},
|
||||
{
|
||||
doc: "build-cache types",
|
||||
options: client.DiskUsageOptions{
|
||||
Types: []system.DiskUsageObject{
|
||||
system.BuildCacheObject,
|
||||
},
|
||||
BuildCache: true,
|
||||
Verbose: true,
|
||||
},
|
||||
expected: system.DiskUsage{
|
||||
expected: client.DiskUsageResult{
|
||||
Containers: client.ContainersDiskUsage{Items: []containertypes.Summary{}},
|
||||
Images: client.ImagesDiskUsage{Items: []image.Summary{}},
|
||||
BuildCache: stepDU.BuildCache,
|
||||
Volumes: client.VolumesDiskUsage{Items: []volume.Volume{}},
|
||||
},
|
||||
},
|
||||
{
|
||||
doc: "container, volume types",
|
||||
options: client.DiskUsageOptions{
|
||||
Types: []system.DiskUsageObject{
|
||||
system.ContainerObject,
|
||||
system.VolumeObject,
|
||||
},
|
||||
Containers: true,
|
||||
Volumes: true,
|
||||
Verbose: true,
|
||||
},
|
||||
expected: system.DiskUsage{
|
||||
expected: client.DiskUsageResult{
|
||||
Containers: stepDU.Containers,
|
||||
Images: client.ImagesDiskUsage{Items: []image.Summary{}},
|
||||
BuildCache: client.BuildCacheDiskUsage{Items: []build.CacheRecord{}},
|
||||
Volumes: stepDU.Volumes,
|
||||
},
|
||||
},
|
||||
{
|
||||
doc: "image, build-cache types",
|
||||
options: client.DiskUsageOptions{
|
||||
Types: []system.DiskUsageObject{
|
||||
system.ImageObject,
|
||||
system.BuildCacheObject,
|
||||
},
|
||||
Images: true,
|
||||
BuildCache: true,
|
||||
Verbose: true,
|
||||
},
|
||||
expected: system.DiskUsage{
|
||||
LayersSize: stepDU.LayersSize,
|
||||
expected: client.DiskUsageResult{
|
||||
Containers: client.ContainersDiskUsage{Items: []containertypes.Summary{}},
|
||||
Images: stepDU.Images,
|
||||
BuildCache: stepDU.BuildCache,
|
||||
Volumes: client.VolumesDiskUsage{Items: []volume.Volume{}},
|
||||
},
|
||||
},
|
||||
{
|
||||
doc: "container, volume, build-cache types",
|
||||
options: client.DiskUsageOptions{
|
||||
Types: []system.DiskUsageObject{
|
||||
system.ContainerObject,
|
||||
system.VolumeObject,
|
||||
system.BuildCacheObject,
|
||||
},
|
||||
Containers: true,
|
||||
BuildCache: true,
|
||||
Volumes: true,
|
||||
Verbose: true,
|
||||
},
|
||||
expected: system.DiskUsage{
|
||||
expected: client.DiskUsageResult{
|
||||
Containers: stepDU.Containers,
|
||||
Volumes: stepDU.Volumes,
|
||||
Images: client.ImagesDiskUsage{
|
||||
Items: []image.Summary{},
|
||||
},
|
||||
BuildCache: stepDU.BuildCache,
|
||||
Volumes: stepDU.Volumes,
|
||||
},
|
||||
},
|
||||
{
|
||||
doc: "image, volume, build-cache types",
|
||||
options: client.DiskUsageOptions{
|
||||
Types: []system.DiskUsageObject{
|
||||
system.ImageObject,
|
||||
system.VolumeObject,
|
||||
system.BuildCacheObject,
|
||||
},
|
||||
Images: true,
|
||||
BuildCache: true,
|
||||
Volumes: true,
|
||||
Verbose: true,
|
||||
},
|
||||
expected: system.DiskUsage{
|
||||
LayersSize: stepDU.LayersSize,
|
||||
expected: client.DiskUsageResult{
|
||||
Containers: client.ContainersDiskUsage{
|
||||
Items: []containertypes.Summary{},
|
||||
},
|
||||
Images: stepDU.Images,
|
||||
Volumes: stepDU.Volumes,
|
||||
BuildCache: stepDU.BuildCache,
|
||||
Volumes: stepDU.Volumes,
|
||||
},
|
||||
},
|
||||
{
|
||||
doc: "container, image, volume types",
|
||||
options: client.DiskUsageOptions{
|
||||
Types: []system.DiskUsageObject{
|
||||
system.ContainerObject,
|
||||
system.ImageObject,
|
||||
system.VolumeObject,
|
||||
},
|
||||
Containers: true,
|
||||
Images: true,
|
||||
Volumes: true,
|
||||
Verbose: true,
|
||||
},
|
||||
expected: system.DiskUsage{
|
||||
LayersSize: stepDU.LayersSize,
|
||||
expected: client.DiskUsageResult{
|
||||
Containers: stepDU.Containers,
|
||||
Images: stepDU.Images,
|
||||
Volumes: stepDU.Volumes,
|
||||
BuildCache: client.BuildCacheDiskUsage{
|
||||
Items: []build.CacheRecord{},
|
||||
},
|
||||
Volumes: stepDU.Volumes,
|
||||
},
|
||||
},
|
||||
{
|
||||
doc: "container, image, volume, build-cache types",
|
||||
options: client.DiskUsageOptions{
|
||||
Types: []system.DiskUsageObject{
|
||||
system.ContainerObject,
|
||||
system.ImageObject,
|
||||
system.VolumeObject,
|
||||
system.BuildCacheObject,
|
||||
},
|
||||
Containers: true,
|
||||
Images: true,
|
||||
BuildCache: true,
|
||||
Volumes: true,
|
||||
Verbose: true,
|
||||
},
|
||||
expected: system.DiskUsage{
|
||||
LayersSize: stepDU.LayersSize,
|
||||
expected: client.DiskUsageResult{
|
||||
Containers: stepDU.Containers,
|
||||
Images: stepDU.Images,
|
||||
Volumes: stepDU.Volumes,
|
||||
BuildCache: stepDU.BuildCache,
|
||||
Volumes: stepDU.Volumes,
|
||||
},
|
||||
},
|
||||
} {
|
||||
|
||||
40
vendor/github.com/moby/moby/api/types/system/build_cache_disk_usage.go
generated
vendored
Normal file
40
vendor/github.com/moby/moby/api/types/system/build_cache_disk_usage.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package system
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"github.com/moby/moby/api/types/build"
|
||||
)
|
||||
|
||||
// BuildCacheDiskUsage BuildCacheDiskUsage represents system data usage for build cache resources.
|
||||
//
|
||||
// swagger:model BuildCacheDiskUsage
|
||||
type BuildCacheDiskUsage struct {
|
||||
|
||||
// Count of active build cache records.
|
||||
//
|
||||
// Example: 1
|
||||
ActiveBuildCacheRecords int64 `json:"ActiveBuildCacheRecords,omitempty"`
|
||||
|
||||
// List of build cache records.
|
||||
//
|
||||
Items []*build.CacheRecord `json:"Items,omitempty"`
|
||||
|
||||
// Disk space that can be reclaimed by removing inactive build cache records.
|
||||
//
|
||||
// Example: 12345678
|
||||
Reclaimable int64 `json:"Reclaimable,omitempty"`
|
||||
|
||||
// Count of all build cache records.
|
||||
//
|
||||
// Example: 4
|
||||
TotalBuildCacheRecords int64 `json:"TotalBuildCacheRecords,omitempty"`
|
||||
|
||||
// Disk space in use by build cache records.
|
||||
//
|
||||
// Example: 98765432
|
||||
TotalSize int64 `json:"TotalSize,omitempty"`
|
||||
}
|
||||
40
vendor/github.com/moby/moby/api/types/system/containers_disk_usage.go
generated
vendored
Normal file
40
vendor/github.com/moby/moby/api/types/system/containers_disk_usage.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package system
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"github.com/moby/moby/api/types/container"
|
||||
)
|
||||
|
||||
// ContainersDiskUsage ContainersDiskUsage provides system data usage information for container resources.
|
||||
//
|
||||
// swagger:model ContainersDiskUsage
|
||||
type ContainersDiskUsage struct {
|
||||
|
||||
// Count of active containers.
|
||||
//
|
||||
// Example: 1
|
||||
ActiveContainers int64 `json:"ActiveContainers,omitempty"`
|
||||
|
||||
// List of container summaries.
|
||||
//
|
||||
Items []*container.Summary `json:"Items,omitempty"`
|
||||
|
||||
// Disk space that can be reclaimed by removing inactive containers.
|
||||
//
|
||||
// Example: 12345678
|
||||
Reclaimable int64 `json:"Reclaimable,omitempty"`
|
||||
|
||||
// Count of all containers.
|
||||
//
|
||||
// Example: 4
|
||||
TotalContainers int64 `json:"TotalContainers,omitempty"`
|
||||
|
||||
// Disk space in use by containers.
|
||||
//
|
||||
// Example: 98765432
|
||||
TotalSize int64 `json:"TotalSize,omitempty"`
|
||||
}
|
||||
28
vendor/github.com/moby/moby/api/types/system/disk_usage.go
generated
vendored
28
vendor/github.com/moby/moby/api/types/system/disk_usage.go
generated
vendored
@@ -24,9 +24,27 @@ const (
|
||||
// DiskUsage contains response of Engine API:
|
||||
// GET "/system/df"
|
||||
type DiskUsage struct {
|
||||
LayersSize int64
|
||||
Images []*image.Summary
|
||||
Containers []*container.Summary
|
||||
Volumes []*volume.Volume
|
||||
BuildCache []*build.CacheRecord
|
||||
LegacyDiskUsage
|
||||
|
||||
ImageUsage *ImagesDiskUsage `json:"ImageUsage,omitempty"`
|
||||
ContainerUsage *ContainersDiskUsage `json:"ContainerUsage,omitempty"`
|
||||
VolumeUsage *VolumesDiskUsage `json:"VolumeUsage,omitempty"`
|
||||
BuildCacheUsage *BuildCacheDiskUsage `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,omitempty"`
|
||||
|
||||
// Deprecated: kept to maintain backwards compatibility with API < v1.52, use [ContainersDiskUsage.Items] instead.
|
||||
Containers []*container.Summary `json:"Containers,omitempty"`
|
||||
|
||||
// Deprecated: kept to maintain backwards compatibility with API < v1.52, use [VolumesDiskUsage.Items] instead.
|
||||
Volumes []*volume.Volume `json:"Volumes,omitempty"`
|
||||
|
||||
// Deprecated: kept to maintain backwards compatibility with API < v1.52, use [BuildCacheDiskUsage.Items] instead.
|
||||
BuildCache []*build.CacheRecord `json:"BuildCache,omitempty"`
|
||||
}
|
||||
|
||||
40
vendor/github.com/moby/moby/api/types/system/images_disk_usage.go
generated
vendored
Normal file
40
vendor/github.com/moby/moby/api/types/system/images_disk_usage.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package system
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"github.com/moby/moby/api/types/image"
|
||||
)
|
||||
|
||||
// ImagesDiskUsage ImagesDiskUsage represents system data usage for image resources.
|
||||
//
|
||||
// swagger:model ImagesDiskUsage
|
||||
type ImagesDiskUsage struct {
|
||||
|
||||
// Count of active images.
|
||||
//
|
||||
// Example: 1
|
||||
ActiveImages int64 `json:"ActiveImages,omitempty"`
|
||||
|
||||
// List of image summaries.
|
||||
//
|
||||
Items []*image.Summary `json:"Items,omitempty"`
|
||||
|
||||
// Disk space that can be reclaimed by removing unused images.
|
||||
//
|
||||
// Example: 12345678
|
||||
Reclaimable int64 `json:"Reclaimable,omitempty"`
|
||||
|
||||
// Count of all images.
|
||||
//
|
||||
// Example: 4
|
||||
TotalImages int64 `json:"TotalImages,omitempty"`
|
||||
|
||||
// Disk space in use by images.
|
||||
//
|
||||
// Example: 98765432
|
||||
TotalSize int64 `json:"TotalSize,omitempty"`
|
||||
}
|
||||
40
vendor/github.com/moby/moby/api/types/system/volumes_disk_usage.go
generated
vendored
Normal file
40
vendor/github.com/moby/moby/api/types/system/volumes_disk_usage.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package system
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"github.com/moby/moby/api/types/volume"
|
||||
)
|
||||
|
||||
// VolumesDiskUsage VolumesDiskUsage represents system data usage for volume resources.
|
||||
//
|
||||
// swagger:model VolumesDiskUsage
|
||||
type VolumesDiskUsage struct {
|
||||
|
||||
// Count of active volumes.
|
||||
//
|
||||
// Example: 1
|
||||
ActiveVolumes int64 `json:"ActiveVolumes,omitempty"`
|
||||
|
||||
// List of volumes.
|
||||
//
|
||||
Items []*volume.Volume `json:"Items,omitempty"`
|
||||
|
||||
// Disk space that can be reclaimed by removing inactive volumes.
|
||||
//
|
||||
// Example: 12345678
|
||||
Reclaimable int64 `json:"Reclaimable,omitempty"`
|
||||
|
||||
// Disk space in use by volumes.
|
||||
//
|
||||
// Example: 98765432
|
||||
TotalSize int64 `json:"TotalSize,omitempty"`
|
||||
|
||||
// Count of all volumes.
|
||||
//
|
||||
// Example: 4
|
||||
TotalVolumes int64 `json:"TotalVolumes,omitempty"`
|
||||
}
|
||||
4
vendor/github.com/moby/moby/client/client_interfaces.go
generated
vendored
4
vendor/github.com/moby/moby/client/client_interfaces.go
generated
vendored
@@ -4,8 +4,6 @@ import (
|
||||
"context"
|
||||
"io"
|
||||
"net"
|
||||
|
||||
"github.com/moby/moby/api/types/system"
|
||||
)
|
||||
|
||||
// APIClient is an interface that clients that talk with a docker server must implement.
|
||||
@@ -173,7 +171,7 @@ type SystemAPIClient interface {
|
||||
Events(ctx context.Context, options EventsListOptions) EventsResult
|
||||
Info(ctx context.Context, options InfoOptions) (SystemInfoResult, error)
|
||||
RegistryLogin(ctx context.Context, auth RegistryLoginOptions) (RegistryLoginResult, error)
|
||||
DiskUsage(ctx context.Context, options DiskUsageOptions) (system.DiskUsage, error)
|
||||
DiskUsage(ctx context.Context, options DiskUsageOptions) (DiskUsageResult, error)
|
||||
Ping(ctx context.Context, options PingOptions) (PingResult, error)
|
||||
}
|
||||
|
||||
|
||||
240
vendor/github.com/moby/moby/client/system_disk_usage.go
generated
vendored
240
vendor/github.com/moby/moby/client/system_disk_usage.go
generated
vendored
@@ -6,28 +6,248 @@ import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
// DiskUsage requests the current data usage from the daemon
|
||||
func (cli *Client) DiskUsage(ctx context.Context, options DiskUsageOptions) (system.DiskUsage, error) {
|
||||
var query url.Values
|
||||
if len(options.Types) > 0 {
|
||||
query = url.Values{}
|
||||
for _, t := range options.Types {
|
||||
query.Add("type", string(t))
|
||||
// DiskUsageOptions holds parameters for [Client.DiskUsage] operations.
|
||||
type DiskUsageOptions struct {
|
||||
// Containers controls whether container disk usage should be computed.
|
||||
Containers bool
|
||||
|
||||
// Images controls whether image disk usage should be computed.
|
||||
Images bool
|
||||
|
||||
// BuildCache controls whether build cache disk usage should be computed.
|
||||
BuildCache bool
|
||||
|
||||
// Volumes controls whether volume disk usage should be computed.
|
||||
Volumes bool
|
||||
|
||||
// Verbose enables more detailed disk usage information.
|
||||
Verbose bool
|
||||
}
|
||||
|
||||
// DiskUsageResult is the result of [Client.DiskUsage] operations.
|
||||
type DiskUsageResult struct {
|
||||
// Containers holds container disk usage information.
|
||||
Containers ContainersDiskUsage
|
||||
|
||||
// Images holds image disk usage information.
|
||||
Images ImagesDiskUsage
|
||||
|
||||
// BuildCache holds build cache disk usage information.
|
||||
BuildCache BuildCacheDiskUsage
|
||||
|
||||
// Volumes holds volume disk usage information.
|
||||
Volumes VolumesDiskUsage
|
||||
}
|
||||
|
||||
// ContainersDiskUsage contains disk usage information for containers.
|
||||
type ContainersDiskUsage struct {
|
||||
// ActiveContainers is the number of active containers.
|
||||
ActiveContainers int64
|
||||
|
||||
// TotalContainers is the total number of containers.
|
||||
TotalContainers int64
|
||||
|
||||
// Reclaimable is the amount of disk space that can be reclaimed.
|
||||
Reclaimable int64
|
||||
|
||||
// TotalSize is the total disk space used by all containers.
|
||||
TotalSize int64
|
||||
|
||||
// Items holds detailed information about each container.
|
||||
Items []container.Summary
|
||||
}
|
||||
|
||||
// ImagesDiskUsage contains disk usage information for images.
|
||||
type ImagesDiskUsage struct {
|
||||
// ActiveImages is the number of active images.
|
||||
ActiveImages int64
|
||||
|
||||
// TotalImages is the total number of images.
|
||||
TotalImages int64
|
||||
|
||||
// Reclaimable is the amount of disk space that can be reclaimed.
|
||||
Reclaimable int64
|
||||
|
||||
// TotalSize is the total disk space used by all images.
|
||||
TotalSize int64
|
||||
|
||||
// Items holds detailed information about each image.
|
||||
Items []image.Summary
|
||||
}
|
||||
|
||||
// VolumesDiskUsage contains disk usage information for volumes.
|
||||
type VolumesDiskUsage struct {
|
||||
// ActiveVolumes is the number of active volumes.
|
||||
ActiveVolumes int64
|
||||
|
||||
// TotalVolumes is the total number of volumes.
|
||||
TotalVolumes int64
|
||||
|
||||
// Reclaimable is the amount of disk space that can be reclaimed.
|
||||
Reclaimable int64
|
||||
|
||||
// TotalSize is the total disk space used by all volumes.
|
||||
TotalSize int64
|
||||
|
||||
// Items holds detailed information about each volume.
|
||||
Items []volume.Volume
|
||||
}
|
||||
|
||||
// BuildCacheDiskUsage contains disk usage information for build cache.
|
||||
type BuildCacheDiskUsage struct {
|
||||
// ActiveBuildCacheRecords is the number of active build cache records.
|
||||
ActiveBuildCacheRecords int64
|
||||
|
||||
// TotalBuildCacheRecords is the total number of build cache records.
|
||||
TotalBuildCacheRecords int64
|
||||
|
||||
// Reclaimable is the amount of disk space that can be reclaimed.
|
||||
Reclaimable int64
|
||||
|
||||
// TotalSize is the total disk space used by all build cache records.
|
||||
TotalSize int64
|
||||
|
||||
// Items holds detailed information about each build cache record.
|
||||
Items []build.CacheRecord
|
||||
}
|
||||
|
||||
// DiskUsage requests the current data usage from the daemon.
|
||||
func (cli *Client) DiskUsage(ctx context.Context, options DiskUsageOptions) (DiskUsageResult, error) {
|
||||
query := url.Values{}
|
||||
|
||||
for _, t := range []struct {
|
||||
flag bool
|
||||
sysObj system.DiskUsageObject
|
||||
}{
|
||||
{options.Containers, system.ContainerObject},
|
||||
{options.Images, system.ImageObject},
|
||||
{options.Volumes, system.VolumeObject},
|
||||
{options.BuildCache, system.BuildCacheObject},
|
||||
} {
|
||||
if t.flag {
|
||||
query.Add("type", string(t.sysObj))
|
||||
}
|
||||
}
|
||||
|
||||
if options.Verbose {
|
||||
query.Set("verbose", "1")
|
||||
}
|
||||
|
||||
resp, err := cli.get(ctx, "/system/df", query, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
if err != nil {
|
||||
return system.DiskUsage{}, err
|
||||
return DiskUsageResult{}, err
|
||||
}
|
||||
|
||||
var du system.DiskUsage
|
||||
if err := json.NewDecoder(resp.Body).Decode(&du); err != nil {
|
||||
return system.DiskUsage{}, fmt.Errorf("Error retrieving disk usage: %v", err)
|
||||
return DiskUsageResult{}, fmt.Errorf("Error retrieving disk usage: %v", err)
|
||||
}
|
||||
return du, nil
|
||||
|
||||
var (
|
||||
r DiskUsageResult
|
||||
imagesFrom = []*image.Summary{}
|
||||
containersFrom = []*container.Summary{}
|
||||
volumesFrom = []*volume.Volume{}
|
||||
buildCacheFrom = []*build.CacheRecord{}
|
||||
)
|
||||
|
||||
if du.ImageUsage != nil {
|
||||
r.Images = ImagesDiskUsage{
|
||||
ActiveImages: du.ImageUsage.ActiveImages,
|
||||
Reclaimable: du.ImageUsage.Reclaimable,
|
||||
TotalImages: du.ImageUsage.TotalImages,
|
||||
TotalSize: du.ImageUsage.TotalSize,
|
||||
}
|
||||
|
||||
if options.Verbose {
|
||||
imagesFrom = du.ImageUsage.Items
|
||||
}
|
||||
} else {
|
||||
// Fallback for legacy response.
|
||||
r.Images = ImagesDiskUsage{
|
||||
TotalSize: du.LayersSize,
|
||||
}
|
||||
|
||||
if du.Images != nil && options.Verbose {
|
||||
imagesFrom = du.Images
|
||||
}
|
||||
}
|
||||
|
||||
r.Images.Items = make([]image.Summary, len(imagesFrom))
|
||||
for i, ii := range imagesFrom {
|
||||
r.Images.Items[i] = *ii
|
||||
}
|
||||
|
||||
if du.ContainerUsage != nil {
|
||||
r.Containers = ContainersDiskUsage{
|
||||
ActiveContainers: du.ContainerUsage.ActiveContainers,
|
||||
Reclaimable: du.ContainerUsage.Reclaimable,
|
||||
TotalContainers: du.ContainerUsage.TotalContainers,
|
||||
TotalSize: du.ContainerUsage.TotalSize,
|
||||
}
|
||||
|
||||
if options.Verbose {
|
||||
containersFrom = du.ContainerUsage.Items
|
||||
}
|
||||
} else if du.Containers != nil && options.Verbose {
|
||||
// Fallback for legacy response.
|
||||
containersFrom = du.Containers
|
||||
}
|
||||
|
||||
r.Containers.Items = make([]container.Summary, len(containersFrom))
|
||||
for i, c := range containersFrom {
|
||||
r.Containers.Items[i] = *c
|
||||
}
|
||||
|
||||
if du.BuildCacheUsage != nil {
|
||||
r.BuildCache = BuildCacheDiskUsage{
|
||||
ActiveBuildCacheRecords: du.BuildCacheUsage.ActiveBuildCacheRecords,
|
||||
Reclaimable: du.BuildCacheUsage.Reclaimable,
|
||||
TotalBuildCacheRecords: du.BuildCacheUsage.TotalBuildCacheRecords,
|
||||
TotalSize: du.BuildCacheUsage.TotalSize,
|
||||
}
|
||||
|
||||
if options.Verbose {
|
||||
buildCacheFrom = du.BuildCacheUsage.Items
|
||||
}
|
||||
} else if du.BuildCache != nil && options.Verbose {
|
||||
// Fallback for legacy response.
|
||||
buildCacheFrom = du.BuildCache
|
||||
}
|
||||
|
||||
r.BuildCache.Items = make([]build.CacheRecord, len(buildCacheFrom))
|
||||
for i, b := range buildCacheFrom {
|
||||
r.BuildCache.Items[i] = *b
|
||||
}
|
||||
|
||||
if du.VolumeUsage != nil {
|
||||
r.Volumes = VolumesDiskUsage{
|
||||
ActiveVolumes: du.VolumeUsage.ActiveVolumes,
|
||||
Reclaimable: du.VolumeUsage.Reclaimable,
|
||||
TotalSize: du.VolumeUsage.TotalSize,
|
||||
TotalVolumes: du.VolumeUsage.TotalVolumes,
|
||||
}
|
||||
|
||||
if options.Verbose {
|
||||
volumesFrom = du.VolumeUsage.Items
|
||||
}
|
||||
} else if du.Volumes != nil && options.Verbose {
|
||||
// Fallback for legacy response.
|
||||
volumesFrom = du.Volumes
|
||||
}
|
||||
|
||||
r.Volumes.Items = make([]volume.Volume, len(volumesFrom))
|
||||
for i, v := range volumesFrom {
|
||||
r.Volumes.Items[i] = *v
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
10
vendor/github.com/moby/moby/client/system_disk_usage_opts.go
generated
vendored
10
vendor/github.com/moby/moby/client/system_disk_usage_opts.go
generated
vendored
@@ -1,10 +0,0 @@
|
||||
package client
|
||||
|
||||
import "github.com/moby/moby/api/types/system"
|
||||
|
||||
// DiskUsageOptions holds parameters for system disk usage query.
|
||||
type DiskUsageOptions struct {
|
||||
// Types specifies what object types to include in the response. If empty,
|
||||
// all object types are returned.
|
||||
Types []system.DiskUsageObject
|
||||
}
|
||||
Reference in New Issue
Block a user