diff --git a/client/image_import.go b/client/image_import.go index a9121c4074..f383f76d49 100644 --- a/client/image_import.go +++ b/client/image_import.go @@ -13,8 +13,10 @@ type ImageImportResult interface { io.ReadCloser } -// ImageImport creates a new image based on the source options. -// It returns the JSON content in the response body. +// ImageImport creates a new image based on the source options. It returns the +// JSON content in the [ImageImportResult]. +// +// The underlying [io.ReadCloser] is automatically closed if the context is canceled, 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 @@ -48,30 +50,17 @@ func (cli *Client) ImageImport(ctx context.Context, source ImageImportSource, re if err != nil { return nil, err } - return &imageImportResult{body: resp.Body}, nil + return &imageImportResult{ + ReadCloser: newCancelReadCloser(ctx, resp.Body), + }, nil } // ImageImportResult holds the response body returned by the daemon for image import. type imageImportResult struct { - // body must be closed to avoid a resource leak - body io.ReadCloser + io.ReadCloser } var ( _ io.ReadCloser = (*imageImportResult)(nil) _ ImageImportResult = (*imageImportResult)(nil) ) - -func (r *imageImportResult) Read(p []byte) (int, error) { - if r == nil || r.body == nil { - return 0, io.EOF - } - return r.body.Read(p) -} - -func (r *imageImportResult) Close() error { - if r == nil || r.body == nil { - return nil - } - return r.body.Close() -} diff --git a/integration/container/export_test.go b/integration/container/export_test.go index e7ddaf913f..24c65755f2 100644 --- a/integration/container/export_test.go +++ b/integration/container/export_test.go @@ -34,6 +34,7 @@ func TestExportContainerAndImportImage(t *testing.T) { SourceName: "-", }, reference, client.ImageImportOptions{}) assert.NilError(t, err) + defer func() { _ = importRes.Close() }() // If the import is successfully, then the message output should contain // the image ID and match with the output from `docker images`. diff --git a/integration/plugin/authz/authz_plugin_test.go b/integration/plugin/authz/authz_plugin_test.go index 81cfe7d43d..809975428b 100644 --- a/integration/plugin/authz/authz_plugin_test.go +++ b/integration/plugin/authz/authz_plugin_test.go @@ -460,17 +460,17 @@ func imageImport(ctx context.Context, apiClient client.APIClient, path string) e return err } defer file.Close() - options := client.ImageImportOptions{} ref := "" source := client.ImageImportSource{ Source: file, SourceName: "-", } - responseReader, err := apiClient.ImageImport(ctx, source, ref, options) + resp, err := apiClient.ImageImport(ctx, source, ref, client.ImageImportOptions{}) if err != nil { return err } - defer responseReader.Close() + _, _ = io.Copy(io.Discard, resp) + _ = resp.Close() return nil } diff --git a/vendor/github.com/moby/moby/client/image_import.go b/vendor/github.com/moby/moby/client/image_import.go index a9121c4074..f383f76d49 100644 --- a/vendor/github.com/moby/moby/client/image_import.go +++ b/vendor/github.com/moby/moby/client/image_import.go @@ -13,8 +13,10 @@ type ImageImportResult interface { io.ReadCloser } -// ImageImport creates a new image based on the source options. -// It returns the JSON content in the response body. +// ImageImport creates a new image based on the source options. It returns the +// JSON content in the [ImageImportResult]. +// +// The underlying [io.ReadCloser] is automatically closed if the context is canceled, 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 @@ -48,30 +50,17 @@ func (cli *Client) ImageImport(ctx context.Context, source ImageImportSource, re if err != nil { return nil, err } - return &imageImportResult{body: resp.Body}, nil + return &imageImportResult{ + ReadCloser: newCancelReadCloser(ctx, resp.Body), + }, nil } // ImageImportResult holds the response body returned by the daemon for image import. type imageImportResult struct { - // body must be closed to avoid a resource leak - body io.ReadCloser + io.ReadCloser } var ( _ io.ReadCloser = (*imageImportResult)(nil) _ ImageImportResult = (*imageImportResult)(nil) ) - -func (r *imageImportResult) Read(p []byte) (int, error) { - if r == nil || r.body == nil { - return 0, io.EOF - } - return r.body.Read(p) -} - -func (r *imageImportResult) Close() error { - if r == nil || r.body == nil { - return nil - } - return r.body.Close() -}