From b3974f07f54db3e6f47ae483794cdedab186f0d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Gronowski?= Date: Mon, 20 Oct 2025 17:28:21 +0200 Subject: [PATCH] client/image_list: Wrap options and result MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Paweł Gronowski Signed-off-by: Austin Vazquez --- client/client_interfaces.go | 2 +- client/image_list.go | 8 ++-- client/image_list_opts.go | 7 ++++ client/image_list_test.go | 2 +- integration-cli/docker_api_images_test.go | 10 ++--- integration/container/export_test.go | 2 +- integration/daemon/migration_test.go | 2 +- integration/image/list_test.go | 40 +++++++++---------- integration/image/load_test.go | 10 ++--- internal/testutil/environment/clean.go | 4 +- internal/testutil/environment/environment.go | 2 +- internal/testutil/environment/protect.go | 2 +- .../moby/moby/client/client_interfaces.go | 2 +- .../github.com/moby/moby/client/image_list.go | 8 ++-- .../moby/moby/client/image_list_opts.go | 7 ++++ 15 files changed, 61 insertions(+), 47 deletions(-) diff --git a/client/client_interfaces.go b/client/client_interfaces.go index 86f9be8022..554ba8e8f5 100644 --- a/client/client_interfaces.go +++ b/client/client_interfaces.go @@ -111,7 +111,7 @@ type ImageAPIClient interface { ImageCreate(ctx context.Context, parentReference string, options ImageCreateOptions) (ImageCreateResult, error) ImageImport(ctx context.Context, source ImageImportSource, ref string, options ImageImportOptions) (ImageImportResult, error) - ImageList(ctx context.Context, options ImageListOptions) ([]image.Summary, error) + ImageList(ctx context.Context, options ImageListOptions) (ImageListResult, error) ImagePull(ctx context.Context, ref string, options ImagePullOptions) (ImagePullResponse, error) ImagePush(ctx context.Context, ref string, options ImagePushOptions) (ImagePushResponse, error) ImageRemove(ctx context.Context, image string, options ImageRemoveOptions) ([]image.DeleteResponse, error) diff --git a/client/image_list.go b/client/image_list.go index d2516d80d3..955422c137 100644 --- a/client/image_list.go +++ b/client/image_list.go @@ -15,7 +15,7 @@ import ( // to include [image.Summary.Manifests] with information about image manifests. // This is experimental and might change in the future without any backward // compatibility. -func (cli *Client) ImageList(ctx context.Context, options ImageListOptions) ([]image.Summary, error) { +func (cli *Client) ImageList(ctx context.Context, options ImageListOptions) (ImageListResult, error) { var images []image.Summary query := url.Values{} @@ -34,7 +34,7 @@ func (cli *Client) ImageList(ctx context.Context, options ImageListOptions) ([]i // Normally, version-negotiation (if enabled) would not happen until // the API request is made. if err := cli.checkVersion(ctx); err != nil { - return images, err + return ImageListResult{}, err } if versions.GreaterThanOrEqualTo(cli.version, "1.47") { @@ -45,9 +45,9 @@ func (cli *Client) ImageList(ctx context.Context, options ImageListOptions) ([]i resp, err := cli.get(ctx, "/images/json", query, nil) defer ensureReaderClosed(resp) if err != nil { - return images, err + return ImageListResult{}, err } err = json.NewDecoder(resp.Body).Decode(&images) - return images, err + return ImageListResult{Items: images}, err } diff --git a/client/image_list_opts.go b/client/image_list_opts.go index 2bd6deb897..a497d5790e 100644 --- a/client/image_list_opts.go +++ b/client/image_list_opts.go @@ -1,5 +1,7 @@ package client +import "github.com/moby/moby/api/types/image" + // ImageListOptions holds parameters to list images with. type ImageListOptions struct { // All controls whether all images in the graph are filtered, or just @@ -15,3 +17,8 @@ type ImageListOptions struct { // Manifests indicates whether the image manifests should be returned. Manifests bool } + +// ImageListResult holds the result from ImageList. +type ImageListResult struct { + Items []image.Summary +} diff --git a/client/image_list_test.go b/client/image_list_test.go index 619150bd24..2fd346ff45 100644 --- a/client/image_list_test.go +++ b/client/image_list_test.go @@ -108,7 +108,7 @@ func TestImageList(t *testing.T) { images, err := client.ImageList(context.Background(), listCase.options) assert.NilError(t, err) - assert.Check(t, is.Len(images, 2)) + assert.Check(t, is.Len(images.Items, 2)) } } diff --git a/integration-cli/docker_api_images_test.go b/integration-cli/docker_api_images_test.go index 0b6ad9d7e1..ac57a8ee32 100644 --- a/integration-cli/docker_api_images_test.go +++ b/integration-cli/docker_api_images_test.go @@ -102,10 +102,10 @@ func (s *DockerAPISuite) TestAPIImagesSizeCompatibility(c *testing.T) { apiclient := testEnv.APIClient() defer apiclient.Close() - images, err := apiclient.ImageList(testutil.GetContext(c), client.ImageListOptions{}) + imageList, err := apiclient.ImageList(testutil.GetContext(c), client.ImageListOptions{}) assert.NilError(c, err) - assert.Assert(c, len(images) != 0) - for _, img := range images { + assert.Assert(c, len(imageList.Items) != 0) + for _, img := range imageList.Items { assert.Assert(c, img.Size != int64(-1)) } @@ -115,8 +115,8 @@ func (s *DockerAPISuite) TestAPIImagesSizeCompatibility(c *testing.T) { v124Images, err := apiclient.ImageList(testutil.GetContext(c), client.ImageListOptions{}) assert.NilError(c, err) - assert.Assert(c, len(v124Images) != 0) - for _, img := range v124Images { + assert.Assert(c, len(v124Images.Items) != 0) + for _, img := range v124Images.Items { assert.Assert(c, img.Size != int64(-1)) } } diff --git a/integration/container/export_test.go b/integration/container/export_test.go index ec175af188..aa0af50528 100644 --- a/integration/container/export_test.go +++ b/integration/container/export_test.go @@ -47,7 +47,7 @@ func TestExportContainerAndImportImage(t *testing.T) { Filters: make(client.Filters).Add("reference", reference), }) assert.NilError(t, err) - assert.Check(t, is.Equal(jm.Status, images.Images[0].ID)) + assert.Check(t, is.Equal(jm.Status, images.Items[0].ID)) } // TestExportContainerAfterDaemonRestart checks that a container diff --git a/integration/daemon/migration_test.go b/integration/daemon/migration_test.go index 91f26312ec..8d9e0fbc0d 100644 --- a/integration/daemon/migration_test.go +++ b/integration/daemon/migration_test.go @@ -136,7 +136,7 @@ func TestMigrateSaveLoad(t *testing.T) { // Delete all images list, err := apiClient.ImageList(ctx, client.ImageListOptions{}) assert.NilError(t, err) - for _, i := range list { + for _, i := range list.Items { _, err = apiClient.ImageRemove(ctx, i.ID, client.ImageRemoveOptions{Force: true}) assert.NilError(t, err) } diff --git a/integration/image/list_test.go b/integration/image/list_test.go index 9d0f69eb85..b368f5e80b 100644 --- a/integration/image/list_test.go +++ b/integration/image/list_test.go @@ -43,12 +43,12 @@ func TestImagesFilterMultiReference(t *testing.T) { options := client.ImageListOptions{ Filters: make(client.Filters).Add("reference", repoTags[:3]...), } - images, err := apiClient.ImageList(ctx, options) + imageList, err := apiClient.ImageList(ctx, options) assert.NilError(t, err) - assert.Assert(t, is.Len(images, 1)) - assert.Check(t, is.Len(images[0].RepoTags, 3)) - for _, repoTag := range images[0].RepoTags { + assert.Assert(t, is.Len(imageList.Items, 1)) + assert.Check(t, is.Len(imageList.Items[0].RepoTags, 3)) + for _, repoTag := range imageList.Items[0].RepoTags { if repoTag != repoTags[0] && repoTag != repoTags[1] && repoTag != repoTags[2] { t.Errorf("list images doesn't match any repoTag we expected, repoTag: %s", repoTag) } @@ -91,7 +91,7 @@ func TestImagesFilterUntil(t *testing.T) { assert.NilError(t, err) var listedIDs []string - for _, i := range list { + for _, i := range list.Items { t.Logf("ImageList: ID=%v RepoTags=%v", i.ID, i.RepoTags) listedIDs = append(listedIDs, i.ID) } @@ -124,7 +124,7 @@ func TestImagesFilterBeforeSince(t *testing.T) { assert.NilError(t, err) var listedIDs []string - for _, i := range list { + for _, i := range list.Items { t.Logf("ImageList: ID=%v RepoTags=%v", i.ID, i.RepoTags) listedIDs = append(listedIDs, i.ID) } @@ -181,12 +181,12 @@ func TestAPIImagesFilters(t *testing.T) { t.Parallel() ctx := testutil.StartSpan(ctx, t) - images, err := apiClient.ImageList(ctx, client.ImageListOptions{ + imageList, err := apiClient.ImageList(ctx, client.ImageListOptions{ Filters: tc.filters, }) assert.Check(t, err) - assert.Assert(t, is.Len(images, tc.expectedImages)) - assert.Check(t, is.Len(images[0].RepoTags, tc.expectedRepoTags)) + assert.Assert(t, is.Len(imageList.Items, tc.expectedImages)) + assert.Check(t, is.Len(imageList.Items[0].RepoTags, tc.expectedRepoTags)) }) } } @@ -255,31 +255,31 @@ func TestAPIImagesListManifests(t *testing.T) { // TODO: Remove when MinAPIVersion >= 1.47 c := d.NewClientT(t, client.WithVersion("1.46")) - images, err := c.ImageList(ctx, client.ImageListOptions{Manifests: true}) + imageList, err := c.ImageList(ctx, client.ImageListOptions{Manifests: true}) assert.NilError(t, err) - assert.Assert(t, is.Len(images, 1)) - assert.Check(t, is.Nil(images[0].Manifests)) + assert.Assert(t, is.Len(imageList.Items, 1)) + assert.Check(t, is.Nil(imageList.Items[0].Manifests)) }) api147 := d.NewClientT(t, client.WithVersion("1.47")) t.Run("no manifests if not requested", func(t *testing.T) { - images, err := api147.ImageList(ctx, client.ImageListOptions{}) + imageList, err := api147.ImageList(ctx, client.ImageListOptions{}) assert.NilError(t, err) - assert.Assert(t, is.Len(images, 1)) - assert.Check(t, is.Nil(images[0].Manifests)) + assert.Assert(t, is.Len(imageList.Items, 1)) + assert.Check(t, is.Nil(imageList.Items[0].Manifests)) }) - images, err := api147.ImageList(ctx, client.ImageListOptions{Manifests: true}) + imageList, err := api147.ImageList(ctx, client.ImageListOptions{Manifests: true}) assert.NilError(t, err) - assert.Check(t, is.Len(images, 1)) - assert.Check(t, images[0].Manifests != nil) - assert.Check(t, is.Len(images[0].Manifests, 3)) + assert.Check(t, is.Len(imageList.Items, 1)) + assert.Check(t, imageList.Items[0].Manifests != nil) + assert.Check(t, is.Len(imageList.Items[0].Manifests, 3)) - for _, mfst := range images[0].Manifests { + for _, mfst := range imageList.Items[0].Manifests { // All manifests should be image manifests assert.Check(t, is.Equal(mfst.Kind, image.ManifestKindImage)) diff --git a/integration/image/load_test.go b/integration/image/load_test.go index eebf71be90..e93f76d920 100644 --- a/integration/image/load_test.go +++ b/integration/image/load_test.go @@ -29,7 +29,7 @@ func TestLoadDanglingImages(t *testing.T) { }) // Should be one image. - images, err := apiClient.ImageList(ctx, client.ImageListOptions{}) + imageList, err := apiClient.ImageList(ctx, client.ImageListOptions{}) assert.NilError(t, err) findImageByName := func(images []image.Summary, imageName string) (image.Summary, error) { @@ -42,7 +42,7 @@ func TestLoadDanglingImages(t *testing.T) { return images[index], nil } - oldImage, err := findImageByName(images, "namedimage:latest") + oldImage, err := findImageByName(imageList.Items, "namedimage:latest") assert.NilError(t, err) // Retain a copy of the old image and then replace it with a new one. @@ -52,10 +52,10 @@ func TestLoadDanglingImages(t *testing.T) { }) }) - images, err = apiClient.ImageList(ctx, client.ImageListOptions{}) + imageList, err = apiClient.ImageList(ctx, client.ImageListOptions{}) assert.NilError(t, err) - newImage, err := findImageByName(images, "namedimage:latest") + newImage, err := findImageByName(imageList.Items, "namedimage:latest") assert.NilError(t, err) // IDs should be different. @@ -72,7 +72,7 @@ func TestLoadDanglingImages(t *testing.T) { return images[index], nil } - danglingImage, err := findImageById(images, oldImage.ID) + danglingImage, err := findImageById(imageList.Items, oldImage.ID) assert.NilError(t, err) assert.Check(t, is.Len(danglingImage.RepoTags, 0)) } diff --git a/internal/testutil/environment/clean.go b/internal/testutil/environment/clean.go index d208c719e9..ef2b990145 100644 --- a/internal/testutil/environment/clean.go +++ b/internal/testutil/environment/clean.go @@ -94,10 +94,10 @@ func getAllContainers(ctx context.Context, t testing.TB, apiClient client.Contai func deleteAllImages(ctx context.Context, t testing.TB, apiclient client.ImageAPIClient, protectedImages map[string]struct{}) { t.Helper() - images, err := apiclient.ImageList(ctx, client.ImageListOptions{}) + imageList, err := apiclient.ImageList(ctx, client.ImageListOptions{}) assert.Check(t, err, "failed to list images") - for _, img := range images { + for _, img := range imageList.Items { tags := tagsFromImageSummary(img) if _, ok := protectedImages[img.ID]; ok { continue diff --git a/internal/testutil/environment/environment.go b/internal/testutil/environment/environment.go index 4e89658118..c55b396dbe 100644 --- a/internal/testutil/environment/environment.go +++ b/internal/testutil/environment/environment.go @@ -205,7 +205,7 @@ func (e *Execution) HasExistingImage(t testing.TB, reference string) bool { }) assert.NilError(t, err, "failed to list images") - return len(imageList) > 0 + return len(imageList.Items) > 0 } // EnsureFrozenImagesLinux loads frozen test images into the daemon diff --git a/internal/testutil/environment/protect.go b/internal/testutil/environment/protect.go index 8fbff2827b..073659f4bc 100644 --- a/internal/testutil/environment/protect.go +++ b/internal/testutil/environment/protect.go @@ -121,7 +121,7 @@ func getExistingImages(ctx context.Context, t testing.TB, testEnv *Execution) [] assert.NilError(t, err, "failed to list images") var images []string - for _, img := range imageList { + for _, img := range imageList.Items { images = append(images, tagsFromImageSummary(img)...) } return images diff --git a/vendor/github.com/moby/moby/client/client_interfaces.go b/vendor/github.com/moby/moby/client/client_interfaces.go index 86f9be8022..554ba8e8f5 100644 --- a/vendor/github.com/moby/moby/client/client_interfaces.go +++ b/vendor/github.com/moby/moby/client/client_interfaces.go @@ -111,7 +111,7 @@ type ImageAPIClient interface { ImageCreate(ctx context.Context, parentReference string, options ImageCreateOptions) (ImageCreateResult, error) ImageImport(ctx context.Context, source ImageImportSource, ref string, options ImageImportOptions) (ImageImportResult, error) - ImageList(ctx context.Context, options ImageListOptions) ([]image.Summary, error) + ImageList(ctx context.Context, options ImageListOptions) (ImageListResult, error) ImagePull(ctx context.Context, ref string, options ImagePullOptions) (ImagePullResponse, error) ImagePush(ctx context.Context, ref string, options ImagePushOptions) (ImagePushResponse, error) ImageRemove(ctx context.Context, image string, options ImageRemoveOptions) ([]image.DeleteResponse, error) diff --git a/vendor/github.com/moby/moby/client/image_list.go b/vendor/github.com/moby/moby/client/image_list.go index d2516d80d3..955422c137 100644 --- a/vendor/github.com/moby/moby/client/image_list.go +++ b/vendor/github.com/moby/moby/client/image_list.go @@ -15,7 +15,7 @@ import ( // to include [image.Summary.Manifests] with information about image manifests. // This is experimental and might change in the future without any backward // compatibility. -func (cli *Client) ImageList(ctx context.Context, options ImageListOptions) ([]image.Summary, error) { +func (cli *Client) ImageList(ctx context.Context, options ImageListOptions) (ImageListResult, error) { var images []image.Summary query := url.Values{} @@ -34,7 +34,7 @@ func (cli *Client) ImageList(ctx context.Context, options ImageListOptions) ([]i // Normally, version-negotiation (if enabled) would not happen until // the API request is made. if err := cli.checkVersion(ctx); err != nil { - return images, err + return ImageListResult{}, err } if versions.GreaterThanOrEqualTo(cli.version, "1.47") { @@ -45,9 +45,9 @@ func (cli *Client) ImageList(ctx context.Context, options ImageListOptions) ([]i resp, err := cli.get(ctx, "/images/json", query, nil) defer ensureReaderClosed(resp) if err != nil { - return images, err + return ImageListResult{}, err } err = json.NewDecoder(resp.Body).Decode(&images) - return images, err + return ImageListResult{Items: images}, err } diff --git a/vendor/github.com/moby/moby/client/image_list_opts.go b/vendor/github.com/moby/moby/client/image_list_opts.go index 2bd6deb897..a497d5790e 100644 --- a/vendor/github.com/moby/moby/client/image_list_opts.go +++ b/vendor/github.com/moby/moby/client/image_list_opts.go @@ -1,5 +1,7 @@ package client +import "github.com/moby/moby/api/types/image" + // ImageListOptions holds parameters to list images with. type ImageListOptions struct { // All controls whether all images in the graph are filtered, or just @@ -15,3 +17,8 @@ type ImageListOptions struct { // Manifests indicates whether the image manifests should be returned. Manifests bool } + +// ImageListResult holds the result from ImageList. +type ImageListResult struct { + Items []image.Summary +}