mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
client/image_(inspect,history,load,save): Wrap return values
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com> Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
committed by
Sebastiaan van Stijn
parent
7066eb3736
commit
2d69edd28a
@@ -119,10 +119,10 @@ type ImageAPIClient interface {
|
|||||||
ImageTag(ctx context.Context, image, ref string) error
|
ImageTag(ctx context.Context, image, ref string) error
|
||||||
ImagesPrune(ctx context.Context, opts ImagePruneOptions) (ImagePruneResult, error)
|
ImagesPrune(ctx context.Context, opts ImagePruneOptions) (ImagePruneResult, error)
|
||||||
|
|
||||||
ImageInspect(ctx context.Context, image string, _ ...ImageInspectOption) (image.InspectResponse, error)
|
ImageInspect(ctx context.Context, image string, _ ...ImageInspectOption) (ImageInspectResult, error)
|
||||||
ImageHistory(ctx context.Context, image string, _ ...ImageHistoryOption) ([]image.HistoryResponseItem, error)
|
ImageHistory(ctx context.Context, image string, _ ...ImageHistoryOption) (ImageHistoryResult, error)
|
||||||
ImageLoad(ctx context.Context, input io.Reader, _ ...ImageLoadOption) (LoadResponse, error)
|
ImageLoad(ctx context.Context, input io.Reader, _ ...ImageLoadOption) (ImageLoadResult, error)
|
||||||
ImageSave(ctx context.Context, images []string, _ ...ImageSaveOption) (io.ReadCloser, error)
|
ImageSave(ctx context.Context, images []string, _ ...ImageSaveOption) (ImageSaveResult, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetworkAPIClient defines API client methods for the networks
|
// NetworkAPIClient defines API client methods for the networks
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/moby/moby/api/types/image"
|
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -22,24 +21,24 @@ func ImageHistoryWithPlatform(platform ocispec.Platform) ImageHistoryOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ImageHistory returns the changes in an image in history format.
|
// ImageHistory returns the changes in an image in history format.
|
||||||
func (cli *Client) ImageHistory(ctx context.Context, imageID string, historyOpts ...ImageHistoryOption) ([]image.HistoryResponseItem, error) {
|
func (cli *Client) ImageHistory(ctx context.Context, imageID string, historyOpts ...ImageHistoryOption) (ImageHistoryResult, error) {
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
|
|
||||||
var opts imageHistoryOpts
|
var opts imageHistoryOpts
|
||||||
for _, o := range historyOpts {
|
for _, o := range historyOpts {
|
||||||
if err := o.Apply(&opts); err != nil {
|
if err := o.Apply(&opts); err != nil {
|
||||||
return nil, err
|
return ImageHistoryResult{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.apiOptions.Platform != nil {
|
if opts.apiOptions.Platform != nil {
|
||||||
if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil {
|
if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil {
|
||||||
return nil, err
|
return ImageHistoryResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := encodePlatform(opts.apiOptions.Platform)
|
p, err := encodePlatform(opts.apiOptions.Platform)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return ImageHistoryResult{}, err
|
||||||
}
|
}
|
||||||
query.Set("platform", p)
|
query.Set("platform", p)
|
||||||
}
|
}
|
||||||
@@ -47,10 +46,10 @@ func (cli *Client) ImageHistory(ctx context.Context, imageID string, historyOpts
|
|||||||
resp, err := cli.get(ctx, "/images/"+imageID+"/history", query, nil)
|
resp, err := cli.get(ctx, "/images/"+imageID+"/history", query, nil)
|
||||||
defer ensureReaderClosed(resp)
|
defer ensureReaderClosed(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return ImageHistoryResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var history []image.HistoryResponseItem
|
var history ImageHistoryResult
|
||||||
err = json.NewDecoder(resp.Body).Decode(&history)
|
err = json.NewDecoder(resp.Body).Decode(&history.Items)
|
||||||
return history, err
|
return history, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
import (
|
||||||
|
"github.com/moby/moby/api/types/image"
|
||||||
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
|
)
|
||||||
|
|
||||||
// ImageHistoryOption is a type representing functional options for the image history operation.
|
// ImageHistoryOption is a type representing functional options for the image history operation.
|
||||||
type ImageHistoryOption interface {
|
type ImageHistoryOption interface {
|
||||||
@@ -20,3 +23,7 @@ type imageHistoryOptions struct {
|
|||||||
// Platform from the manifest list to use for history.
|
// Platform from the manifest list to use for history.
|
||||||
Platform *ocispec.Platform
|
Platform *ocispec.Platform
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ImageHistoryResult struct {
|
||||||
|
Items []image.HistoryResponseItem
|
||||||
|
}
|
||||||
|
|||||||
@@ -36,16 +36,17 @@ func TestImageHistory(t *testing.T) {
|
|||||||
}, nil
|
}, nil
|
||||||
}))
|
}))
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
expected := []image.HistoryResponseItem{
|
expected := ImageHistoryResult{
|
||||||
{
|
Items: []image.HistoryResponseItem{
|
||||||
ID: "image_id1",
|
{
|
||||||
Tags: []string{"tag1", "tag2"},
|
ID: "image_id1",
|
||||||
},
|
Tags: []string{"tag1", "tag2"},
|
||||||
{
|
},
|
||||||
ID: "image_id2",
|
{
|
||||||
Tags: []string{"tag1", "tag2"},
|
ID: "image_id2",
|
||||||
},
|
Tags: []string{"tag1", "tag2"},
|
||||||
}
|
},
|
||||||
|
}}
|
||||||
|
|
||||||
imageHistories, err := client.ImageHistory(context.Background(), "image_id", ImageHistoryWithPlatform(ocispec.Platform{
|
imageHistories, err := client.ImageHistory(context.Background(), "image_id", ImageHistoryWithPlatform(ocispec.Platform{
|
||||||
Architecture: "arm64",
|
Architecture: "arm64",
|
||||||
|
|||||||
@@ -7,38 +7,36 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/moby/moby/api/types/image"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ImageInspect returns the image information.
|
// ImageInspect returns the image information.
|
||||||
func (cli *Client) ImageInspect(ctx context.Context, imageID string, inspectOpts ...ImageInspectOption) (image.InspectResponse, error) {
|
func (cli *Client) ImageInspect(ctx context.Context, imageID string, inspectOpts ...ImageInspectOption) (ImageInspectResult, error) {
|
||||||
if imageID == "" {
|
if imageID == "" {
|
||||||
return image.InspectResponse{}, objectNotFoundError{object: "image", id: imageID}
|
return ImageInspectResult{}, objectNotFoundError{object: "image", id: imageID}
|
||||||
}
|
}
|
||||||
|
|
||||||
var opts imageInspectOpts
|
var opts imageInspectOpts
|
||||||
for _, opt := range inspectOpts {
|
for _, opt := range inspectOpts {
|
||||||
if err := opt.Apply(&opts); err != nil {
|
if err := opt.Apply(&opts); err != nil {
|
||||||
return image.InspectResponse{}, fmt.Errorf("error applying image inspect option: %w", err)
|
return ImageInspectResult{}, fmt.Errorf("error applying image inspect option: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
if opts.apiOptions.Manifests {
|
if opts.apiOptions.Manifests {
|
||||||
if err := cli.NewVersionError(ctx, "1.48", "manifests"); err != nil {
|
if err := cli.NewVersionError(ctx, "1.48", "manifests"); err != nil {
|
||||||
return image.InspectResponse{}, err
|
return ImageInspectResult{}, err
|
||||||
}
|
}
|
||||||
query.Set("manifests", "1")
|
query.Set("manifests", "1")
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.apiOptions.Platform != nil {
|
if opts.apiOptions.Platform != nil {
|
||||||
if err := cli.NewVersionError(ctx, "1.49", "platform"); err != nil {
|
if err := cli.NewVersionError(ctx, "1.49", "platform"); err != nil {
|
||||||
return image.InspectResponse{}, err
|
return ImageInspectResult{}, err
|
||||||
}
|
}
|
||||||
platform, err := encodePlatform(opts.apiOptions.Platform)
|
platform, err := encodePlatform(opts.apiOptions.Platform)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return image.InspectResponse{}, err
|
return ImageInspectResult{}, err
|
||||||
}
|
}
|
||||||
query.Set("platform", platform)
|
query.Set("platform", platform)
|
||||||
}
|
}
|
||||||
@@ -46,7 +44,7 @@ func (cli *Client) ImageInspect(ctx context.Context, imageID string, inspectOpts
|
|||||||
resp, err := cli.get(ctx, "/images/"+imageID+"/json", query, nil)
|
resp, err := cli.get(ctx, "/images/"+imageID+"/json", query, nil)
|
||||||
defer ensureReaderClosed(resp)
|
defer ensureReaderClosed(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return image.InspectResponse{}, err
|
return ImageInspectResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := opts.raw
|
buf := opts.raw
|
||||||
@@ -55,10 +53,10 @@ func (cli *Client) ImageInspect(ctx context.Context, imageID string, inspectOpts
|
|||||||
}
|
}
|
||||||
|
|
||||||
if _, err := io.Copy(buf, resp.Body); err != nil {
|
if _, err := io.Copy(buf, resp.Body); err != nil {
|
||||||
return image.InspectResponse{}, err
|
return ImageInspectResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var response image.InspectResponse
|
var response ImageInspectResult
|
||||||
err = json.Unmarshal(buf.Bytes(), &response)
|
err = json.Unmarshal(buf.Bytes(), &response)
|
||||||
return response, err
|
return response, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package client
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
|
||||||
|
"github.com/moby/moby/api/types/image"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -62,3 +63,7 @@ type imageInspectOptions struct {
|
|||||||
// This option is only available for API version 1.49 and up.
|
// This option is only available for API version 1.49 and up.
|
||||||
Platform *ocispec.Platform
|
Platform *ocispec.Platform
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ImageInspectResult struct {
|
||||||
|
image.InspectResponse
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,16 +9,16 @@ import (
|
|||||||
|
|
||||||
// ImageLoad loads an image in the docker host from the client host.
|
// ImageLoad loads an image in the docker host from the client host.
|
||||||
// It's up to the caller to close the [io.ReadCloser] in the
|
// It's up to the caller to close the [io.ReadCloser] in the
|
||||||
// [image.LoadResponse] returned by this function.
|
// [ImageLoadResult] returned by this function.
|
||||||
//
|
//
|
||||||
// Platform is an optional parameter that specifies the platform to load from
|
// Platform is an optional parameter that specifies the platform to load from
|
||||||
// the provided multi-platform image. Passing a platform only has an effect
|
// the provided multi-platform image. Passing a platform only has an effect
|
||||||
// if the input image is a multi-platform image.
|
// if the input image is a multi-platform image.
|
||||||
func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, loadOpts ...ImageLoadOption) (LoadResponse, error) {
|
func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, loadOpts ...ImageLoadOption) (ImageLoadResult, error) {
|
||||||
var opts imageLoadOpts
|
var opts imageLoadOpts
|
||||||
for _, opt := range loadOpts {
|
for _, opt := range loadOpts {
|
||||||
if err := opt.Apply(&opts); err != nil {
|
if err := opt.Apply(&opts); err != nil {
|
||||||
return LoadResponse{}, err
|
return ImageLoadResult{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,12 +29,12 @@ func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, loadOpts ...I
|
|||||||
}
|
}
|
||||||
if len(opts.apiOptions.Platforms) > 0 {
|
if len(opts.apiOptions.Platforms) > 0 {
|
||||||
if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil {
|
if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil {
|
||||||
return LoadResponse{}, err
|
return ImageLoadResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := encodePlatforms(opts.apiOptions.Platforms...)
|
p, err := encodePlatforms(opts.apiOptions.Platforms...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return LoadResponse{}, err
|
return ImageLoadResult{}, err
|
||||||
}
|
}
|
||||||
query["platform"] = p
|
query["platform"] = p
|
||||||
}
|
}
|
||||||
@@ -43,10 +43,10 @@ func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, loadOpts ...I
|
|||||||
"Content-Type": {"application/x-tar"},
|
"Content-Type": {"application/x-tar"},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return LoadResponse{}, err
|
return ImageLoadResult{}, err
|
||||||
}
|
}
|
||||||
return LoadResponse{
|
return ImageLoadResult{
|
||||||
Body: resp.Body,
|
body: resp.Body,
|
||||||
JSON: resp.Header.Get("Content-Type") == "application/json",
|
JSON: resp.Header.Get("Content-Type") == "application/json",
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@@ -73,8 +73,19 @@ func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, loadOpts ...I
|
|||||||
//
|
//
|
||||||
// We should deprecated the "quiet" option, as it's really a client
|
// We should deprecated the "quiet" option, as it's really a client
|
||||||
// responsibility.
|
// responsibility.
|
||||||
type LoadResponse struct {
|
type ImageLoadResult struct {
|
||||||
// Body must be closed to avoid a resource leak
|
// Body must be closed to avoid a resource leak
|
||||||
Body io.ReadCloser
|
body io.ReadCloser
|
||||||
JSON bool
|
JSON bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r ImageLoadResult) Read(p []byte) (n int, err error) {
|
||||||
|
return r.body.Read(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r ImageLoadResult) Close() error {
|
||||||
|
if r.body == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return r.body.Close()
|
||||||
|
}
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ func TestImageLoad(t *testing.T) {
|
|||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Check(t, is.Equal(imageLoadResponse.JSON, tc.expectedResponseJSON))
|
assert.Check(t, is.Equal(imageLoadResponse.JSON, tc.expectedResponseJSON))
|
||||||
|
|
||||||
body, err := io.ReadAll(imageLoadResponse.Body)
|
body, err := io.ReadAll(imageLoadResponse)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Check(t, is.Equal(string(body), expectedOutput))
|
assert.Check(t, is.Equal(string(body), expectedOutput))
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,21 +2,20 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ImageSave retrieves one or more images from the docker host as an
|
// ImageSave retrieves one or more images from the docker host as an
|
||||||
// [io.ReadCloser].
|
// [ImageSaveResult].
|
||||||
//
|
//
|
||||||
// Platforms is an optional parameter that specifies the platforms to save
|
// Platforms is an optional parameter that specifies the platforms to save
|
||||||
// from the image. Passing a platform only has an effect if the input image
|
// from the image. Passing a platform only has an effect if the input image
|
||||||
// is a multi-platform image.
|
// is a multi-platform image.
|
||||||
func (cli *Client) ImageSave(ctx context.Context, imageIDs []string, saveOpts ...ImageSaveOption) (io.ReadCloser, error) {
|
func (cli *Client) ImageSave(ctx context.Context, imageIDs []string, saveOpts ...ImageSaveOption) (ImageSaveResult, error) {
|
||||||
var opts imageSaveOpts
|
var opts imageSaveOpts
|
||||||
for _, opt := range saveOpts {
|
for _, opt := range saveOpts {
|
||||||
if err := opt.Apply(&opts); err != nil {
|
if err := opt.Apply(&opts); err != nil {
|
||||||
return nil, err
|
return ImageSaveResult{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,18 +25,18 @@ func (cli *Client) ImageSave(ctx context.Context, imageIDs []string, saveOpts ..
|
|||||||
|
|
||||||
if len(opts.apiOptions.Platforms) > 0 {
|
if len(opts.apiOptions.Platforms) > 0 {
|
||||||
if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil {
|
if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil {
|
||||||
return nil, err
|
return ImageSaveResult{}, err
|
||||||
}
|
}
|
||||||
p, err := encodePlatforms(opts.apiOptions.Platforms...)
|
p, err := encodePlatforms(opts.apiOptions.Platforms...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return ImageSaveResult{}, err
|
||||||
}
|
}
|
||||||
query["platform"] = p
|
query["platform"] = p
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := cli.get(ctx, "/images/get", query, nil)
|
resp, err := cli.get(ctx, "/images/get", query, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return ImageSaveResult{}, err
|
||||||
}
|
}
|
||||||
return resp.Body, nil
|
return newImageSaveResult(resp.Body), nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"sync"
|
||||||
|
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
@@ -36,3 +38,34 @@ type imageSaveOptions struct {
|
|||||||
// multi-platform image and has multiple variants.
|
// multi-platform image and has multiple variants.
|
||||||
Platforms []ocispec.Platform
|
Platforms []ocispec.Platform
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newImageSaveResult(rc io.ReadCloser) ImageSaveResult {
|
||||||
|
if rc == nil {
|
||||||
|
panic("nil io.ReadCloser")
|
||||||
|
}
|
||||||
|
return ImageSaveResult{
|
||||||
|
rc: rc,
|
||||||
|
close: sync.OnceValue(rc.Close),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ImageSaveResult struct {
|
||||||
|
rc io.ReadCloser
|
||||||
|
close func() error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read implements io.ReadCloser
|
||||||
|
func (r ImageSaveResult) Read(p []byte) (n int, err error) {
|
||||||
|
if r.rc == nil {
|
||||||
|
return 0, io.EOF
|
||||||
|
}
|
||||||
|
return r.rc.Read(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close implements io.ReadCloser
|
||||||
|
func (r ImageSaveResult) Close() error {
|
||||||
|
if r.close == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return r.close()
|
||||||
|
}
|
||||||
|
|||||||
@@ -111,6 +111,6 @@ func TestBuildSquashParent(t *testing.T) {
|
|||||||
|
|
||||||
inspect, err = apiClient.ImageInspect(ctx, name)
|
inspect, err = apiClient.ImageInspect(ctx, name)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Check(t, is.Len(testHistory, len(origHistory)+1))
|
assert.Check(t, is.Len(testHistory.Items, len(origHistory.Items)+1))
|
||||||
assert.Check(t, is.Len(inspect.RootFS.Layers, 2))
|
assert.Check(t, is.Len(inspect.RootFS.Layers, 2))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,9 +105,9 @@ func TestBuildUserNamespaceValidateCapabilitiesAreV2(t *testing.T) {
|
|||||||
tarReader := bufio.NewReader(tarFile)
|
tarReader := bufio.NewReader(tarFile)
|
||||||
loadResp, err := clientNoUserRemap.ImageLoad(ctx, tarReader)
|
loadResp, err := clientNoUserRemap.ImageLoad(ctx, tarReader)
|
||||||
assert.NilError(t, err, "failed to load image tar file")
|
assert.NilError(t, err, "failed to load image tar file")
|
||||||
defer loadResp.Body.Close()
|
defer loadResp.Close()
|
||||||
buf = bytes.NewBuffer(nil)
|
buf = bytes.NewBuffer(nil)
|
||||||
err = jsonmessage.DisplayJSONMessagesStream(loadResp.Body, buf, 0, false, nil)
|
err = jsonmessage.DisplayJSONMessagesStream(loadResp, buf, 0, false, nil)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
cid := container.Run(ctx, t, clientNoUserRemap,
|
cid := container.Run(ctx, t, clientNoUserRemap,
|
||||||
|
|||||||
@@ -148,8 +148,8 @@ func TestMigrateSaveLoad(t *testing.T) {
|
|||||||
// Import
|
// Import
|
||||||
lr, err := apiClient.ImageLoad(ctx, bytes.NewReader(buf.Bytes()), client.ImageLoadWithQuiet(true))
|
lr, err := apiClient.ImageLoad(ctx, bytes.NewReader(buf.Bytes()), client.ImageLoadWithQuiet(true))
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
io.Copy(io.Discard, lr.Body)
|
io.Copy(io.Discard, lr)
|
||||||
lr.Body.Close()
|
lr.Close()
|
||||||
|
|
||||||
result := container.RunAttach(ctx, t, apiClient, func(c *container.TestContainerConfig) {
|
result := container.RunAttach(ctx, t, apiClient, func(c *container.TestContainerConfig) {
|
||||||
c.Name = "Migration-save-load-" + snapshotter
|
c.Name = "Migration-save-load-" + snapshotter
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ func TestAPIImagesHistory(t *testing.T) {
|
|||||||
|
|
||||||
imgID := build.Do(ctx, t, client, fakecontext.New(t, t.TempDir(), fakecontext.WithDockerfile(dockerfile)))
|
imgID := build.Do(ctx, t, client, fakecontext.New(t, t.TempDir(), fakecontext.WithDockerfile(dockerfile)))
|
||||||
|
|
||||||
historydata, err := client.ImageHistory(ctx, imgID)
|
res, err := client.ImageHistory(ctx, imgID)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
assert.Assert(t, len(historydata) != 0)
|
assert.Assert(t, len(res.Items) != 0)
|
||||||
|
|
||||||
var found bool
|
var found bool
|
||||||
for _, imageLayer := range historydata {
|
for _, imageLayer := range res.Items {
|
||||||
if imageLayer.ID == imgID {
|
if imageLayer.ID == imgID {
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
@@ -107,20 +107,20 @@ func TestAPIImageHistoryCrossPlatform(t *testing.T) {
|
|||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
ctx := testutil.StartSpan(ctx, t)
|
ctx := testutil.StartSpan(ctx, t)
|
||||||
|
|
||||||
hist, err := apiClient.ImageHistory(ctx, tc.imageRef, tc.options...)
|
res, err := apiClient.ImageHistory(ctx, tc.imageRef, tc.options...)
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
found := false
|
found := false
|
||||||
for _, layer := range hist {
|
for _, layer := range res.Items {
|
||||||
if layer.ID == imgID {
|
if layer.ID == imgID {
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert.Assert(t, found, "History should contain the built image ID")
|
assert.Assert(t, found, "History should contain the built image ID")
|
||||||
assert.Assert(t, is.Len(hist, 3))
|
assert.Assert(t, is.Len(res.Items, 3))
|
||||||
|
|
||||||
for i, layer := range hist {
|
for i, layer := range res.Items {
|
||||||
assert.Assert(t, layer.Size >= 0, "Layer %d should not have negative size", i)
|
assert.Assert(t, layer.Size >= 0, "Layer %d should not have negative size", i)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -145,29 +145,29 @@ func TestPruneDontDeleteUsedImage(t *testing.T) {
|
|||||||
} {
|
} {
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
name string
|
name string
|
||||||
imageID func(t *testing.T, inspect image.InspectResponse) string
|
imageID func(t *testing.T, inspect client.ImageInspectResult) string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "full id",
|
name: "full id",
|
||||||
imageID: func(t *testing.T, inspect image.InspectResponse) string {
|
imageID: func(t *testing.T, inspect client.ImageInspectResult) string {
|
||||||
return inspect.ID
|
return inspect.ID
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "full id without sha256 prefix",
|
name: "full id without sha256 prefix",
|
||||||
imageID: func(t *testing.T, inspect image.InspectResponse) string {
|
imageID: func(t *testing.T, inspect client.ImageInspectResult) string {
|
||||||
return strings.TrimPrefix(inspect.ID, "sha256:")
|
return strings.TrimPrefix(inspect.ID, "sha256:")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "truncated id (without sha256 prefix)",
|
name: "truncated id (without sha256 prefix)",
|
||||||
imageID: func(t *testing.T, inspect image.InspectResponse) string {
|
imageID: func(t *testing.T, inspect client.ImageInspectResult) string {
|
||||||
return strings.TrimPrefix(inspect.ID, "sha256:")[:8]
|
return strings.TrimPrefix(inspect.ID, "sha256:")[:8]
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "repo and digest without tag",
|
name: "repo and digest without tag",
|
||||||
imageID: func(t *testing.T, inspect image.InspectResponse) string {
|
imageID: func(t *testing.T, inspect client.ImageInspectResult) string {
|
||||||
skip.If(t, !testEnv.UsingSnapshotter())
|
skip.If(t, !testEnv.UsingSnapshotter())
|
||||||
|
|
||||||
return "busybox@" + inspect.ID
|
return "busybox@" + inspect.ID
|
||||||
@@ -175,7 +175,7 @@ func TestPruneDontDeleteUsedImage(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "tagged and digested",
|
name: "tagged and digested",
|
||||||
imageID: func(t *testing.T, inspect image.InspectResponse) string {
|
imageID: func(t *testing.T, inspect client.ImageInspectResult) string {
|
||||||
skip.If(t, !testEnv.UsingSnapshotter())
|
skip.If(t, !testEnv.UsingSnapshotter())
|
||||||
|
|
||||||
return "busybox:latest@" + inspect.ID
|
return "busybox:latest@" + inspect.ID
|
||||||
@@ -183,7 +183,7 @@ func TestPruneDontDeleteUsedImage(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "repo digest",
|
name: "repo digest",
|
||||||
imageID: func(t *testing.T, inspect image.InspectResponse) string {
|
imageID: func(t *testing.T, inspect client.ImageInspectResult) string {
|
||||||
// graphdriver won't have a repo digest
|
// graphdriver won't have a repo digest
|
||||||
skip.If(t, len(inspect.RepoDigests) == 0, "no repo digest")
|
skip.If(t, len(inspect.RepoDigests) == 0, "no repo digest")
|
||||||
|
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ func TestRemoveByDigest(t *testing.T) {
|
|||||||
|
|
||||||
inspect, err = apiClient.ImageInspect(ctx, "test-remove-by-digest")
|
inspect, err = apiClient.ImageInspect(ctx, "test-remove-by-digest")
|
||||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound))
|
assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound))
|
||||||
assert.Check(t, is.DeepEqual(inspect, image.InspectResponse{}))
|
assert.Check(t, is.DeepEqual(inspect, client.ImageInspectResult{}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRemoveWithPlatform(t *testing.T) {
|
func TestRemoveWithPlatform(t *testing.T) {
|
||||||
|
|||||||
@@ -328,8 +328,8 @@ func TestSaveAndLoadPlatform(t *testing.T) {
|
|||||||
// load the full exported image (all platforms in it)
|
// load the full exported image (all platforms in it)
|
||||||
resp, err := apiClient.ImageLoad(ctx, rdr)
|
resp, err := apiClient.ImageLoad(ctx, rdr)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
_, err = io.ReadAll(resp.Body)
|
_, err = io.ReadAll(resp)
|
||||||
resp.Body.Close()
|
resp.Close()
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
rdr.Close()
|
rdr.Close()
|
||||||
@@ -366,8 +366,8 @@ func TestSaveAndLoadPlatform(t *testing.T) {
|
|||||||
// load the exported image on the specified platforms only
|
// load the exported image on the specified platforms only
|
||||||
resp, err = apiClient.ImageLoad(ctx, rdr, client.ImageLoadWithPlatforms(tc.loadPlatforms...))
|
resp, err = apiClient.ImageLoad(ctx, rdr, client.ImageLoadWithPlatforms(tc.loadPlatforms...))
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
_, err = io.ReadAll(resp.Body)
|
_, err = io.ReadAll(resp)
|
||||||
resp.Body.Close()
|
resp.Close()
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
rdr.Close()
|
rdr.Close()
|
||||||
|
|||||||
@@ -30,10 +30,10 @@ func Load(ctx context.Context, t *testing.T, apiClient client.APIClient, imageFu
|
|||||||
resp, err := apiClient.ImageLoad(ctx, rc, client.ImageLoadWithQuiet(true))
|
resp, err := apiClient.ImageLoad(ctx, rc, client.ImageLoadWithQuiet(true))
|
||||||
assert.NilError(t, err, "Failed to load dangling image")
|
assert.NilError(t, err, "Failed to load dangling image")
|
||||||
|
|
||||||
defer resp.Body.Close()
|
defer resp.Close()
|
||||||
|
|
||||||
if !assert.Check(t, err) {
|
if !assert.Check(t, err) {
|
||||||
respBody, err := io.ReadAll(resp.Body)
|
respBody, err := io.ReadAll(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to read response body: %v", err)
|
t.Fatalf("Failed to read response body: %v", err)
|
||||||
return ""
|
return ""
|
||||||
@@ -41,7 +41,7 @@ func Load(ctx context.Context, t *testing.T, apiClient client.APIClient, imageFu
|
|||||||
t.Fatalf("Failed load: %s", string(respBody))
|
t.Fatalf("Failed load: %s", string(respBody))
|
||||||
}
|
}
|
||||||
|
|
||||||
all, err := io.ReadAll(resp.Body)
|
all, err := io.ReadAll(resp)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
decoder := json.NewDecoder(bytes.NewReader(all))
|
decoder := json.NewDecoder(bytes.NewReader(all))
|
||||||
|
|||||||
@@ -448,7 +448,7 @@ func imageLoad(ctx context.Context, apiClient client.APIClient, path string) err
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer response.Body.Close()
|
defer response.Close()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -886,7 +886,7 @@ func (d *Daemon) LoadImage(ctx context.Context, t testing.TB, img string) {
|
|||||||
|
|
||||||
resp, err := c.ImageLoad(ctx, reader, client.ImageLoadWithQuiet(true))
|
resp, err := c.ImageLoad(ctx, reader, client.ImageLoadWithQuiet(true))
|
||||||
assert.NilError(t, err, "[%s] failed to load %s", d.id, img)
|
assert.NilError(t, err, "[%s] failed to load %s", d.id, img)
|
||||||
defer resp.Body.Close()
|
defer resp.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Daemon) getClientConfig() (*clientConfig, error) {
|
func (d *Daemon) getClientConfig() (*clientConfig, error) {
|
||||||
|
|||||||
@@ -114,9 +114,9 @@ func loadFrozenImages(ctx context.Context, apiClient client.APIClient) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to load frozen images")
|
return errors.Wrap(err, "failed to load frozen images")
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Close()
|
||||||
fd, isTerminal := term.GetFdInfo(os.Stdout)
|
fd, isTerminal := term.GetFdInfo(os.Stdout)
|
||||||
return jsonmessage.DisplayJSONMessagesStream(resp.Body, os.Stdout, fd, isTerminal, nil)
|
return jsonmessage.DisplayJSONMessagesStream(resp, os.Stdout, fd, isTerminal, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func pullImages(ctx context.Context, client client.APIClient, images []string) error {
|
func pullImages(ctx context.Context, client client.APIClient, images []string) error {
|
||||||
|
|||||||
8
vendor/github.com/moby/moby/client/client_interfaces.go
generated
vendored
8
vendor/github.com/moby/moby/client/client_interfaces.go
generated
vendored
@@ -119,10 +119,10 @@ type ImageAPIClient interface {
|
|||||||
ImageTag(ctx context.Context, image, ref string) error
|
ImageTag(ctx context.Context, image, ref string) error
|
||||||
ImagesPrune(ctx context.Context, opts ImagePruneOptions) (ImagePruneResult, error)
|
ImagesPrune(ctx context.Context, opts ImagePruneOptions) (ImagePruneResult, error)
|
||||||
|
|
||||||
ImageInspect(ctx context.Context, image string, _ ...ImageInspectOption) (image.InspectResponse, error)
|
ImageInspect(ctx context.Context, image string, _ ...ImageInspectOption) (ImageInspectResult, error)
|
||||||
ImageHistory(ctx context.Context, image string, _ ...ImageHistoryOption) ([]image.HistoryResponseItem, error)
|
ImageHistory(ctx context.Context, image string, _ ...ImageHistoryOption) (ImageHistoryResult, error)
|
||||||
ImageLoad(ctx context.Context, input io.Reader, _ ...ImageLoadOption) (LoadResponse, error)
|
ImageLoad(ctx context.Context, input io.Reader, _ ...ImageLoadOption) (ImageLoadResult, error)
|
||||||
ImageSave(ctx context.Context, images []string, _ ...ImageSaveOption) (io.ReadCloser, error)
|
ImageSave(ctx context.Context, images []string, _ ...ImageSaveOption) (ImageSaveResult, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetworkAPIClient defines API client methods for the networks
|
// NetworkAPIClient defines API client methods for the networks
|
||||||
|
|||||||
15
vendor/github.com/moby/moby/client/image_history.go
generated
vendored
15
vendor/github.com/moby/moby/client/image_history.go
generated
vendored
@@ -6,7 +6,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/moby/moby/api/types/image"
|
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -22,24 +21,24 @@ func ImageHistoryWithPlatform(platform ocispec.Platform) ImageHistoryOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ImageHistory returns the changes in an image in history format.
|
// ImageHistory returns the changes in an image in history format.
|
||||||
func (cli *Client) ImageHistory(ctx context.Context, imageID string, historyOpts ...ImageHistoryOption) ([]image.HistoryResponseItem, error) {
|
func (cli *Client) ImageHistory(ctx context.Context, imageID string, historyOpts ...ImageHistoryOption) (ImageHistoryResult, error) {
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
|
|
||||||
var opts imageHistoryOpts
|
var opts imageHistoryOpts
|
||||||
for _, o := range historyOpts {
|
for _, o := range historyOpts {
|
||||||
if err := o.Apply(&opts); err != nil {
|
if err := o.Apply(&opts); err != nil {
|
||||||
return nil, err
|
return ImageHistoryResult{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.apiOptions.Platform != nil {
|
if opts.apiOptions.Platform != nil {
|
||||||
if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil {
|
if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil {
|
||||||
return nil, err
|
return ImageHistoryResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := encodePlatform(opts.apiOptions.Platform)
|
p, err := encodePlatform(opts.apiOptions.Platform)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return ImageHistoryResult{}, err
|
||||||
}
|
}
|
||||||
query.Set("platform", p)
|
query.Set("platform", p)
|
||||||
}
|
}
|
||||||
@@ -47,10 +46,10 @@ func (cli *Client) ImageHistory(ctx context.Context, imageID string, historyOpts
|
|||||||
resp, err := cli.get(ctx, "/images/"+imageID+"/history", query, nil)
|
resp, err := cli.get(ctx, "/images/"+imageID+"/history", query, nil)
|
||||||
defer ensureReaderClosed(resp)
|
defer ensureReaderClosed(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return ImageHistoryResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var history []image.HistoryResponseItem
|
var history ImageHistoryResult
|
||||||
err = json.NewDecoder(resp.Body).Decode(&history)
|
err = json.NewDecoder(resp.Body).Decode(&history.Items)
|
||||||
return history, err
|
return history, err
|
||||||
}
|
}
|
||||||
|
|||||||
9
vendor/github.com/moby/moby/client/image_history_opts.go
generated
vendored
9
vendor/github.com/moby/moby/client/image_history_opts.go
generated
vendored
@@ -1,6 +1,9 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
import (
|
||||||
|
"github.com/moby/moby/api/types/image"
|
||||||
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
|
)
|
||||||
|
|
||||||
// ImageHistoryOption is a type representing functional options for the image history operation.
|
// ImageHistoryOption is a type representing functional options for the image history operation.
|
||||||
type ImageHistoryOption interface {
|
type ImageHistoryOption interface {
|
||||||
@@ -20,3 +23,7 @@ type imageHistoryOptions struct {
|
|||||||
// Platform from the manifest list to use for history.
|
// Platform from the manifest list to use for history.
|
||||||
Platform *ocispec.Platform
|
Platform *ocispec.Platform
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ImageHistoryResult struct {
|
||||||
|
Items []image.HistoryResponseItem
|
||||||
|
}
|
||||||
|
|||||||
20
vendor/github.com/moby/moby/client/image_inspect.go
generated
vendored
20
vendor/github.com/moby/moby/client/image_inspect.go
generated
vendored
@@ -7,38 +7,36 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/moby/moby/api/types/image"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ImageInspect returns the image information.
|
// ImageInspect returns the image information.
|
||||||
func (cli *Client) ImageInspect(ctx context.Context, imageID string, inspectOpts ...ImageInspectOption) (image.InspectResponse, error) {
|
func (cli *Client) ImageInspect(ctx context.Context, imageID string, inspectOpts ...ImageInspectOption) (ImageInspectResult, error) {
|
||||||
if imageID == "" {
|
if imageID == "" {
|
||||||
return image.InspectResponse{}, objectNotFoundError{object: "image", id: imageID}
|
return ImageInspectResult{}, objectNotFoundError{object: "image", id: imageID}
|
||||||
}
|
}
|
||||||
|
|
||||||
var opts imageInspectOpts
|
var opts imageInspectOpts
|
||||||
for _, opt := range inspectOpts {
|
for _, opt := range inspectOpts {
|
||||||
if err := opt.Apply(&opts); err != nil {
|
if err := opt.Apply(&opts); err != nil {
|
||||||
return image.InspectResponse{}, fmt.Errorf("error applying image inspect option: %w", err)
|
return ImageInspectResult{}, fmt.Errorf("error applying image inspect option: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
if opts.apiOptions.Manifests {
|
if opts.apiOptions.Manifests {
|
||||||
if err := cli.NewVersionError(ctx, "1.48", "manifests"); err != nil {
|
if err := cli.NewVersionError(ctx, "1.48", "manifests"); err != nil {
|
||||||
return image.InspectResponse{}, err
|
return ImageInspectResult{}, err
|
||||||
}
|
}
|
||||||
query.Set("manifests", "1")
|
query.Set("manifests", "1")
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.apiOptions.Platform != nil {
|
if opts.apiOptions.Platform != nil {
|
||||||
if err := cli.NewVersionError(ctx, "1.49", "platform"); err != nil {
|
if err := cli.NewVersionError(ctx, "1.49", "platform"); err != nil {
|
||||||
return image.InspectResponse{}, err
|
return ImageInspectResult{}, err
|
||||||
}
|
}
|
||||||
platform, err := encodePlatform(opts.apiOptions.Platform)
|
platform, err := encodePlatform(opts.apiOptions.Platform)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return image.InspectResponse{}, err
|
return ImageInspectResult{}, err
|
||||||
}
|
}
|
||||||
query.Set("platform", platform)
|
query.Set("platform", platform)
|
||||||
}
|
}
|
||||||
@@ -46,7 +44,7 @@ func (cli *Client) ImageInspect(ctx context.Context, imageID string, inspectOpts
|
|||||||
resp, err := cli.get(ctx, "/images/"+imageID+"/json", query, nil)
|
resp, err := cli.get(ctx, "/images/"+imageID+"/json", query, nil)
|
||||||
defer ensureReaderClosed(resp)
|
defer ensureReaderClosed(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return image.InspectResponse{}, err
|
return ImageInspectResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := opts.raw
|
buf := opts.raw
|
||||||
@@ -55,10 +53,10 @@ func (cli *Client) ImageInspect(ctx context.Context, imageID string, inspectOpts
|
|||||||
}
|
}
|
||||||
|
|
||||||
if _, err := io.Copy(buf, resp.Body); err != nil {
|
if _, err := io.Copy(buf, resp.Body); err != nil {
|
||||||
return image.InspectResponse{}, err
|
return ImageInspectResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var response image.InspectResponse
|
var response ImageInspectResult
|
||||||
err = json.Unmarshal(buf.Bytes(), &response)
|
err = json.Unmarshal(buf.Bytes(), &response)
|
||||||
return response, err
|
return response, err
|
||||||
}
|
}
|
||||||
|
|||||||
5
vendor/github.com/moby/moby/client/image_inspect_opts.go
generated
vendored
5
vendor/github.com/moby/moby/client/image_inspect_opts.go
generated
vendored
@@ -3,6 +3,7 @@ package client
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
|
||||||
|
"github.com/moby/moby/api/types/image"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -62,3 +63,7 @@ type imageInspectOptions struct {
|
|||||||
// This option is only available for API version 1.49 and up.
|
// This option is only available for API version 1.49 and up.
|
||||||
Platform *ocispec.Platform
|
Platform *ocispec.Platform
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ImageInspectResult struct {
|
||||||
|
image.InspectResponse
|
||||||
|
}
|
||||||
|
|||||||
31
vendor/github.com/moby/moby/client/image_load.go
generated
vendored
31
vendor/github.com/moby/moby/client/image_load.go
generated
vendored
@@ -9,16 +9,16 @@ import (
|
|||||||
|
|
||||||
// ImageLoad loads an image in the docker host from the client host.
|
// ImageLoad loads an image in the docker host from the client host.
|
||||||
// It's up to the caller to close the [io.ReadCloser] in the
|
// It's up to the caller to close the [io.ReadCloser] in the
|
||||||
// [image.LoadResponse] returned by this function.
|
// [ImageLoadResult] returned by this function.
|
||||||
//
|
//
|
||||||
// Platform is an optional parameter that specifies the platform to load from
|
// Platform is an optional parameter that specifies the platform to load from
|
||||||
// the provided multi-platform image. Passing a platform only has an effect
|
// the provided multi-platform image. Passing a platform only has an effect
|
||||||
// if the input image is a multi-platform image.
|
// if the input image is a multi-platform image.
|
||||||
func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, loadOpts ...ImageLoadOption) (LoadResponse, error) {
|
func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, loadOpts ...ImageLoadOption) (ImageLoadResult, error) {
|
||||||
var opts imageLoadOpts
|
var opts imageLoadOpts
|
||||||
for _, opt := range loadOpts {
|
for _, opt := range loadOpts {
|
||||||
if err := opt.Apply(&opts); err != nil {
|
if err := opt.Apply(&opts); err != nil {
|
||||||
return LoadResponse{}, err
|
return ImageLoadResult{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,12 +29,12 @@ func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, loadOpts ...I
|
|||||||
}
|
}
|
||||||
if len(opts.apiOptions.Platforms) > 0 {
|
if len(opts.apiOptions.Platforms) > 0 {
|
||||||
if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil {
|
if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil {
|
||||||
return LoadResponse{}, err
|
return ImageLoadResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := encodePlatforms(opts.apiOptions.Platforms...)
|
p, err := encodePlatforms(opts.apiOptions.Platforms...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return LoadResponse{}, err
|
return ImageLoadResult{}, err
|
||||||
}
|
}
|
||||||
query["platform"] = p
|
query["platform"] = p
|
||||||
}
|
}
|
||||||
@@ -43,10 +43,10 @@ func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, loadOpts ...I
|
|||||||
"Content-Type": {"application/x-tar"},
|
"Content-Type": {"application/x-tar"},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return LoadResponse{}, err
|
return ImageLoadResult{}, err
|
||||||
}
|
}
|
||||||
return LoadResponse{
|
return ImageLoadResult{
|
||||||
Body: resp.Body,
|
body: resp.Body,
|
||||||
JSON: resp.Header.Get("Content-Type") == "application/json",
|
JSON: resp.Header.Get("Content-Type") == "application/json",
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@@ -73,8 +73,19 @@ func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, loadOpts ...I
|
|||||||
//
|
//
|
||||||
// We should deprecated the "quiet" option, as it's really a client
|
// We should deprecated the "quiet" option, as it's really a client
|
||||||
// responsibility.
|
// responsibility.
|
||||||
type LoadResponse struct {
|
type ImageLoadResult struct {
|
||||||
// Body must be closed to avoid a resource leak
|
// Body must be closed to avoid a resource leak
|
||||||
Body io.ReadCloser
|
body io.ReadCloser
|
||||||
JSON bool
|
JSON bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r ImageLoadResult) Read(p []byte) (n int, err error) {
|
||||||
|
return r.body.Read(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r ImageLoadResult) Close() error {
|
||||||
|
if r.body == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return r.body.Close()
|
||||||
|
}
|
||||||
|
|||||||
15
vendor/github.com/moby/moby/client/image_save.go
generated
vendored
15
vendor/github.com/moby/moby/client/image_save.go
generated
vendored
@@ -2,21 +2,20 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ImageSave retrieves one or more images from the docker host as an
|
// ImageSave retrieves one or more images from the docker host as an
|
||||||
// [io.ReadCloser].
|
// [ImageSaveResult].
|
||||||
//
|
//
|
||||||
// Platforms is an optional parameter that specifies the platforms to save
|
// Platforms is an optional parameter that specifies the platforms to save
|
||||||
// from the image. Passing a platform only has an effect if the input image
|
// from the image. Passing a platform only has an effect if the input image
|
||||||
// is a multi-platform image.
|
// is a multi-platform image.
|
||||||
func (cli *Client) ImageSave(ctx context.Context, imageIDs []string, saveOpts ...ImageSaveOption) (io.ReadCloser, error) {
|
func (cli *Client) ImageSave(ctx context.Context, imageIDs []string, saveOpts ...ImageSaveOption) (ImageSaveResult, error) {
|
||||||
var opts imageSaveOpts
|
var opts imageSaveOpts
|
||||||
for _, opt := range saveOpts {
|
for _, opt := range saveOpts {
|
||||||
if err := opt.Apply(&opts); err != nil {
|
if err := opt.Apply(&opts); err != nil {
|
||||||
return nil, err
|
return ImageSaveResult{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,18 +25,18 @@ func (cli *Client) ImageSave(ctx context.Context, imageIDs []string, saveOpts ..
|
|||||||
|
|
||||||
if len(opts.apiOptions.Platforms) > 0 {
|
if len(opts.apiOptions.Platforms) > 0 {
|
||||||
if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil {
|
if err := cli.NewVersionError(ctx, "1.48", "platform"); err != nil {
|
||||||
return nil, err
|
return ImageSaveResult{}, err
|
||||||
}
|
}
|
||||||
p, err := encodePlatforms(opts.apiOptions.Platforms...)
|
p, err := encodePlatforms(opts.apiOptions.Platforms...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return ImageSaveResult{}, err
|
||||||
}
|
}
|
||||||
query["platform"] = p
|
query["platform"] = p
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := cli.get(ctx, "/images/get", query, nil)
|
resp, err := cli.get(ctx, "/images/get", query, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return ImageSaveResult{}, err
|
||||||
}
|
}
|
||||||
return resp.Body, nil
|
return newImageSaveResult(resp.Body), nil
|
||||||
}
|
}
|
||||||
|
|||||||
33
vendor/github.com/moby/moby/client/image_save_opts.go
generated
vendored
33
vendor/github.com/moby/moby/client/image_save_opts.go
generated
vendored
@@ -2,6 +2,8 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"sync"
|
||||||
|
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
@@ -36,3 +38,34 @@ type imageSaveOptions struct {
|
|||||||
// multi-platform image and has multiple variants.
|
// multi-platform image and has multiple variants.
|
||||||
Platforms []ocispec.Platform
|
Platforms []ocispec.Platform
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newImageSaveResult(rc io.ReadCloser) ImageSaveResult {
|
||||||
|
if rc == nil {
|
||||||
|
panic("nil io.ReadCloser")
|
||||||
|
}
|
||||||
|
return ImageSaveResult{
|
||||||
|
rc: rc,
|
||||||
|
close: sync.OnceValue(rc.Close),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ImageSaveResult struct {
|
||||||
|
rc io.ReadCloser
|
||||||
|
close func() error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read implements io.ReadCloser
|
||||||
|
func (r ImageSaveResult) Read(p []byte) (n int, err error) {
|
||||||
|
if r.rc == nil {
|
||||||
|
return 0, io.EOF
|
||||||
|
}
|
||||||
|
return r.rc.Read(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close implements io.ReadCloser
|
||||||
|
func (r ImageSaveResult) Close() error {
|
||||||
|
if r.close == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return r.close()
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user