From 48cacbca24c48d451db6e6bfbb08dffa36d97078 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Thu, 24 Nov 2022 19:04:31 +0100 Subject: [PATCH] api/types: move image-types to api/types/image Signed-off-by: Sebastiaan van Stijn --- api/server/router/image/backend.go | 4 +-- api/server/router/image/image_routes.go | 2 +- api/swagger.yaml | 2 ++ .../delete_response.go} | 8 +++--- api/types/image/image.go | 9 +++++++ .../{image_summary.go => image/summary.go} | 8 +++--- api/types/types.go | 13 +++------- api/types/types_deprecated.go | 16 ++++++++++++ client/image_list.go | 5 ++-- client/image_list_test.go | 5 ++-- client/image_prune_test.go | 3 ++- client/image_remove.go | 5 ++-- client/image_remove_test.go | 3 ++- client/interface.go | 4 +-- daemon/containerd/image_delete.go | 20 +++++++------- daemon/containerd/image_list.go | 10 +++---- daemon/containerd/image_prune.go | 5 ++-- daemon/daemon.go | 3 ++- daemon/disk_usage.go | 7 ++--- daemon/image_service.go | 4 +-- daemon/images/image_delete.go | 26 +++++++------------ daemon/images/image_list.go | 14 +++++----- daemon/images/image_prune.go | 3 ++- hack/generate-swagger-api.sh | 7 +++-- integration/system/disk_usage_test.go | 9 ++++--- testutil/environment/protect.go | 7 ++--- 26 files changed, 116 insertions(+), 86 deletions(-) rename api/types/{image_delete_response_item.go => image/delete_response.go} (68%) create mode 100644 api/types/image/image.go rename api/types/{image_summary.go => image/summary.go} (96%) diff --git a/api/server/router/image/backend.go b/api/server/router/image/backend.go index d599538dca..57d16f0bf6 100644 --- a/api/server/router/image/backend.go +++ b/api/server/router/image/backend.go @@ -22,9 +22,9 @@ type Backend interface { } type imageBackend interface { - ImageDelete(ctx context.Context, imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error) + ImageDelete(ctx context.Context, imageRef string, force, prune bool) ([]image.DeleteResponse, error) ImageHistory(ctx context.Context, imageName string) ([]*image.HistoryResponseItem, error) - Images(ctx context.Context, opts types.ImageListOptions) ([]*types.ImageSummary, error) + Images(ctx context.Context, opts types.ImageListOptions) ([]*image.Summary, error) GetImage(ctx context.Context, refOrID string, options image.GetImageOpts) (*dockerimage.Image, error) TagImage(ctx context.Context, id dockerimage.ID, newRef reference.Named) error ImagesPrune(ctx context.Context, pruneFilters filters.Args) (*types.ImagesPruneReport, error) diff --git a/api/server/router/image/image_routes.go b/api/server/router/image/image_routes.go index 5d37565c1d..a8eb4a40ca 100644 --- a/api/server/router/image/image_routes.go +++ b/api/server/router/image/image_routes.go @@ -353,7 +353,7 @@ func (ir *imageRouter) toImageInspect(img *image.Image) (*types.ImageInspect, er Data: img.Details.Metadata, }, RootFS: rootFSToAPIType(img.RootFS), - Metadata: types.ImageMetadata{ + Metadata: opts.Metadata{ LastTagTime: img.Details.LastUpdated, }, }, nil diff --git a/api/swagger.yaml b/api/swagger.yaml index 943c53811a..18c2414a2f 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -1840,6 +1840,7 @@ definitions: x-nullable: true ImageSummary: type: "object" + x-go-name: "Summary" required: - Id - ParentId @@ -4477,6 +4478,7 @@ definitions: ImageDeleteResponseItem: type: "object" + x-go-name: "DeleteResponse" properties: Untagged: description: "The image ID of an image that was untagged" diff --git a/api/types/image_delete_response_item.go b/api/types/image/delete_response.go similarity index 68% rename from api/types/image_delete_response_item.go rename to api/types/image/delete_response.go index b9a65a0d8e..998620dc6a 100644 --- a/api/types/image_delete_response_item.go +++ b/api/types/image/delete_response.go @@ -1,11 +1,11 @@ -package types +package image // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command -// ImageDeleteResponseItem image delete response item -// swagger:model ImageDeleteResponseItem -type ImageDeleteResponseItem struct { +// DeleteResponse delete response +// swagger:model DeleteResponse +type DeleteResponse struct { // The image ID of an image that was deleted Deleted string `json:"Deleted,omitempty"` diff --git a/api/types/image/image.go b/api/types/image/image.go new file mode 100644 index 0000000000..167df28c7b --- /dev/null +++ b/api/types/image/image.go @@ -0,0 +1,9 @@ +package image + +import "time" + +// Metadata contains engine-local data about the image. +type Metadata struct { + // LastTagTime is the date and time at which the image was last tagged. + LastTagTime time.Time `json:",omitempty"` +} diff --git a/api/types/image_summary.go b/api/types/image/summary.go similarity index 96% rename from api/types/image_summary.go rename to api/types/image/summary.go index 076848ad5f..f1e3e2ef01 100644 --- a/api/types/image_summary.go +++ b/api/types/image/summary.go @@ -1,11 +1,11 @@ -package types +package image // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command -// ImageSummary image summary -// swagger:model ImageSummary -type ImageSummary struct { +// Summary summary +// swagger:model Summary +type Summary struct { // Number of containers using this image. Includes both stopped and running // containers. diff --git a/api/types/types.go b/api/types/types.go index 84a85df786..a28224c191 100644 --- a/api/types/types.go +++ b/api/types/types.go @@ -7,6 +7,7 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/swarm" @@ -128,13 +129,7 @@ type ImageInspect struct { // Metadata of the image in the local cache. // // This information is local to the daemon, and not part of the image itself. - Metadata ImageMetadata -} - -// ImageMetadata contains engine-local data about the image -type ImageMetadata struct { - // LastTagTime is the date and time at which the image was last tagged. - LastTagTime time.Time `json:",omitempty"` + Metadata image.Metadata } // Container contains response of Engine API: @@ -514,7 +509,7 @@ type DiskUsageOptions struct { // GET "/system/df" type DiskUsage struct { LayersSize int64 - Images []*ImageSummary + Images []*image.Summary Containers []*Container Volumes []*volume.Volume BuildCache []*BuildCache @@ -538,7 +533,7 @@ type VolumesPruneReport struct { // ImagesPruneReport contains the response for Engine API: // POST "/images/prune" type ImagesPruneReport struct { - ImagesDeleted []ImageDeleteResponseItem + ImagesDeleted []image.DeleteResponse SpaceReclaimed uint64 } diff --git a/api/types/types_deprecated.go b/api/types/types_deprecated.go index 3d0174b756..1940d864b6 100644 --- a/api/types/types_deprecated.go +++ b/api/types/types_deprecated.go @@ -2,6 +2,7 @@ package types import ( "github.com/docker/docker/api/types/checkpoint" + "github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/system" ) @@ -63,6 +64,21 @@ type SecurityOpt = system.SecurityOpt // Deprecated: use [system.KeyValue]. type KeyValue = system.KeyValue +// ImageDeleteResponseItem image delete response item. +// +// Deprecated: use [image.DeleteResponse]. +type ImageDeleteResponseItem = image.DeleteResponse + +// ImageSummary image summary. +// +// Deprecated: use [image.Summary]. +type ImageSummary = image.Summary + +// ImageMetadata contains engine-local data about the image. +// +// Deprecated: use [image.Metadata]. +type ImageMetadata = image.Metadata + // DecodeSecurityOptions decodes a security options string slice to a type safe // [system.SecurityOpt]. // diff --git a/client/image_list.go b/client/image_list.go index 986b961a45..f3f2280e32 100644 --- a/client/image_list.go +++ b/client/image_list.go @@ -7,11 +7,12 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/versions" ) // ImageList returns a list of images in the docker host. -func (cli *Client) ImageList(ctx context.Context, options types.ImageListOptions) ([]types.ImageSummary, error) { +func (cli *Client) ImageList(ctx context.Context, options types.ImageListOptions) ([]image.Summary, error) { // Make sure we negotiated (if the client is configured to do so), // as code below contains API-version specific handling of options. // @@ -19,7 +20,7 @@ func (cli *Client) ImageList(ctx context.Context, options types.ImageListOptions // the API request is made. cli.checkVersion(ctx) - var images []types.ImageSummary + var images []image.Summary query := url.Values{} optionFilters := options.Filters diff --git a/client/image_list_test.go b/client/image_list_test.go index c571d5bd98..bcd6db7d98 100644 --- a/client/image_list_test.go +++ b/client/image_list_test.go @@ -13,6 +13,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/image" "github.com/docker/docker/errdefs" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -80,7 +81,7 @@ func TestImageList(t *testing.T) { return nil, fmt.Errorf("%s not set in URL query properly. Expected '%s', got %s", key, expected, actual) } } - content, err := json.Marshal([]types.ImageSummary{ + content, err := json.Marshal([]image.Summary{ { ID: "image_id2", }, @@ -121,7 +122,7 @@ func TestImageListApiBefore125(t *testing.T) { if actualFilters != "" { return nil, fmt.Errorf("filters should have not been present, were with value: %s", actualFilters) } - content, err := json.Marshal([]types.ImageSummary{ + content, err := json.Marshal([]image.Summary{ { ID: "image_id2", }, diff --git a/client/image_prune_test.go b/client/image_prune_test.go index f8428efb16..5abe9ea317 100644 --- a/client/image_prune_test.go +++ b/client/image_prune_test.go @@ -10,6 +10,7 @@ import ( "strings" "testing" + "github.com/docker/docker/api/types/image" "github.com/docker/docker/errdefs" "github.com/docker/docker/api/types" @@ -84,7 +85,7 @@ func TestImagesPrune(t *testing.T) { assert.Check(t, is.Equal(expected, actual)) } content, err := json.Marshal(types.ImagesPruneReport{ - ImagesDeleted: []types.ImageDeleteResponseItem{ + ImagesDeleted: []image.DeleteResponse{ { Deleted: "image_id1", }, diff --git a/client/image_remove.go b/client/image_remove.go index 6a9fb3f41f..b936d20830 100644 --- a/client/image_remove.go +++ b/client/image_remove.go @@ -6,10 +6,11 @@ import ( "net/url" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/image" ) // ImageRemove removes an image from the docker host. -func (cli *Client) ImageRemove(ctx context.Context, imageID string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) { +func (cli *Client) ImageRemove(ctx context.Context, imageID string, options types.ImageRemoveOptions) ([]image.DeleteResponse, error) { query := url.Values{} if options.Force { @@ -19,7 +20,7 @@ func (cli *Client) ImageRemove(ctx context.Context, imageID string, options type query.Set("noprune", "1") } - var dels []types.ImageDeleteResponseItem + var dels []image.DeleteResponse resp, err := cli.delete(ctx, "/images/"+imageID, query, nil) defer ensureReaderClosed(resp) if err != nil { diff --git a/client/image_remove_test.go b/client/image_remove_test.go index 24638afc42..9614f8572c 100644 --- a/client/image_remove_test.go +++ b/client/image_remove_test.go @@ -11,6 +11,7 @@ import ( "testing" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/image" "github.com/docker/docker/errdefs" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -74,7 +75,7 @@ func TestImageRemove(t *testing.T) { return nil, fmt.Errorf("%s not set in URL query properly. Expected '%s', got %s", key, expected, actual) } } - b, err := json.Marshal([]types.ImageDeleteResponseItem{ + b, err := json.Marshal([]image.DeleteResponse{ { Untagged: "image_id1", }, diff --git a/client/interface.go b/client/interface.go index b2e5d36486..bb416c79cb 100644 --- a/client/interface.go +++ b/client/interface.go @@ -94,11 +94,11 @@ type ImageAPIClient interface { ImageHistory(ctx context.Context, image string) ([]image.HistoryResponseItem, error) ImageImport(ctx context.Context, source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error) ImageInspectWithRaw(ctx context.Context, image string) (types.ImageInspect, []byte, error) - ImageList(ctx context.Context, options types.ImageListOptions) ([]types.ImageSummary, error) + ImageList(ctx context.Context, options types.ImageListOptions) ([]image.Summary, error) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (types.ImageLoadResponse, error) ImagePull(ctx context.Context, ref string, options types.ImagePullOptions) (io.ReadCloser, error) ImagePush(ctx context.Context, ref string, options types.ImagePushOptions) (io.ReadCloser, error) - ImageRemove(ctx context.Context, image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) + ImageRemove(ctx context.Context, image string, options types.ImageRemoveOptions) ([]image.DeleteResponse, error) ImageSearch(ctx context.Context, term string, options types.ImageSearchOptions) ([]registry.SearchResult, error) ImageSave(ctx context.Context, images []string) (io.ReadCloser, error) ImageTag(ctx context.Context, image, ref string) error diff --git a/daemon/containerd/image_delete.go b/daemon/containerd/image_delete.go index 4efbaf7773..459c4c8f6c 100644 --- a/daemon/containerd/image_delete.go +++ b/daemon/containerd/image_delete.go @@ -9,8 +9,8 @@ import ( "github.com/containerd/containerd/images" "github.com/containerd/log" "github.com/distribution/reference" - "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/events" + imagetypes "github.com/docker/docker/api/types/image" "github.com/docker/docker/container" "github.com/docker/docker/image" "github.com/docker/docker/internal/compatcontext" @@ -52,7 +52,7 @@ import ( // conflict will not be reported. // // TODO(thaJeztah): image delete should send prometheus counters; see https://github.com/moby/moby/issues/45268 -func (i *ImageService) ImageDelete(ctx context.Context, imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error) { +func (i *ImageService) ImageDelete(ctx context.Context, imageRef string, force, prune bool) ([]imagetypes.DeleteResponse, error) { parsedRef, err := reference.ParseNormalizedNamed(imageRef) if err != nil { return nil, err @@ -80,7 +80,7 @@ func (i *ImageService) ImageDelete(ctx context.Context, imageRef string, force, return nil, err } i.LogImageEvent(imgID.String(), imgID.String(), events.ActionUnTag) - records := []types.ImageDeleteResponseItem{{Untagged: reference.FamiliarString(reference.TagNameOnly(parsedRef))}} + records := []imagetypes.DeleteResponse{{Untagged: reference.FamiliarString(reference.TagNameOnly(parsedRef))}} return records, nil } @@ -111,7 +111,7 @@ func (i *ImageService) ImageDelete(ctx context.Context, imageRef string, force, } i.LogImageEvent(imgID.String(), imgID.String(), events.ActionUnTag) - records := []types.ImageDeleteResponseItem{{Untagged: reference.FamiliarString(reference.TagNameOnly(parsedRef))}} + records := []imagetypes.DeleteResponse{{Untagged: reference.FamiliarString(reference.TagNameOnly(parsedRef))}} return records, nil } @@ -122,8 +122,8 @@ func (i *ImageService) ImageDelete(ctx context.Context, imageRef string, force, // also deletes dangling parents if there is no conflict in doing so. // Parent images are removed quietly, and if there is any issue/conflict // it is logged but does not halt execution/an error is not returned. -func (i *ImageService) deleteAll(ctx context.Context, img images.Image, force, prune bool) ([]types.ImageDeleteResponseItem, error) { - var records []types.ImageDeleteResponseItem +func (i *ImageService) deleteAll(ctx context.Context, img images.Image, force, prune bool) ([]imagetypes.DeleteResponse, error) { + var records []imagetypes.DeleteResponse // Workaround for: https://github.com/moby/buildkit/issues/3797 possiblyDeletedConfigs := map[digest.Digest]struct{}{} @@ -163,7 +163,7 @@ func (i *ImageService) deleteAll(ctx context.Context, img images.Image, force, p } } i.LogImageEvent(imgID, imgID, events.ActionDelete) - records = append(records, types.ImageDeleteResponseItem{Deleted: imgID}) + records = append(records, imagetypes.DeleteResponse{Deleted: imgID}) for _, parent := range parents { if !isDanglingImage(parent.img) { @@ -176,7 +176,7 @@ func (i *ImageService) deleteAll(ctx context.Context, img images.Image, force, p } parentID := parent.img.Target.Digest.String() i.LogImageEvent(parentID, parentID, events.ActionDelete) - records = append(records, types.ImageDeleteResponseItem{Deleted: parentID}) + records = append(records, imagetypes.DeleteResponse{Deleted: parentID}) } return records, nil @@ -238,7 +238,7 @@ const ( // images and untagged references are appended to the given records. If any // error or conflict is encountered, it will be returned immediately without // deleting the image. -func (i *ImageService) imageDeleteHelper(ctx context.Context, img images.Image, records *[]types.ImageDeleteResponseItem, force bool) error { +func (i *ImageService) imageDeleteHelper(ctx context.Context, img images.Image, records *[]imagetypes.DeleteResponse, force bool) error { // First, determine if this image has any conflicts. Ignore soft conflicts // if force is true. c := conflictHard @@ -264,7 +264,7 @@ func (i *ImageService) imageDeleteHelper(ctx context.Context, img images.Image, if !isDanglingImage(img) { i.LogImageEvent(imgID.String(), imgID.String(), events.ActionUnTag) - *records = append(*records, types.ImageDeleteResponseItem{Untagged: reference.FamiliarString(untaggedRef)}) + *records = append(*records, imagetypes.DeleteResponse{Untagged: reference.FamiliarString(untaggedRef)}) } return nil diff --git a/daemon/containerd/image_list.go b/daemon/containerd/image_list.go index 8a38b8888b..44227dbd43 100644 --- a/daemon/containerd/image_list.go +++ b/daemon/containerd/image_list.go @@ -46,7 +46,7 @@ var acceptedImageFilterTags = map[string]bool{ // byCreated is a temporary type used to sort a list of images by creation // time. -type byCreated []*types.ImageSummary +type byCreated []*imagetypes.Summary func (r byCreated) Len() int { return len(r) } func (r byCreated) Swap(i, j int) { r[i], r[j] = r[j], r[i] } @@ -57,7 +57,7 @@ func (r byCreated) Less(i, j int) bool { return r[i].Created < r[j].Created } // TODO(thaJeztah): implement opts.ContainerCount (used for docker system df); see https://github.com/moby/moby/issues/43853 // TODO(thaJeztah): verify behavior of `RepoDigests` and `RepoTags` for images without (untagged) or multiple tags; see https://github.com/moby/moby/issues/43861 // TODO(thaJeztah): verify "Size" vs "VirtualSize" in images; see https://github.com/moby/moby/issues/43862 -func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions) ([]*types.ImageSummary, error) { +func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions) ([]*imagetypes.Summary, error) { if err := opts.Filters.Validate(acceptedImageFilterTags); err != nil { return nil, err } @@ -89,7 +89,7 @@ func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions) var ( allContainers []*container.Container - summaries = make([]*types.ImageSummary, 0, len(imgs)) + summaries = make([]*imagetypes.Summary, 0, len(imgs)) root []*[]digest.Digest layers map[digest.Digest]int ) @@ -208,7 +208,7 @@ func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions) return summaries, nil } -func (i *ImageService) singlePlatformImage(ctx context.Context, contentStore content.Store, repoTags []string, imageManifest *ImageManifest, opts types.ImageListOptions, allContainers []*container.Container) (*types.ImageSummary, []digest.Digest, error) { +func (i *ImageService) singlePlatformImage(ctx context.Context, contentStore content.Store, repoTags []string, imageManifest *ImageManifest, opts types.ImageListOptions, allContainers []*container.Container) (*imagetypes.Summary, []digest.Digest, error) { diffIDs, err := imageManifest.RootFS(ctx) if err != nil { return nil, nil, errors.Wrapf(err, "failed to get rootfs of image %s", imageManifest.Name()) @@ -276,7 +276,7 @@ func (i *ImageService) singlePlatformImage(ctx context.Context, contentStore con return nil, nil, err } - summary := &types.ImageSummary{ + summary := &imagetypes.Summary{ ParentID: "", ID: target.String(), Created: rawImg.CreatedAt.Unix(), diff --git a/daemon/containerd/image_prune.go b/daemon/containerd/image_prune.go index 41ce1fcc47..1ca513ae5a 100644 --- a/daemon/containerd/image_prune.go +++ b/daemon/containerd/image_prune.go @@ -10,6 +10,7 @@ import ( "github.com/distribution/reference" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/image" "github.com/docker/docker/errdefs" "github.com/docker/docker/internal/compatcontext" "github.com/hashicorp/go-multierror" @@ -182,7 +183,7 @@ func (i *ImageService) pruneUnused(ctx context.Context, filterFunc imageFilterFu } report.ImagesDeleted = append(report.ImagesDeleted, - types.ImageDeleteResponseItem{ + image.DeleteResponse{ Untagged: img.Name, }, ) @@ -193,7 +194,7 @@ func (i *ImageService) pruneUnused(ctx context.Context, filterFunc imageFilterFu if cerrdefs.IsNotFound(err) { report.ImagesDeleted = append(report.ImagesDeleted, - types.ImageDeleteResponseItem{ + image.DeleteResponse{ Deleted: blob.Digest.String(), }, ) diff --git a/daemon/daemon.go b/daemon/daemon.go index bc47ac5fec..ac9872e539 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -27,6 +27,7 @@ import ( dist "github.com/docker/distribution" "github.com/docker/docker/api/types" containertypes "github.com/docker/docker/api/types/container" + imagetypes "github.com/docker/docker/api/types/image" registrytypes "github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/volume" @@ -122,7 +123,7 @@ type Daemon struct { seccompProfilePath string usageContainers singleflight.Group[struct{}, []*types.Container] - usageImages singleflight.Group[struct{}, []*types.ImageSummary] + usageImages singleflight.Group[struct{}, []*imagetypes.Summary] usageVolumes singleflight.Group[struct{}, []*volume.Volume] usageLayer singleflight.Group[struct{}, int64] diff --git a/daemon/disk_usage.go b/daemon/disk_usage.go index b4c2b277d0..e66e917d68 100644 --- a/daemon/disk_usage.go +++ b/daemon/disk_usage.go @@ -7,6 +7,7 @@ import ( "github.com/docker/docker/api/server/router/system" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/volume" "github.com/pkg/errors" "golang.org/x/sync/errgroup" @@ -31,8 +32,8 @@ func (daemon *Daemon) containerDiskUsage(ctx context.Context) ([]*types.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) ([]*types.ImageSummary, error) { - imgs, _, err := daemon.usageImages.Do(ctx, struct{}{}, func(ctx context.Context) ([]*types.ImageSummary, error) { +func (daemon *Daemon) imageDiskUsage(ctx context.Context) ([]*image.Summary, error) { + 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, types.ImageListOptions{ Filters: filters.NewArgs(), @@ -89,7 +90,7 @@ func (daemon *Daemon) SystemDiskUsage(ctx context.Context, opts system.DiskUsage } var ( - images []*types.ImageSummary + images []*image.Summary layersSize int64 ) if opts.Images { diff --git a/daemon/image_service.go b/daemon/image_service.go index 5b28fbe8ef..50105c5304 100644 --- a/daemon/image_service.go +++ b/daemon/image_service.go @@ -30,11 +30,11 @@ type ImageService interface { PullImage(ctx context.Context, ref reference.Named, platform *ocispec.Platform, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error PushImage(ctx context.Context, ref reference.Named, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error CreateImage(ctx context.Context, config []byte, parent string, contentStoreDigest digest.Digest) (builder.Image, error) - ImageDelete(ctx context.Context, imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error) + ImageDelete(ctx context.Context, imageRef string, force, prune bool) ([]imagetype.DeleteResponse, error) ExportImage(ctx context.Context, names []string, outStream io.Writer) error PerformWithBaseFS(ctx context.Context, c *container.Container, fn func(string) error) error LoadImage(ctx context.Context, inTar io.ReadCloser, outStream io.Writer, quiet bool) error - Images(ctx context.Context, opts types.ImageListOptions) ([]*types.ImageSummary, error) + Images(ctx context.Context, opts types.ImageListOptions) ([]*imagetype.Summary, error) LogImageEvent(imageID, refName string, action events.Action) CountImages() int ImagesPrune(ctx context.Context, pruneFilters filters.Args) (*types.ImagesPruneReport, error) diff --git a/daemon/images/image_delete.go b/daemon/images/image_delete.go index 786cc728fb..844f48852f 100644 --- a/daemon/images/image_delete.go +++ b/daemon/images/image_delete.go @@ -7,7 +7,6 @@ import ( "time" "github.com/distribution/reference" - "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/events" imagetypes "github.com/docker/docker/api/types/image" "github.com/docker/docker/container" @@ -61,9 +60,9 @@ const ( // If prune is true, ancestor images will each attempt to be deleted quietly, // meaning any delete conflicts will cause the image to not be deleted and the // conflict will not be reported. -func (i *ImageService) ImageDelete(ctx context.Context, imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error) { +func (i *ImageService) ImageDelete(ctx context.Context, imageRef string, force, prune bool) ([]imagetypes.DeleteResponse, error) { start := time.Now() - records := []types.ImageDeleteResponseItem{} + records := []imagetypes.DeleteResponse{} img, err := i.GetImage(ctx, imageRef, imagetypes.GetImageOpts{}) if err != nil { @@ -104,7 +103,7 @@ func (i *ImageService) ImageDelete(ctx context.Context, imageRef string, force, return nil, err } - untaggedRecord := types.ImageDeleteResponseItem{Untagged: reference.FamiliarString(parsedRef)} + untaggedRecord := imagetypes.DeleteResponse{Untagged: reference.FamiliarString(parsedRef)} i.LogImageEvent(imgID.String(), imgID.String(), events.ActionUnTag) records = append(records, untaggedRecord) @@ -130,9 +129,7 @@ func (i *ImageService) ImageDelete(ctx context.Context, imageRef string, force, if _, err := i.removeImageRef(repoRef); err != nil { return records, err } - - untaggedRecord := types.ImageDeleteResponseItem{Untagged: reference.FamiliarString(repoRef)} - records = append(records, untaggedRecord) + records = append(records, imagetypes.DeleteResponse{Untagged: reference.FamiliarString(repoRef)}) } else { remainingRefs = append(remainingRefs, repoRef) } @@ -165,11 +162,8 @@ func (i *ImageService) ImageDelete(ctx context.Context, imageRef string, force, if err != nil { return nil, err } - - untaggedRecord := types.ImageDeleteResponseItem{Untagged: reference.FamiliarString(parsedRef)} - i.LogImageEvent(imgID.String(), imgID.String(), events.ActionUnTag) - records = append(records, untaggedRecord) + records = append(records, imagetypes.DeleteResponse{Untagged: reference.FamiliarString(parsedRef)}) } } } @@ -243,14 +237,14 @@ func (i *ImageService) removeImageRef(ref reference.Named) (reference.Named, err // on the first encountered error. Removed references are logged to this // daemon's event service. An "Untagged" types.ImageDeleteResponseItem is added to the // given list of records. -func (i *ImageService) removeAllReferencesToImageID(imgID image.ID, records *[]types.ImageDeleteResponseItem) error { +func (i *ImageService) removeAllReferencesToImageID(imgID image.ID, records *[]imagetypes.DeleteResponse) error { for _, imageRef := range i.referenceStore.References(imgID.Digest()) { parsedRef, err := i.removeImageRef(imageRef) if err != nil { return err } i.LogImageEvent(imgID.String(), imgID.String(), events.ActionUnTag) - *records = append(*records, types.ImageDeleteResponseItem{ + *records = append(*records, imagetypes.DeleteResponse{ Untagged: reference.FamiliarString(parsedRef), }) } @@ -291,7 +285,7 @@ func (idc *imageDeleteConflict) Conflict() {} // conflict is encountered, it will be returned immediately without deleting // the image. If quiet is true, any encountered conflicts will be ignored and // the function will return nil immediately without deleting the image. -func (i *ImageService) imageDeleteHelper(imgID image.ID, records *[]types.ImageDeleteResponseItem, force, prune, quiet bool) error { +func (i *ImageService) imageDeleteHelper(imgID image.ID, records *[]imagetypes.DeleteResponse, force, prune, quiet bool) error { // First, determine if this image has any conflicts. Ignore soft conflicts // if force is true. c := conflictHard @@ -327,9 +321,9 @@ func (i *ImageService) imageDeleteHelper(imgID image.ID, records *[]types.ImageD } i.LogImageEvent(imgID.String(), imgID.String(), events.ActionDelete) - *records = append(*records, types.ImageDeleteResponseItem{Deleted: imgID.String()}) + *records = append(*records, imagetypes.DeleteResponse{Deleted: imgID.String()}) for _, removedLayer := range removedLayers { - *records = append(*records, types.ImageDeleteResponseItem{Deleted: removedLayer.ChainID.String()}) + *records = append(*records, imagetypes.DeleteResponse{Deleted: removedLayer.ChainID.String()}) } if !prune || parent == "" { diff --git a/daemon/images/image_list.go b/daemon/images/image_list.go index d5e4bf96ef..8da13be112 100644 --- a/daemon/images/image_list.go +++ b/daemon/images/image_list.go @@ -25,14 +25,14 @@ var acceptedImageFilterTags = map[string]bool{ // byCreated is a temporary type used to sort a list of images by creation // time. -type byCreated []*types.ImageSummary +type byCreated []*imagetypes.Summary func (r byCreated) Len() int { return len(r) } func (r byCreated) Swap(i, j int) { r[i], r[j] = r[j], r[i] } func (r byCreated) Less(i, j int) bool { return r[i].Created < r[j].Created } // Images returns a filtered list of images. -func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions) ([]*types.ImageSummary, error) { +func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions) ([]*imagetypes.Summary, error) { if err := opts.Filters.Validate(acceptedImageFilterTags); err != nil { return nil, err } @@ -83,8 +83,8 @@ func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions) } var ( - summaries = make([]*types.ImageSummary, 0, len(selectedImages)) - summaryMap map[*image.Image]*types.ImageSummary + summaries = make([]*imagetypes.Summary, 0, len(selectedImages)) + summaryMap map[*image.Image]*imagetypes.Summary allContainers []*container.Container ) for id, img := range selectedImages { @@ -197,7 +197,7 @@ func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions) if opts.ContainerCount || opts.SharedSize { // Lazily init summaryMap. if summaryMap == nil { - summaryMap = make(map[*image.Image]*types.ImageSummary, len(selectedImages)) + summaryMap = make(map[*image.Image]*imagetypes.Summary, len(selectedImages)) } summaryMap[img] = summary } @@ -252,12 +252,12 @@ func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions) return summaries, nil } -func newImageSummary(image *image.Image, size int64) *types.ImageSummary { +func newImageSummary(image *image.Image, size int64) *imagetypes.Summary { var created int64 if image.Created != nil { created = image.Created.Unix() } - summary := &types.ImageSummary{ + summary := &imagetypes.Summary{ ParentID: image.Parent.String(), ID: image.ID().String(), Created: created, diff --git a/daemon/images/image_prune.go b/daemon/images/image_prune.go index 7ade3409d7..7634b837ff 100644 --- a/daemon/images/image_prune.go +++ b/daemon/images/image_prune.go @@ -12,6 +12,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/events" "github.com/docker/docker/api/types/filters" + imagetypes "github.com/docker/docker/api/types/image" timetypes "github.com/docker/docker/api/types/time" "github.com/docker/docker/errdefs" "github.com/docker/docker/image" @@ -96,7 +97,7 @@ deleteImagesLoop: default: } - deletedImages := []types.ImageDeleteResponseItem{} + deletedImages := []imagetypes.DeleteResponse{} refs := i.referenceStore.References(id.Digest()) if len(refs) > 0 { shouldDelete := !danglingOnly diff --git a/hack/generate-swagger-api.sh b/hack/generate-swagger-api.sh index d5032178e5..65fe2d13b6 100755 --- a/hack/generate-swagger-api.sh +++ b/hack/generate-swagger-api.sh @@ -6,8 +6,6 @@ swagger generate model -f api/swagger.yaml \ -n ErrorResponse \ -n GraphDriverData \ -n IdResponse \ - -n ImageDeleteResponseItem \ - -n ImageSummary \ -n Plugin \ -n PluginDevice \ -n PluginMount \ @@ -24,6 +22,11 @@ swagger generate model -f api/swagger.yaml \ -n ChangeType \ -n FilesystemChange +swagger generate model -f api/swagger.yaml \ + -t api -m types/image --skip-validator -C api/swagger-gen.yaml \ + -n ImageDeleteResponseItem \ + -n ImageSummary + swagger generate model -f api/swagger.yaml \ -t api -m types/volume --skip-validator -C api/swagger-gen.yaml \ -n Volume \ diff --git a/integration/system/disk_usage_test.go b/integration/system/disk_usage_test.go index 8a4f9a460b..9aafe167fa 100644 --- a/integration/system/disk_usage_test.go +++ b/integration/system/disk_usage_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/volume" "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/testutil" @@ -36,7 +37,7 @@ func TestDiskUsage(t *testing.T) { du, err := client.DiskUsage(ctx, types.DiskUsageOptions{}) assert.NilError(t, err) assert.DeepEqual(t, du, types.DiskUsage{ - Images: []*types.ImageSummary{}, + Images: []*image.Summary{}, Containers: []*types.Container{}, Volumes: []*volume.Volume{}, BuildCache: []*types.BuildCache{}, @@ -55,7 +56,7 @@ func TestDiskUsage(t *testing.T) { assert.Equal(t, len(du.Images), 1) assert.DeepEqual(t, du, types.DiskUsage{ LayersSize: du.LayersSize, - Images: []*types.ImageSummary{ + Images: []*image.Summary{ { Created: du.Images[0].Created, ID: du.Images[0].ID, @@ -83,8 +84,8 @@ func TestDiskUsage(t *testing.T) { assert.Assert(t, du.Containers[0].Created >= prev.Images[0].Created) assert.DeepEqual(t, du, types.DiskUsage{ LayersSize: prev.LayersSize, - Images: []*types.ImageSummary{ - func() *types.ImageSummary { + Images: []*image.Summary{ + func() *image.Summary { sum := *prev.Images[0] sum.Containers++ return &sum diff --git a/testutil/environment/protect.go b/testutil/environment/protect.go index 4ea745ceec..a398f25a9d 100644 --- a/testutil/environment/protect.go +++ b/testutil/environment/protect.go @@ -6,6 +6,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/volume" "github.com/docker/docker/errdefs" "go.opentelemetry.io/otel" @@ -112,13 +113,13 @@ func getExistingImages(ctx context.Context, t testing.TB, testEnv *Execution) [] assert.NilError(t, err, "failed to list images") var images []string - for _, image := range imageList { - images = append(images, tagsFromImageSummary(image)...) + for _, img := range imageList { + images = append(images, tagsFromImageSummary(img)...) } return images } -func tagsFromImageSummary(image types.ImageSummary) []string { +func tagsFromImageSummary(image image.Summary) []string { var result []string for _, tag := range image.RepoTags { // Starting from API 1.43 no longer outputs the hardcoded