From cfcbfabb0ff8d2e0a38a118adbc64afc8152cfeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Gronowski?= Date: Tue, 5 Mar 2024 17:26:27 +0100 Subject: [PATCH] api/image/list: Return `Containers` count MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This parameter was already supported for some time in the backend (for purposes related to docker system prune). It was also already present in the imagetypes.ListOptions but was never actually handled by the client. Make it available by default in the response. Signed-off-by: Paweł Gronowski --- api/server/router/image/image_routes.go | 4 ++++ api/swagger.yaml | 3 +-- api/types/image/opts.go | 2 ++ daemon/containerd/image_list.go | 5 +--- daemon/disk_usage.go | 5 ++-- daemon/images/image_list.go | 32 +++++++++---------------- docs/api/version-history.md | 3 +++ 7 files changed, 24 insertions(+), 30 deletions(-) diff --git a/api/server/router/image/image_routes.go b/api/server/router/image/image_routes.go index 3ae77c38a0..23096e5418 100644 --- a/api/server/router/image/image_routes.go +++ b/api/server/router/image/image_routes.go @@ -459,6 +459,7 @@ func (ir *imageRouter) getImagesJSON(ctx context.Context, w http.ResponseWriter, useNone := versions.LessThan(version, "1.43") withVirtualSize := versions.LessThan(version, "1.44") noDescriptor := versions.LessThan(version, "1.48") + noContainers := versions.LessThan(version, "1.51") for _, img := range images { if useNone { if len(img.RepoTags) == 0 && len(img.RepoDigests) == 0 { @@ -479,6 +480,9 @@ func (ir *imageRouter) getImagesJSON(ctx context.Context, w http.ResponseWriter, if noDescriptor { img.Descriptor = nil } + if noContainers { + img.Containers = -1 + } } return httputils.WriteJSON(w, http.StatusOK, images) diff --git a/api/swagger.yaml b/api/swagger.yaml index 207dabe1aa..8d6a8f9356 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -2196,8 +2196,7 @@ definitions: Number of containers using this image. Includes both stopped and running containers. - This size is not calculated by default, and depends on which API endpoint - is used. `-1` indicates that the value has not been set / calculated. + `-1` indicates that the value has not been set / calculated. x-nullable: false type: "integer" example: 2 diff --git a/api/types/image/opts.go b/api/types/image/opts.go index fd038557c0..9e33a42fa6 100644 --- a/api/types/image/opts.go +++ b/api/types/image/opts.go @@ -75,6 +75,8 @@ type ListOptions struct { SharedSize bool // ContainerCount indicates whether container count should be computed. + // + // Deprecated: This field has been unused and is no longer required and will be removed in a future version. ContainerCount bool // Manifests indicates whether the image manifests should be returned. diff --git a/daemon/containerd/image_list.go b/daemon/containerd/image_list.go index 734bfb1ec8..d9085b810e 100644 --- a/daemon/containerd/image_list.go +++ b/daemon/containerd/image_list.go @@ -409,10 +409,7 @@ func (i *ImageService) imageSummary(ctx context.Context, img c8dimages.Image, pl image.Manifests = summary.Manifests target := img.Target image.Descriptor = &target - - if opts.ContainerCount { - image.Containers = summary.ContainersCount - } + image.Containers = summary.ContainersCount return image, summary, nil } diff --git a/daemon/disk_usage.go b/daemon/disk_usage.go index ae960dca2e..9f6d3ad376 100644 --- a/daemon/disk_usage.go +++ b/daemon/disk_usage.go @@ -57,9 +57,8 @@ func (daemon *Daemon) imageDiskUsage(ctx context.Context) ([]*image.Summary, err imgs, _, err := daemon.usageImages.Do(ctx, struct{}{}, func(ctx context.Context) ([]*image.Summary, error) { // Get all top images with extra attributes imgs, err := daemon.imageService.Images(ctx, image.ListOptions{ - Filters: filters.NewArgs(), - SharedSize: true, - ContainerCount: true, + Filters: filters.NewArgs(), + SharedSize: true, }) if err != nil { return nil, errors.Wrap(err, "failed to retrieve image list") diff --git a/daemon/images/image_list.go b/daemon/images/image_list.go index e5a22a07c8..364923fab5 100644 --- a/daemon/images/image_list.go +++ b/daemon/images/image_list.go @@ -105,7 +105,7 @@ func (i *ImageService) Images(ctx context.Context, opts imagetypes.ListOptions) var ( summaries = make([]*imagetypes.Summary, 0, len(selectedImages)) - summaryMap map[*image.Image]*imagetypes.Summary + summaryMap = make(map[*image.Image]*imagetypes.Summary, len(selectedImages)) allContainers []*container.Container ) for id, img := range selectedImages { @@ -198,30 +198,20 @@ func (i *ImageService) Images(ctx context.Context, opts imagetypes.ListOptions) continue } - if opts.ContainerCount { - // Lazily init allContainers. - if allContainers == nil { - allContainers = i.containers.List() - } - - // Get container count - var containers int64 - for _, c := range allContainers { - if c.ImageID == id { - containers++ - } - } - // NOTE: By default, Containers is -1, or "not set" - summary.Containers = containers + // Lazily init allContainers. + if allContainers == nil { + allContainers = i.containers.List() } - if opts.ContainerCount || opts.SharedSize { - // Lazily init summaryMap. - if summaryMap == nil { - summaryMap = make(map[*image.Image]*imagetypes.Summary, len(selectedImages)) + // Get container count + var containersCount int64 + for _, c := range allContainers { + if c.ImageID == id { + containersCount++ } - summaryMap[img] = summary } + summary.Containers = containersCount + summaryMap[img] = summary summaries = append(summaries, summary) } diff --git a/docs/api/version-history.md b/docs/api/version-history.md index 09466f6043..4e295e4526 100644 --- a/docs/api/version-history.md +++ b/docs/api/version-history.md @@ -17,6 +17,9 @@ keywords: "API, Docker, rcli, REST, documentation" [Docker Engine API v1.51](https://docs.docker.com/reference/api/engine/version/v1.51/) documentation +* `GET /images/json` now sets the value of `Containers` field for all images + to the count of containers using the image. + This field was previously always -1. ## v1.50 API changes