From a7f409014f89e20171792a17b6565eae07cb519b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Gronowski?= Date: Mon, 20 Oct 2025 20:15:04 +0200 Subject: [PATCH] client/image_create&import: Wrap options and result MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Paweł Gronowski --- client/client_interfaces.go | 4 ++-- client/image_create.go | 9 ++++----- client/image_create_opts.go | 7 +++++++ client/image_create_test.go | 6 +++--- client/image_import.go | 9 ++++----- client/image_import_opts.go | 16 ++++++++++++++++ client/image_import_test.go | 6 +++--- integration/container/export_test.go | 10 +++++----- .../moby/moby/client/client_interfaces.go | 4 ++-- .../github.com/moby/moby/client/image_create.go | 9 ++++----- .../moby/moby/client/image_create_opts.go | 7 +++++++ .../github.com/moby/moby/client/image_import.go | 9 ++++----- .../moby/moby/client/image_import_opts.go | 16 ++++++++++++++++ 13 files changed, 77 insertions(+), 35 deletions(-) diff --git a/client/client_interfaces.go b/client/client_interfaces.go index 3d4a9209fd..86f9be8022 100644 --- a/client/client_interfaces.go +++ b/client/client_interfaces.go @@ -108,8 +108,8 @@ type ImageAPIClient interface { ImageBuild(ctx context.Context, context io.Reader, options ImageBuildOptions) (ImageBuildResult, error) BuildCachePrune(ctx context.Context, opts BuildCachePruneOptions) (BuildCachePruneResult, error) BuildCancel(ctx context.Context, id string, opts BuildCancelOptions) (BuildCancelResult, error) - ImageCreate(ctx context.Context, parentReference string, options ImageCreateOptions) (io.ReadCloser, error) - ImageImport(ctx context.Context, source ImageImportSource, ref string, options ImageImportOptions) (io.ReadCloser, error) + 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) ImagePull(ctx context.Context, ref string, options ImagePullOptions) (ImagePullResponse, error) diff --git a/client/image_create.go b/client/image_create.go index 12bd38f3db..25e8a57ecc 100644 --- a/client/image_create.go +++ b/client/image_create.go @@ -2,7 +2,6 @@ package client import ( "context" - "io" "net/http" "net/url" "strings" @@ -13,10 +12,10 @@ import ( // ImageCreate creates a new image based on the parent options. // It returns the JSON content in the response body. -func (cli *Client) ImageCreate(ctx context.Context, parentReference string, options ImageCreateOptions) (io.ReadCloser, error) { +func (cli *Client) ImageCreate(ctx context.Context, parentReference string, options ImageCreateOptions) (ImageCreateResult, error) { ref, err := reference.ParseNormalizedNamed(parentReference) if err != nil { - return nil, err + return ImageCreateResult{}, err } query := url.Values{} @@ -27,9 +26,9 @@ func (cli *Client) ImageCreate(ctx context.Context, parentReference string, opti } resp, err := cli.tryImageCreate(ctx, query, staticAuth(options.RegistryAuth)) if err != nil { - return nil, err + return ImageCreateResult{}, err } - return resp.Body, nil + return ImageCreateResult{Body: resp.Body}, nil } func (cli *Client) tryImageCreate(ctx context.Context, query url.Values, resolveAuth registry.RequestAuthConfig) (*http.Response, error) { diff --git a/client/image_create_opts.go b/client/image_create_opts.go index a55f35d4db..301cf0bb81 100644 --- a/client/image_create_opts.go +++ b/client/image_create_opts.go @@ -1,7 +1,14 @@ package client +import "io" + // ImageCreateOptions holds information to create images. type ImageCreateOptions struct { RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry. Platform string // Platform is the target platform of the image if it needs to be pulled from the registry. } + +// ImageCreateResult holds the response body returned by the daemon for image create. +type ImageCreateResult struct { + Body io.ReadCloser +} diff --git a/client/image_create_test.go b/client/image_create_test.go index 25156d21fc..fba0caf6ac 100644 --- a/client/image_create_test.go +++ b/client/image_create_test.go @@ -57,13 +57,13 @@ func TestImageCreate(t *testing.T) { })) assert.NilError(t, err) - createResponse, err := client.ImageCreate(context.Background(), specifiedReference, ImageCreateOptions{ + createResult, err := client.ImageCreate(context.Background(), specifiedReference, ImageCreateOptions{ RegistryAuth: expectedRegistryAuth, }) assert.NilError(t, err) - response, err := io.ReadAll(createResponse) + response, err := io.ReadAll(createResult.Body) assert.NilError(t, err) - err = createResponse.Close() + err = createResult.Body.Close() assert.NilError(t, err) assert.Check(t, is.Equal(string(response), "body")) } diff --git a/client/image_import.go b/client/image_import.go index 9db6a21033..ca0fa1d0f6 100644 --- a/client/image_import.go +++ b/client/image_import.go @@ -2,7 +2,6 @@ package client import ( "context" - "io" "net/url" "strings" @@ -11,11 +10,11 @@ import ( // ImageImport creates a new image based on the source options. // It returns the JSON content in the response body. -func (cli *Client) ImageImport(ctx context.Context, source ImageImportSource, ref string, options ImageImportOptions) (io.ReadCloser, error) { +func (cli *Client) ImageImport(ctx context.Context, source ImageImportSource, ref string, options ImageImportOptions) (ImageImportResult, error) { if ref != "" { // Check if the given image name can be resolved if _, err := reference.ParseNormalizedNamed(ref); err != nil { - return nil, err + return ImageImportResult{}, err } } @@ -41,7 +40,7 @@ func (cli *Client) ImageImport(ctx context.Context, source ImageImportSource, re resp, err := cli.postRaw(ctx, "/images/create", query, source.Source, nil) if err != nil { - return nil, err + return ImageImportResult{}, err } - return resp.Body, nil + return ImageImportResult{body: resp.Body}, nil } diff --git a/client/image_import_opts.go b/client/image_import_opts.go index c0c1c1b6de..44ea0e2caa 100644 --- a/client/image_import_opts.go +++ b/client/image_import_opts.go @@ -17,3 +17,19 @@ type ImageImportOptions struct { Changes []string // Changes are the raw changes to apply to this image Platform string // Platform is the target platform of the image } + +// ImageImportResult holds the response body returned by the daemon for image import. +type ImageImportResult struct { + body io.ReadCloser +} + +func (r ImageImportResult) Read(p []byte) (n int, err error) { + return r.body.Read(p) +} + +func (r ImageImportResult) Close() error { + if r.body == nil { + return nil + } + return r.body.Close() +} diff --git a/client/image_import_test.go b/client/image_import_test.go index 28b34d3c01..571d60bd66 100644 --- a/client/image_import_test.go +++ b/client/image_import_test.go @@ -77,14 +77,14 @@ func TestImageImport(t *testing.T) { }, nil })) assert.NilError(t, err) - resp, err := client.ImageImport(context.Background(), ImageImportSource{ + result, err := client.ImageImport(context.Background(), ImageImportSource{ Source: strings.NewReader("source"), SourceName: "image_source", }, "repository_name:imported", tc.options) assert.NilError(t, err) - defer assert.NilError(t, resp.Close()) + defer assert.NilError(t, result.Close()) - body, err := io.ReadAll(resp) + body, err := io.ReadAll(result) assert.NilError(t, err) assert.Check(t, is.Equal(string(body), expectedOutput)) }) diff --git a/integration/container/export_test.go b/integration/container/export_test.go index dda6305648..ec175af188 100644 --- a/integration/container/export_test.go +++ b/integration/container/export_test.go @@ -27,10 +27,10 @@ func TestExportContainerAndImportImage(t *testing.T) { poll.WaitOn(t, container.IsStopped(ctx, apiClient, cID)) reference := "repo/" + strings.ToLower(t.Name()) + ":v1" - exportResp, err := apiClient.ContainerExport(ctx, cID) + exportRes, err := apiClient.ContainerExport(ctx, cID) assert.NilError(t, err) - importResp, err := apiClient.ImageImport(ctx, client.ImageImportSource{ - Source: exportResp, + importRes, err := apiClient.ImageImport(ctx, client.ImageImportSource{ + Source: exportRes, SourceName: "-", }, reference, client.ImageImportOptions{}) assert.NilError(t, err) @@ -38,7 +38,7 @@ func TestExportContainerAndImportImage(t *testing.T) { // If the import is successfully, then the message output should contain // the image ID and match with the output from `docker images`. - dec := json.NewDecoder(importResp) + dec := json.NewDecoder(importRes) var jm jsonmessage.JSONMessage err = dec.Decode(&jm) assert.NilError(t, err) @@ -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[0].ID)) + assert.Check(t, is.Equal(jm.Status, images.Images[0].ID)) } // TestExportContainerAfterDaemonRestart checks that a container diff --git a/vendor/github.com/moby/moby/client/client_interfaces.go b/vendor/github.com/moby/moby/client/client_interfaces.go index 3d4a9209fd..86f9be8022 100644 --- a/vendor/github.com/moby/moby/client/client_interfaces.go +++ b/vendor/github.com/moby/moby/client/client_interfaces.go @@ -108,8 +108,8 @@ type ImageAPIClient interface { ImageBuild(ctx context.Context, context io.Reader, options ImageBuildOptions) (ImageBuildResult, error) BuildCachePrune(ctx context.Context, opts BuildCachePruneOptions) (BuildCachePruneResult, error) BuildCancel(ctx context.Context, id string, opts BuildCancelOptions) (BuildCancelResult, error) - ImageCreate(ctx context.Context, parentReference string, options ImageCreateOptions) (io.ReadCloser, error) - ImageImport(ctx context.Context, source ImageImportSource, ref string, options ImageImportOptions) (io.ReadCloser, error) + 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) ImagePull(ctx context.Context, ref string, options ImagePullOptions) (ImagePullResponse, error) diff --git a/vendor/github.com/moby/moby/client/image_create.go b/vendor/github.com/moby/moby/client/image_create.go index 12bd38f3db..25e8a57ecc 100644 --- a/vendor/github.com/moby/moby/client/image_create.go +++ b/vendor/github.com/moby/moby/client/image_create.go @@ -2,7 +2,6 @@ package client import ( "context" - "io" "net/http" "net/url" "strings" @@ -13,10 +12,10 @@ import ( // ImageCreate creates a new image based on the parent options. // It returns the JSON content in the response body. -func (cli *Client) ImageCreate(ctx context.Context, parentReference string, options ImageCreateOptions) (io.ReadCloser, error) { +func (cli *Client) ImageCreate(ctx context.Context, parentReference string, options ImageCreateOptions) (ImageCreateResult, error) { ref, err := reference.ParseNormalizedNamed(parentReference) if err != nil { - return nil, err + return ImageCreateResult{}, err } query := url.Values{} @@ -27,9 +26,9 @@ func (cli *Client) ImageCreate(ctx context.Context, parentReference string, opti } resp, err := cli.tryImageCreate(ctx, query, staticAuth(options.RegistryAuth)) if err != nil { - return nil, err + return ImageCreateResult{}, err } - return resp.Body, nil + return ImageCreateResult{Body: resp.Body}, nil } func (cli *Client) tryImageCreate(ctx context.Context, query url.Values, resolveAuth registry.RequestAuthConfig) (*http.Response, error) { diff --git a/vendor/github.com/moby/moby/client/image_create_opts.go b/vendor/github.com/moby/moby/client/image_create_opts.go index a55f35d4db..301cf0bb81 100644 --- a/vendor/github.com/moby/moby/client/image_create_opts.go +++ b/vendor/github.com/moby/moby/client/image_create_opts.go @@ -1,7 +1,14 @@ package client +import "io" + // ImageCreateOptions holds information to create images. type ImageCreateOptions struct { RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry. Platform string // Platform is the target platform of the image if it needs to be pulled from the registry. } + +// ImageCreateResult holds the response body returned by the daemon for image create. +type ImageCreateResult struct { + Body io.ReadCloser +} diff --git a/vendor/github.com/moby/moby/client/image_import.go b/vendor/github.com/moby/moby/client/image_import.go index 9db6a21033..ca0fa1d0f6 100644 --- a/vendor/github.com/moby/moby/client/image_import.go +++ b/vendor/github.com/moby/moby/client/image_import.go @@ -2,7 +2,6 @@ package client import ( "context" - "io" "net/url" "strings" @@ -11,11 +10,11 @@ import ( // ImageImport creates a new image based on the source options. // It returns the JSON content in the response body. -func (cli *Client) ImageImport(ctx context.Context, source ImageImportSource, ref string, options ImageImportOptions) (io.ReadCloser, error) { +func (cli *Client) ImageImport(ctx context.Context, source ImageImportSource, ref string, options ImageImportOptions) (ImageImportResult, error) { if ref != "" { // Check if the given image name can be resolved if _, err := reference.ParseNormalizedNamed(ref); err != nil { - return nil, err + return ImageImportResult{}, err } } @@ -41,7 +40,7 @@ func (cli *Client) ImageImport(ctx context.Context, source ImageImportSource, re resp, err := cli.postRaw(ctx, "/images/create", query, source.Source, nil) if err != nil { - return nil, err + return ImageImportResult{}, err } - return resp.Body, nil + return ImageImportResult{body: resp.Body}, nil } diff --git a/vendor/github.com/moby/moby/client/image_import_opts.go b/vendor/github.com/moby/moby/client/image_import_opts.go index c0c1c1b6de..44ea0e2caa 100644 --- a/vendor/github.com/moby/moby/client/image_import_opts.go +++ b/vendor/github.com/moby/moby/client/image_import_opts.go @@ -17,3 +17,19 @@ type ImageImportOptions struct { Changes []string // Changes are the raw changes to apply to this image Platform string // Platform is the target platform of the image } + +// ImageImportResult holds the response body returned by the daemon for image import. +type ImageImportResult struct { + body io.ReadCloser +} + +func (r ImageImportResult) Read(p []byte) (n int, err error) { + return r.body.Read(p) +} + +func (r ImageImportResult) Close() error { + if r.body == nil { + return nil + } + return r.body.Close() +}