mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
client: Client.ImageImport: close reader on context cancellation
Use a cancelReadCloser to automatically close the reader when the context is cancelled. Consumers are still recommended to manually close the reader, but the cancelReadCloser makes the Close idempotent. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
27
vendor/github.com/moby/moby/client/image_import.go
generated
vendored
27
vendor/github.com/moby/moby/client/image_import.go
generated
vendored
@@ -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()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user