api/types/image: move image option types to client

Signed-off-by: Austin Vazquez <austin.vazquez@docker.com>
This commit is contained in:
Austin Vazquez
2025-08-20 10:28:23 -05:00
parent 531be96bf9
commit 853aed171b
77 changed files with 512 additions and 487 deletions

View File

@@ -1,124 +0,0 @@
package image
import (
"context"
"io"
"github.com/moby/moby/api/types/filters"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// ImportSource holds source information for ImageImport
type ImportSource struct {
Source io.Reader // Source is the data to send to the server to create this image from. You must set SourceName to "-" to leverage this.
SourceName string // SourceName is the name of the image to pull. Set to "-" to leverage the Source attribute.
}
// ImportOptions holds information to import images from the client host.
type ImportOptions struct {
Tag string // Tag is the name to tag this image with. This attribute is deprecated.
Message string // Message is the message to tag the image with
Changes []string // Changes are the raw changes to apply to this image
Platform string // Platform is the target platform of the image
}
// CreateOptions holds information to create images.
type CreateOptions 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.
}
// PullOptions holds information to pull images.
type PullOptions struct {
All bool
RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry
// PrivilegeFunc is a function that clients can supply to retry operations
// after getting an authorization error. This function returns the registry
// authentication header value in base64 encoded format, or an error if the
// privilege request fails.
//
// For details, refer to [github.com/moby/moby/api/types/registry.RequestAuthConfig].
PrivilegeFunc func(context.Context) (string, error)
Platform string
}
// PushOptions holds information to push images.
type PushOptions struct {
All bool
RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry
// PrivilegeFunc is a function that clients can supply to retry operations
// after getting an authorization error. This function returns the registry
// authentication header value in base64 encoded format, or an error if the
// privilege request fails.
//
// For details, refer to [github.com/moby/moby/api/types/registry.RequestAuthConfig].
PrivilegeFunc func(context.Context) (string, error)
// Platform is an optional field that selects a specific platform to push
// when the image is a multi-platform image.
// Using this will only push a single platform-specific manifest.
Platform *ocispec.Platform `json:",omitempty"`
}
// ListOptions holds parameters to list images with.
type ListOptions struct {
// All controls whether all images in the graph are filtered, or just
// the heads.
All bool
// Filters is a JSON-encoded set of filter arguments.
Filters filters.Args
// SharedSize indicates whether the shared size of images should be computed.
SharedSize bool
// ContainerCount indicates whether container count should be computed.
//
// Deprecated: This field has been unused and is no longer required and will be removed in a future version.
ContainerCount bool
// Manifests indicates whether the image manifests should be returned.
Manifests bool
}
// RemoveOptions holds parameters to remove images.
type RemoveOptions struct {
Platforms []ocispec.Platform
Force bool
PruneChildren bool
}
// HistoryOptions holds parameters to get image history.
type HistoryOptions struct {
// Platform from the manifest list to use for history.
Platform *ocispec.Platform
}
// LoadOptions holds parameters to load images.
type LoadOptions struct {
// Quiet suppresses progress output
Quiet bool
// Platforms selects the platforms to load if the image is a
// multi-platform image and has multiple variants.
Platforms []ocispec.Platform
}
type InspectOptions struct {
// Manifests returns the image manifests.
Manifests bool
// Platform selects the specific platform of a multi-platform image to inspect.
//
// This option is only available for API version 1.49 and up.
Platform *ocispec.Platform
}
// SaveOptions holds parameters to save images.
type SaveOptions struct {
// Platforms selects the platforms to save if the image is a
// multi-platform image and has multiple variants.
Platforms []ocispec.Platform
}

View File

@@ -109,13 +109,13 @@ type ImageAPIClient interface {
ImageBuild(ctx context.Context, context io.Reader, options build.ImageBuildOptions) (build.ImageBuildResponse, error)
BuildCachePrune(ctx context.Context, opts build.CachePruneOptions) (*build.CachePruneReport, error)
BuildCancel(ctx context.Context, id string) error
ImageCreate(ctx context.Context, parentReference string, options image.CreateOptions) (io.ReadCloser, error)
ImageImport(ctx context.Context, source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, 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)
ImageList(ctx context.Context, options image.ListOptions) ([]image.Summary, error)
ImagePull(ctx context.Context, ref string, options image.PullOptions) (io.ReadCloser, error)
ImagePush(ctx context.Context, ref string, options image.PushOptions) (io.ReadCloser, error)
ImageRemove(ctx context.Context, image string, options image.RemoveOptions) ([]image.DeleteResponse, error)
ImageList(ctx context.Context, options ImageListOptions) ([]image.Summary, error)
ImagePull(ctx context.Context, ref string, options ImagePullOptions) (io.ReadCloser, error)
ImagePush(ctx context.Context, ref string, options ImagePushOptions) (io.ReadCloser, error)
ImageRemove(ctx context.Context, image string, options ImageRemoveOptions) ([]image.DeleteResponse, error)
ImageSearch(ctx context.Context, term string, options ImageSearchOptions) ([]registry.SearchResult, error)
ImageTag(ctx context.Context, image, ref string) error
ImagesPrune(ctx context.Context, pruneFilter filters.Args) (image.PruneReport, error)

View File

@@ -8,13 +8,12 @@ import (
"strings"
"github.com/distribution/reference"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/registry"
)
// 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 image.CreateOptions) (io.ReadCloser, error) {
func (cli *Client) ImageCreate(ctx context.Context, parentReference string, options ImageCreateOptions) (io.ReadCloser, error) {
ref, err := reference.ParseNormalizedNamed(parentReference)
if err != nil {
return nil, err

View File

@@ -0,0 +1,7 @@
package client
// 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.
}

View File

@@ -10,7 +10,6 @@ import (
"testing"
cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/registry"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@@ -20,7 +19,7 @@ func TestImageCreateError(t *testing.T) {
client := &Client{
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ImageCreate(context.Background(), "reference", image.CreateOptions{})
_, err := client.ImageCreate(context.Background(), "reference", ImageCreateOptions{})
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal))
}
@@ -61,7 +60,7 @@ func TestImageCreate(t *testing.T) {
}),
}
createResponse, err := client.ImageCreate(context.Background(), specifiedReference, image.CreateOptions{
createResponse, err := client.ImageCreate(context.Background(), specifiedReference, ImageCreateOptions{
RegistryAuth: expectedRegistryAuth,
})
assert.NilError(t, err)

View File

@@ -1,8 +1,6 @@
package client
import (
"github.com/moby/moby/api/types/image"
)
import ocispec "github.com/opencontainers/image-spec/specs-go/v1"
// ImageHistoryOption is a type representing functional options for the image history operation.
type ImageHistoryOption interface {
@@ -15,5 +13,10 @@ func (f imageHistoryOptionFunc) Apply(o *imageHistoryOpts) error {
}
type imageHistoryOpts struct {
apiOptions image.HistoryOptions
apiOptions imageHistoryOptions
}
type imageHistoryOptions struct {
// Platform from the manifest list to use for history.
Platform *ocispec.Platform
}

View File

@@ -7,12 +7,11 @@ import (
"strings"
"github.com/distribution/reference"
"github.com/moby/moby/api/types/image"
)
// 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 image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) {
func (cli *Client) ImageImport(ctx context.Context, source ImageImportSource, ref string, options ImageImportOptions) (io.ReadCloser, error) {
if ref != "" {
// Check if the given image name can be resolved
if _, err := reference.ParseNormalizedNamed(ref); err != nil {

View File

@@ -0,0 +1,19 @@
package client
import (
"io"
)
// ImageImportSource holds source information for ImageImport
type ImageImportSource struct {
Source io.Reader // Source is the data to send to the server to create this image from. You must set SourceName to "-" to leverage this.
SourceName string // SourceName is the name of the image to pull. Set to "-" to leverage the Source attribute.
}
// ImageImportOptions holds information to import images from the client host.
type ImageImportOptions struct {
Tag string // Tag is the name to tag this image with. This attribute is deprecated.
Message string // Message is the message to tag the image with
Changes []string // Changes are the raw changes to apply to this image
Platform string // Platform is the target platform of the image
}

View File

@@ -10,7 +10,6 @@ import (
"testing"
cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/image"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
@@ -19,7 +18,7 @@ func TestImageImportError(t *testing.T) {
client := &Client{
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ImageImport(context.Background(), image.ImportSource{}, "image:tag", image.ImportOptions{})
_, err := client.ImageImport(context.Background(), ImageImportSource{}, "image:tag", ImageImportOptions{})
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal))
}
@@ -30,7 +29,7 @@ func TestImageImport(t *testing.T) {
)
tests := []struct {
doc string
options image.ImportOptions
options ImageImportOptions
expectedQueryParams url.Values
}{
{
@@ -42,7 +41,7 @@ func TestImageImport(t *testing.T) {
},
{
doc: "change options",
options: image.ImportOptions{
options: ImageImportOptions{
Tag: "imported",
Message: "A message",
Changes: []string{"change1", "change2"},
@@ -57,7 +56,7 @@ func TestImageImport(t *testing.T) {
},
{
doc: "with platform",
options: image.ImportOptions{
options: ImageImportOptions{
Platform: "linux/amd64",
},
expectedQueryParams: url.Values{
@@ -80,7 +79,7 @@ func TestImageImport(t *testing.T) {
}, nil
}),
}
resp, err := client.ImageImport(context.Background(), image.ImportSource{
resp, err := client.ImageImport(context.Background(), ImageImportSource{
Source: strings.NewReader("source"),
SourceName: "image_source",
}, "repository_name:imported", tc.options)

View File

@@ -3,7 +3,6 @@ package client
import (
"bytes"
"github.com/moby/moby/api/types/image"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
@@ -50,7 +49,7 @@ func ImageInspectWithPlatform(platform *ocispec.Platform) ImageInspectOption {
}
// ImageInspectWithAPIOpts sets the API options for the image inspect operation.
func ImageInspectWithAPIOpts(opts image.InspectOptions) ImageInspectOption {
func ImageInspectWithAPIOpts(opts ImageInspectOptions) ImageInspectOption {
return imageInspectOptionFunc(func(clientOpts *imageInspectOpts) error {
clientOpts.apiOptions = opts
return nil
@@ -59,5 +58,15 @@ func ImageInspectWithAPIOpts(opts image.InspectOptions) ImageInspectOption {
type imageInspectOpts struct {
raw *bytes.Buffer
apiOptions image.InspectOptions
apiOptions ImageInspectOptions
}
type ImageInspectOptions struct {
// Manifests returns the image manifests.
Manifests bool
// Platform selects the specific platform of a multi-platform image to inspect.
//
// This option is only available for API version 1.49 and up.
Platform *ocispec.Platform
}

View File

@@ -16,7 +16,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 image.ListOptions) ([]image.Summary, error) {
func (cli *Client) ImageList(ctx context.Context, options ImageListOptions) ([]image.Summary, error) {
var images []image.Summary
// Make sure we negotiated (if the client is configured to do so),

24
client/image_list_opts.go Normal file
View File

@@ -0,0 +1,24 @@
package client
import "github.com/moby/moby/api/types/filters"
// ImageListOptions holds parameters to list images with.
type ImageListOptions struct {
// All controls whether all images in the graph are filtered, or just
// the heads.
All bool
// Filters is a JSON-encoded set of filter arguments.
Filters filters.Args
// SharedSize indicates whether the shared size of images should be computed.
SharedSize bool
// ContainerCount indicates whether container count should be computed.
//
// Deprecated: This field has been unused and is no longer required and will be removed in a future version.
ContainerCount bool
// Manifests indicates whether the image manifests should be returned.
Manifests bool
}

View File

@@ -23,7 +23,7 @@ func TestImageListError(t *testing.T) {
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ImageList(context.Background(), image.ListOptions{})
_, err := client.ImageList(context.Background(), ImageListOptions{})
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal))
}
@@ -35,7 +35,7 @@ func TestImageListConnectionError(t *testing.T) {
client, err := NewClientWithOpts(WithAPIVersionNegotiation(), WithHost("tcp://no-such-host.invalid"))
assert.NilError(t, err)
_, err = client.ImageList(context.Background(), image.ListOptions{})
_, err = client.ImageList(context.Background(), ImageListOptions{})
assert.Check(t, is.ErrorType(err, IsErrConnectionFailed))
}
@@ -43,11 +43,11 @@ func TestImageList(t *testing.T) {
const expectedURL = "/images/json"
listCases := []struct {
options image.ListOptions
options ImageListOptions
expectedQueryParams map[string]string
}{
{
options: image.ListOptions{},
options: ImageListOptions{},
expectedQueryParams: map[string]string{
"all": "",
"filter": "",
@@ -55,7 +55,7 @@ func TestImageList(t *testing.T) {
},
},
{
options: image.ListOptions{
options: ImageListOptions{
Filters: filters.NewArgs(
filters.Arg("label", "label1"),
filters.Arg("label", "label2"),
@@ -69,7 +69,7 @@ func TestImageList(t *testing.T) {
},
},
{
options: image.ListOptions{
options: ImageListOptions{
Filters: filters.NewArgs(filters.Arg("dangling", "false")),
},
expectedQueryParams: map[string]string{
@@ -148,7 +148,7 @@ func TestImageListApiBefore125(t *testing.T) {
version: "1.24",
}
options := image.ListOptions{
options := ImageListOptions{
Filters: filters.NewArgs(filters.Arg("reference", "image:tag")),
}
@@ -165,12 +165,12 @@ func TestImageListWithSharedSize(t *testing.T) {
for _, tc := range []struct {
name string
version string
options image.ListOptions
options ImageListOptions
sharedSize string // expected value for the shared-size query param, or empty if it should not be set.
}{
{name: "unset after 1.42, no options set", version: "1.42"},
{name: "set after 1.42, if requested", version: "1.42", options: image.ListOptions{SharedSize: true}, sharedSize: "1"},
{name: "unset before 1.42, even if requested", version: "1.41", options: image.ListOptions{SharedSize: true}},
{name: "set after 1.42, if requested", version: "1.42", options: ImageListOptions{SharedSize: true}, sharedSize: "1"},
{name: "unset before 1.42, even if requested", version: "1.41", options: ImageListOptions{SharedSize: true}},
} {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()

View File

@@ -3,7 +3,6 @@ package client
import (
"fmt"
"github.com/moby/moby/api/types/image"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
@@ -18,7 +17,16 @@ func (f imageLoadOptionFunc) Apply(o *imageLoadOpts) error {
}
type imageLoadOpts struct {
apiOptions image.LoadOptions
apiOptions imageLoadOptions
}
type imageLoadOptions struct {
// Quiet suppresses progress output
Quiet bool
// Platforms selects the platforms to load if the image is a
// multi-platform image and has multiple variants.
Platforms []ocispec.Platform
}
// ImageLoadWithQuiet sets the quiet option for the image load operation.

View File

@@ -8,14 +8,13 @@ import (
cerrdefs "github.com/containerd/errdefs"
"github.com/distribution/reference"
"github.com/moby/moby/api/types/image"
)
// ImagePull requests the docker host to pull an image from a remote registry.
// It executes the privileged function if the operation is unauthorized
// and it tries one more time.
// It's up to the caller to handle the [io.ReadCloser] and close it.
func (cli *Client) ImagePull(ctx context.Context, refStr string, options image.PullOptions) (io.ReadCloser, error) {
func (cli *Client) ImagePull(ctx context.Context, refStr string, options ImagePullOptions) (io.ReadCloser, error) {
// FIXME(vdemeester): there is currently used in a few way in docker/docker
// - if not in trusted content, ref is used to pass the whole reference, and tag is empty
// - if in trusted content, ref is used to pass the reference name, and tag for the digest

18
client/image_pull_opts.go Normal file
View File

@@ -0,0 +1,18 @@
package client
import "context"
// ImagePullOptions holds information to pull images.
type ImagePullOptions struct {
All bool
RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry
// PrivilegeFunc is a function that clients can supply to retry operations
// after getting an authorization error. This function returns the registry
// authentication header value in base64 encoded format, or an error if the
// privilege request fails.
//
// For details, refer to [github.com/moby/moby/api/types/registry.RequestAuthConfig].
PrivilegeFunc func(context.Context) (string, error)
Platform string
}

View File

@@ -11,7 +11,6 @@ import (
"testing"
cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/registry"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@@ -24,7 +23,7 @@ func TestImagePullReferenceParseError(t *testing.T) {
}),
}
// An empty reference is an invalid reference
_, err := client.ImagePull(context.Background(), "", image.PullOptions{})
_, err := client.ImagePull(context.Background(), "", ImagePullOptions{})
assert.Check(t, is.ErrorContains(err, "invalid reference format"))
}
@@ -32,7 +31,7 @@ func TestImagePullAnyError(t *testing.T) {
client := &Client{
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ImagePull(context.Background(), "myimage", image.PullOptions{})
_, err := client.ImagePull(context.Background(), "myimage", ImagePullOptions{})
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal))
}
@@ -40,7 +39,7 @@ func TestImagePullStatusUnauthorizedError(t *testing.T) {
client := &Client{
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
}
_, err := client.ImagePull(context.Background(), "myimage", image.PullOptions{})
_, err := client.ImagePull(context.Background(), "myimage", ImagePullOptions{})
assert.Check(t, is.ErrorType(err, cerrdefs.IsUnauthorized))
}
@@ -48,7 +47,7 @@ func TestImagePullWithUnauthorizedErrorAndPrivilegeFuncError(t *testing.T) {
client := &Client{
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
}
_, err := client.ImagePull(context.Background(), "myimage", image.PullOptions{
_, err := client.ImagePull(context.Background(), "myimage", ImagePullOptions{
PrivilegeFunc: func(_ context.Context) (string, error) {
return "", errors.New("error requesting privilege")
},
@@ -60,7 +59,7 @@ func TestImagePullWithUnauthorizedErrorAndAnotherUnauthorizedError(t *testing.T)
client := &Client{
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
}
_, err := client.ImagePull(context.Background(), "myimage", image.PullOptions{
_, err := client.ImagePull(context.Background(), "myimage", ImagePullOptions{
PrivilegeFunc: staticAuth("a-auth-header"),
})
assert.Check(t, is.ErrorType(err, cerrdefs.IsUnauthorized))
@@ -100,7 +99,7 @@ func TestImagePullWithPrivilegedFuncNoError(t *testing.T) {
}, nil
}),
}
resp, err := client.ImagePull(context.Background(), "myimage", image.PullOptions{
resp, err := client.ImagePull(context.Background(), "myimage", ImagePullOptions{
RegistryAuth: invalidAuth,
PrivilegeFunc: staticAuth(validAuth),
})
@@ -193,7 +192,7 @@ func TestImagePullWithoutErrors(t *testing.T) {
}, nil
}),
}
resp, err := client.ImagePull(context.Background(), pullCase.reference, image.PullOptions{
resp, err := client.ImagePull(context.Background(), pullCase.reference, ImagePullOptions{
All: pullCase.all,
})
assert.NilError(t, err)

View File

@@ -11,7 +11,6 @@ import (
cerrdefs "github.com/containerd/errdefs"
"github.com/distribution/reference"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/registry"
)
@@ -19,7 +18,7 @@ import (
// It executes the privileged function if the operation is unauthorized
// and it tries one more time.
// It's up to the caller to handle the [io.ReadCloser] and close it.
func (cli *Client) ImagePush(ctx context.Context, image string, options image.PushOptions) (io.ReadCloser, error) {
func (cli *Client) ImagePush(ctx context.Context, image string, options ImagePushOptions) (io.ReadCloser, error) {
ref, err := reference.ParseNormalizedNamed(image)
if err != nil {
return nil, err

26
client/image_push_opts.go Normal file
View File

@@ -0,0 +1,26 @@
package client
import (
"context"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// ImagePushOptions holds information to push images.
type ImagePushOptions struct {
All bool
RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry
// PrivilegeFunc is a function that clients can supply to retry operations
// after getting an authorization error. This function returns the registry
// authentication header value in base64 encoded format, or an error if the
// privilege request fails.
//
// For details, refer to [github.com/moby/moby/api/types/registry.RequestAuthConfig].
PrivilegeFunc func(context.Context) (string, error)
// Platform is an optional field that selects a specific platform to push
// when the image is a multi-platform image.
// Using this will only push a single platform-specific manifest.
Platform *ocispec.Platform `json:",omitempty"`
}

View File

@@ -11,7 +11,6 @@ import (
"testing"
cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/registry"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@@ -24,10 +23,10 @@ func TestImagePushReferenceError(t *testing.T) {
}),
}
// An empty reference is an invalid reference
_, err := client.ImagePush(context.Background(), "", image.PushOptions{})
_, err := client.ImagePush(context.Background(), "", ImagePushOptions{})
assert.Check(t, is.ErrorContains(err, "invalid reference format"))
// An canonical reference cannot be pushed
_, err = client.ImagePush(context.Background(), "repo@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", image.PushOptions{})
_, err = client.ImagePush(context.Background(), "repo@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", ImagePushOptions{})
assert.Check(t, is.Error(err, "cannot push a digest reference"))
}
@@ -35,7 +34,7 @@ func TestImagePushAnyError(t *testing.T) {
client := &Client{
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ImagePush(context.Background(), "myimage", image.PushOptions{})
_, err := client.ImagePush(context.Background(), "myimage", ImagePushOptions{})
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal))
}
@@ -43,7 +42,7 @@ func TestImagePushStatusUnauthorizedError(t *testing.T) {
client := &Client{
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
}
_, err := client.ImagePush(context.Background(), "myimage", image.PushOptions{})
_, err := client.ImagePush(context.Background(), "myimage", ImagePushOptions{})
assert.Check(t, is.ErrorType(err, cerrdefs.IsUnauthorized))
}
@@ -54,7 +53,7 @@ func TestImagePushWithUnauthorizedErrorAndPrivilegeFuncError(t *testing.T) {
privilegeFunc := func(_ context.Context) (string, error) {
return "", errors.New("Error requesting privilege")
}
_, err := client.ImagePush(context.Background(), "myimage", image.PushOptions{
_, err := client.ImagePush(context.Background(), "myimage", ImagePushOptions{
PrivilegeFunc: privilegeFunc,
})
assert.Check(t, is.Error(err, "Error requesting privilege"))
@@ -67,7 +66,7 @@ func TestImagePushWithUnauthorizedErrorAndAnotherUnauthorizedError(t *testing.T)
privilegeFunc := func(_ context.Context) (string, error) {
return "a-auth-header", nil
}
_, err := client.ImagePush(context.Background(), "myimage", image.PushOptions{
_, err := client.ImagePush(context.Background(), "myimage", ImagePushOptions{
PrivilegeFunc: privilegeFunc,
})
assert.Check(t, is.ErrorType(err, cerrdefs.IsUnauthorized))
@@ -103,7 +102,7 @@ func TestImagePushWithPrivilegedFuncNoError(t *testing.T) {
}, nil
}),
}
resp, err := client.ImagePush(context.Background(), "myname/myimage:tag", image.PushOptions{
resp, err := client.ImagePush(context.Background(), "myname/myimage:tag", ImagePushOptions{
RegistryAuth: invalidAuth,
PrivilegeFunc: staticAuth(validAuth),
})
@@ -193,7 +192,7 @@ func TestImagePushWithoutErrors(t *testing.T) {
}, nil
}),
}
resp, err := client.ImagePush(context.Background(), tc.reference, image.PushOptions{
resp, err := client.ImagePush(context.Background(), tc.reference, ImagePushOptions{
All: tc.all,
})
assert.NilError(t, err)

View File

@@ -9,7 +9,7 @@ import (
)
// ImageRemove removes an image from the docker host.
func (cli *Client) ImageRemove(ctx context.Context, imageID string, options image.RemoveOptions) ([]image.DeleteResponse, error) {
func (cli *Client) ImageRemove(ctx context.Context, imageID string, options ImageRemoveOptions) ([]image.DeleteResponse, error) {
query := url.Values{}
if options.Force {

View File

@@ -0,0 +1,10 @@
package client
import ocispec "github.com/opencontainers/image-spec/specs-go/v1"
// ImageRemoveOptions holds parameters to remove images.
type ImageRemoveOptions struct {
Platforms []ocispec.Platform
Force bool
PruneChildren bool
}

View File

@@ -22,7 +22,7 @@ func TestImageRemoveError(t *testing.T) {
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ImageRemove(context.Background(), "image_id", image.RemoveOptions{})
_, err := client.ImageRemove(context.Background(), "image_id", ImageRemoveOptions{})
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal))
}
@@ -31,7 +31,7 @@ func TestImageRemoveImageNotFound(t *testing.T) {
client: newMockClient(errorMock(http.StatusNotFound, "no such image: unknown")),
}
_, err := client.ImageRemove(context.Background(), "unknown", image.RemoveOptions{})
_, err := client.ImageRemove(context.Background(), "unknown", ImageRemoveOptions{})
assert.Check(t, is.ErrorContains(err, "no such image: unknown"))
assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound))
}
@@ -105,7 +105,7 @@ func TestImageRemove(t *testing.T) {
}),
}
opts := image.RemoveOptions{
opts := ImageRemoveOptions{
Force: removeCase.force,
PruneChildren: removeCase.pruneChildren,
}

View File

@@ -3,7 +3,6 @@ package client
import (
"fmt"
"github.com/moby/moby/api/types/image"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
@@ -29,5 +28,11 @@ func ImageSaveWithPlatforms(platforms ...ocispec.Platform) ImageSaveOption {
}
type imageSaveOpts struct {
apiOptions image.SaveOptions
apiOptions imageSaveOptions
}
type imageSaveOptions struct {
// Platforms selects the platforms to save if the image is a
// multi-platform image and has multiple variants.
Platforms []ocispec.Platform
}

View File

@@ -18,6 +18,7 @@ import (
"github.com/moby/moby/v2/daemon/internal/image"
"github.com/moby/moby/v2/daemon/internal/metrics"
"github.com/moby/moby/v2/daemon/internal/stringid"
"github.com/moby/moby/v2/daemon/server/imagebackend"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
@@ -54,7 +55,7 @@ import (
// conflict will not be reported.
//
// TODO(thaJeztah): image delete should send prometheus counters; see https://github.com/moby/moby/issues/45268
func (i *ImageService) ImageDelete(ctx context.Context, imageRef string, options imagetypes.RemoveOptions) (response []imagetypes.DeleteResponse, retErr error) {
func (i *ImageService) ImageDelete(ctx context.Context, imageRef string, options imagebackend.RemoveOptions) (response []imagetypes.DeleteResponse, retErr error) {
start := time.Now()
defer func() {
if retErr == nil {

View File

@@ -8,10 +8,10 @@ import (
"github.com/containerd/containerd/v2/core/metadata"
"github.com/containerd/containerd/v2/pkg/namespaces"
"github.com/containerd/log/logtest"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/v2/daemon/container"
daemonevents "github.com/moby/moby/v2/daemon/events"
dimages "github.com/moby/moby/v2/daemon/images"
"github.com/moby/moby/v2/daemon/server/imagebackend"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
@@ -235,7 +235,7 @@ func TestImageDelete(t *testing.T) {
}
}
_, err := service.ImageDelete(ctx, tc.ref, image.RemoveOptions{})
_, err := service.ImageDelete(ctx, tc.ref, imagebackend.RemoveOptions{})
if tc.err == nil {
assert.NilError(t, err)
} else {

View File

@@ -22,6 +22,7 @@ import (
imagetypes "github.com/moby/moby/api/types/image"
"github.com/moby/moby/v2/daemon/internal/timestamp"
"github.com/moby/moby/v2/daemon/server/backend"
"github.com/moby/moby/v2/daemon/server/imagebackend"
"github.com/moby/moby/v2/errdefs"
"github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/identity"
@@ -62,7 +63,7 @@ func (r byCreated) Less(i, j int) bool { return r[i].Created < r[j].Created }
//
// TODO(thaJeztah): verify behavior of `RepoDigests` and `RepoTags` for images without (untagged) or multiple tags; see https://github.com/moby/moby/issues/43861
// TODO(thaJeztah): verify "Size" vs "VirtualSize" in images; see https://github.com/moby/moby/issues/43862
func (i *ImageService) Images(ctx context.Context, opts imagetypes.ListOptions) ([]*imagetypes.Summary, error) {
func (i *ImageService) Images(ctx context.Context, opts imagebackend.ListOptions) ([]*imagetypes.Summary, error) {
if err := opts.Filters.Validate(acceptedImageFilterTags); err != nil {
return nil, err
}
@@ -375,7 +376,7 @@ func (i *ImageService) multiPlatformSummary(ctx context.Context, img c8dimages.I
// It also returns the chainIDs of all the layers of the image (including all its platforms).
// All return values will be nil if the image should be skipped.
func (i *ImageService) imageSummary(ctx context.Context, img c8dimages.Image, platformMatcher platforms.MatchComparer,
opts imagetypes.ListOptions, tagsByDigest map[digest.Digest][]string,
opts imagebackend.ListOptions, tagsByDigest map[digest.Digest][]string,
) (*imagetypes.Summary, *multiPlatformSummary, error) {
summary, err := i.multiPlatformSummary(ctx, img, platformMatcher)
if err != nil {

View File

@@ -17,6 +17,7 @@ import (
"github.com/containerd/platforms"
imagetypes "github.com/moby/moby/api/types/image"
"github.com/moby/moby/v2/daemon/container"
"github.com/moby/moby/v2/daemon/server/imagebackend"
"github.com/moby/moby/v2/internal/testutils/specialimage"
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@@ -104,7 +105,7 @@ func BenchmarkImageList(b *testing.B) {
b.Run(strconv.Itoa(count)+"-images", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_, err := imgSvc.Images(ctx, imagetypes.ListOptions{All: true, SharedSize: true})
_, err := imgSvc.Images(ctx, imagebackend.ListOptions{All: true, SharedSize: true})
assert.NilError(b, err)
}
})
@@ -129,7 +130,7 @@ func TestImageListCheckTotalSize(t *testing.T) {
img, err := service.images.Create(ctx, imagesFromIndex(twoplatform)[0])
assert.NilError(t, err)
all, err := service.Images(ctx, imagetypes.ListOptions{Manifests: true, SharedSize: true})
all, err := service.Images(ctx, imagebackend.ListOptions{Manifests: true, SharedSize: true})
assert.NilError(t, err)
assert.Check(t, is.Len(all, 1))
@@ -189,7 +190,7 @@ func TestImageListCheckTotalSize(t *testing.T) {
assert.NilError(t, err, "failed to delete layer %s", layer.Digest)
}
all, err := service.Images(ctx, imagetypes.ListOptions{Manifests: true, SharedSize: true})
all, err := service.Images(ctx, imagebackend.ListOptions{Manifests: true, SharedSize: true})
assert.NilError(t, err)
assert.Assert(t, is.Len(all, 1))
@@ -377,7 +378,7 @@ func TestImageList(t *testing.T) {
assert.NilError(t, err)
}
opts := imagetypes.ListOptions{
opts := imagebackend.ListOptions{
Manifests: true,
SharedSize: true,
}

View File

@@ -15,8 +15,8 @@ import (
cerrdefs "github.com/containerd/errdefs"
"github.com/containerd/platforms"
"github.com/moby/go-archive"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/v2/daemon/server/backend"
"github.com/moby/moby/v2/daemon/server/imagebackend"
"github.com/moby/moby/v2/internal/testutils/labelstore"
"github.com/moby/moby/v2/internal/testutils/specialimage"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@@ -55,10 +55,10 @@ func TestImageLoad(t *testing.T) {
cleanup := func(ctx context.Context, t *testing.T) {
// Remove all existing images to start fresh
images, err := imgSvc.Images(ctx, image.ListOptions{})
images, err := imgSvc.Images(ctx, imagebackend.ListOptions{})
assert.NilError(t, err)
for _, img := range images {
_, err := imgSvc.ImageDelete(ctx, img.ID, image.RemoveOptions{PruneChildren: true})
_, err := imgSvc.ImageDelete(ctx, img.ID, imagebackend.RemoveOptions{PruneChildren: true})
assert.NilError(t, err)
}

View File

@@ -8,6 +8,7 @@ import (
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/v2/daemon/server/backend"
"github.com/moby/moby/v2/daemon/server/imagebackend"
"github.com/pkg/errors"
"golang.org/x/sync/errgroup"
)
@@ -54,7 +55,7 @@ func (daemon *Daemon) containerDiskUsage(ctx context.Context) (*backend.Containe
func (daemon *Daemon) imageDiskUsage(ctx context.Context) ([]*image.Summary, error) {
imgs, _, err := daemon.usageImages.Do(ctx, struct{}{}, func(ctx context.Context) ([]*image.Summary, error) {
// Get all top images with extra attributes
imgs, err := daemon.imageService.Images(ctx, image.ListOptions{
imgs, err := daemon.imageService.Images(ctx, imagebackend.ListOptions{
Filters: filters.NewArgs(),
SharedSize: true,
})

View File

@@ -16,6 +16,7 @@ import (
"github.com/moby/moby/v2/daemon/internal/image"
"github.com/moby/moby/v2/daemon/internal/layer"
"github.com/moby/moby/v2/daemon/server/backend"
"github.com/moby/moby/v2/daemon/server/imagebackend"
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
@@ -29,10 +30,10 @@ type ImageService interface {
PullImage(ctx context.Context, ref reference.Named, platform *ocispec.Platform, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error
PushImage(ctx context.Context, ref reference.Named, platform *ocispec.Platform, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error
CreateImage(ctx context.Context, config []byte, parent string, contentStoreDigest digest.Digest) (builder.Image, error)
ImageDelete(ctx context.Context, imageRef string, options imagetype.RemoveOptions) ([]imagetype.DeleteResponse, error)
ImageDelete(ctx context.Context, imageRef string, options imagebackend.RemoveOptions) ([]imagetype.DeleteResponse, error)
ExportImage(ctx context.Context, names []string, platformList []ocispec.Platform, outStream io.Writer) error
LoadImage(ctx context.Context, inTar io.ReadCloser, platformList []ocispec.Platform, outStream io.Writer, quiet bool) error
Images(ctx context.Context, opts imagetype.ListOptions) ([]*imagetype.Summary, error)
Images(ctx context.Context, opts imagebackend.ListOptions) ([]*imagetype.Summary, error)
LogImageEvent(ctx context.Context, imageID, refName string, action events.Action)
CountImages(ctx context.Context) int
ImagesPrune(ctx context.Context, pruneFilters filters.Args) (*imagetype.PruneReport, error)

View File

@@ -14,6 +14,7 @@ import (
"github.com/moby/moby/v2/daemon/internal/metrics"
"github.com/moby/moby/v2/daemon/internal/stringid"
"github.com/moby/moby/v2/daemon/server/backend"
"github.com/moby/moby/v2/daemon/server/imagebackend"
"github.com/moby/moby/v2/errdefs"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
@@ -63,7 +64,7 @@ const (
// If options.PruneChildren is true, ancestor images are attempted to be deleted quietly,
// meaning any delete conflicts will cause the image to not be deleted and the
// conflict will not be reported.
func (i *ImageService) ImageDelete(ctx context.Context, imageRef string, options imagetypes.RemoveOptions) ([]imagetypes.DeleteResponse, error) {
func (i *ImageService) ImageDelete(ctx context.Context, imageRef string, options imagebackend.RemoveOptions) ([]imagetypes.DeleteResponse, error) {
start := time.Now()
records := []imagetypes.DeleteResponse{}

View File

@@ -14,6 +14,7 @@ import (
"github.com/moby/moby/v2/daemon/internal/layer"
"github.com/moby/moby/v2/daemon/internal/timestamp"
"github.com/moby/moby/v2/daemon/server/backend"
"github.com/moby/moby/v2/daemon/server/imagebackend"
)
var acceptedImageFilterTags = map[string]bool{
@@ -34,7 +35,7 @@ func (r byCreated) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
func (r byCreated) Less(i, j int) bool { return r[i].Created < r[j].Created }
// Images returns a filtered list of images.
func (i *ImageService) Images(ctx context.Context, opts imagetypes.ListOptions) ([]*imagetypes.Summary, error) {
func (i *ImageService) Images(ctx context.Context, opts imagebackend.ListOptions) ([]*imagetypes.Summary, error) {
if err := opts.Filters.Validate(acceptedImageFilterTags); err != nil {
return nil, err
}

View File

@@ -14,6 +14,7 @@ import (
"github.com/moby/moby/v2/daemon/internal/image"
"github.com/moby/moby/v2/daemon/internal/layer"
"github.com/moby/moby/v2/daemon/internal/timestamp"
"github.com/moby/moby/v2/daemon/server/imagebackend"
"github.com/moby/moby/v2/errdefs"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
@@ -114,7 +115,7 @@ deleteImagesLoop:
if shouldDelete {
for _, ref := range refs {
imgDel, err := i.ImageDelete(ctx, ref.String(), imagetypes.RemoveOptions{
imgDel, err := i.ImageDelete(ctx, ref.String(), imagebackend.RemoveOptions{
PruneChildren: true,
})
if imageDeleteFailed(ref.String(), err) {
@@ -125,7 +126,7 @@ deleteImagesLoop:
}
} else {
hex := id.Digest().Encoded()
imgDel, err := i.ImageDelete(ctx, hex, imagetypes.RemoveOptions{
imgDel, err := i.ImageDelete(ctx, hex, imagebackend.RemoveOptions{
PruneChildren: true,
})
if imageDeleteFailed(hex, err) {

View File

@@ -0,0 +1,27 @@
package imagebackend
import (
"github.com/moby/moby/api/types/filters"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
type RemoveOptions struct {
Platforms []ocispec.Platform
Force bool
PruneChildren bool
}
type ListOptions struct {
// All controls whether all images in the graph are filtered, or just
// the heads.
All bool
// Filters is a JSON-encoded set of filter arguments.
Filters filters.Args
// SharedSize indicates whether the shared size of images should be computed.
SharedSize bool
// Manifests indicates whether the image manifests should be returned.
Manifests bool
}

View File

@@ -10,6 +10,7 @@ import (
"github.com/moby/moby/api/types/registry"
dockerimage "github.com/moby/moby/v2/daemon/internal/image"
"github.com/moby/moby/v2/daemon/server/backend"
"github.com/moby/moby/v2/daemon/server/imagebackend"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
@@ -22,9 +23,9 @@ type Backend interface {
}
type imageBackend interface {
ImageDelete(ctx context.Context, imageRef string, options image.RemoveOptions) ([]image.DeleteResponse, error)
ImageDelete(ctx context.Context, imageRef string, options imagebackend.RemoveOptions) ([]image.DeleteResponse, error)
ImageHistory(ctx context.Context, imageName string, platform *ocispec.Platform) ([]*image.HistoryResponseItem, error)
Images(ctx context.Context, opts image.ListOptions) ([]*image.Summary, error)
Images(ctx context.Context, opts imagebackend.ListOptions) ([]*image.Summary, error)
GetImage(ctx context.Context, refOrID string, options backend.GetImageOpts) (*dockerimage.Image, error)
ImageInspect(ctx context.Context, refOrID string, options backend.ImageInspectOpts) (*image.InspectResponse, error)
TagImage(ctx context.Context, id dockerimage.ID, newRef reference.Named) error

View File

@@ -15,13 +15,13 @@ import (
"github.com/moby/moby/api/pkg/progress"
"github.com/moby/moby/api/pkg/streamformatter"
"github.com/moby/moby/api/types/filters"
imagetypes "github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/registry"
"github.com/moby/moby/api/types/versions"
"github.com/moby/moby/v2/daemon/builder/remotecontext"
"github.com/moby/moby/v2/daemon/internal/image"
"github.com/moby/moby/v2/daemon/server/backend"
"github.com/moby/moby/v2/daemon/server/httputils"
"github.com/moby/moby/v2/daemon/server/imagebackend"
"github.com/moby/moby/v2/dockerversion"
"github.com/moby/moby/v2/errdefs"
"github.com/moby/moby/v2/pkg/ioutils"
@@ -328,7 +328,7 @@ func (ir *imageRouter) deleteImages(ctx context.Context, w http.ResponseWriter,
p = val
}
list, err := ir.backend.ImageDelete(ctx, name, imagetypes.RemoveOptions{
list, err := ir.backend.ImageDelete(ctx, name, imagebackend.RemoveOptions{
Force: force,
PruneChildren: prune,
Platforms: p,
@@ -442,7 +442,7 @@ func (ir *imageRouter) getImagesJSON(ctx context.Context, w http.ResponseWriter,
manifests = httputils.BoolValue(r, "manifests")
}
images, err := ir.backend.Images(ctx, imagetypes.ListOptions{
images, err := ir.backend.Images(ctx, imagebackend.ListOptions{
All: httputils.BoolValue(r, "all"),
Filters: imageFilters,
SharedSize: sharedSize,

View File

@@ -11,7 +11,7 @@ import (
"strings"
"testing"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/client"
"github.com/moby/moby/v2/testutil"
"github.com/moby/moby/v2/testutil/fakecontext"
"github.com/moby/moby/v2/testutil/fakegit"
@@ -327,15 +327,15 @@ func (s *DockerAPISuite) TestBuildOnBuildCache(c *testing.T) {
}
func (s *DockerRegistrySuite) TestBuildCopyFromForcePull(c *testing.T) {
client := testEnv.APIClient()
apiClient := testEnv.APIClient()
repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
// tag the image to upload it to the private registry
ctx := testutil.GetContext(c)
err := client.ImageTag(ctx, "busybox", repoName)
err := apiClient.ImageTag(ctx, "busybox", repoName)
assert.Check(c, err)
// push the image to the registry
rc, err := client.ImagePush(ctx, repoName, image.PushOptions{RegistryAuth: "{}"})
rc, err := apiClient.ImagePush(ctx, repoName, client.ImagePushOptions{RegistryAuth: "{}"})
assert.Check(c, err)
_, err = io.Copy(io.Discard, rc)
assert.Check(c, err)

View File

@@ -6,7 +6,6 @@ import (
"strings"
"testing"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/client"
"github.com/moby/moby/v2/integration-cli/cli"
"github.com/moby/moby/v2/integration-cli/cli/build"
@@ -51,13 +50,13 @@ func (s *DockerAPISuite) TestAPIImagesDelete(c *testing.T) {
cli.DockerCmd(c, "tag", name, "test:tag1")
_, err = apiClient.ImageRemove(testutil.GetContext(c), id, image.RemoveOptions{})
_, err = apiClient.ImageRemove(testutil.GetContext(c), id, client.ImageRemoveOptions{})
assert.ErrorContains(c, err, "unable to delete")
_, err = apiClient.ImageRemove(testutil.GetContext(c), "test:noexist", image.RemoveOptions{})
_, err = apiClient.ImageRemove(testutil.GetContext(c), "test:noexist", client.ImageRemoveOptions{})
assert.ErrorContains(c, err, "No such image")
_, err = apiClient.ImageRemove(testutil.GetContext(c), "test:tag1", image.RemoveOptions{})
_, err = apiClient.ImageRemove(testutil.GetContext(c), "test:tag1", client.ImageRemoveOptions{})
assert.NilError(c, err)
}
@@ -103,7 +102,7 @@ func (s *DockerAPISuite) TestAPIImagesSizeCompatibility(c *testing.T) {
apiclient := testEnv.APIClient()
defer apiclient.Close()
images, err := apiclient.ImageList(testutil.GetContext(c), image.ListOptions{})
images, err := apiclient.ImageList(testutil.GetContext(c), client.ImageListOptions{})
assert.NilError(c, err)
assert.Assert(c, len(images) != 0)
for _, img := range images {
@@ -114,7 +113,7 @@ func (s *DockerAPISuite) TestAPIImagesSizeCompatibility(c *testing.T) {
assert.NilError(c, err)
defer apiclient.Close()
v124Images, err := apiclient.ImageList(testutil.GetContext(c), image.ListOptions{})
v124Images, err := apiclient.ImageList(testutil.GetContext(c), client.ImageListOptions{})
assert.NilError(c, err)
assert.Assert(c, len(v124Images) != 0)
for _, img := range v124Images {

View File

@@ -826,7 +826,7 @@ func TestBuildHistoryDoesNotPreventRemoval(t *testing.T) {
err := buildImage("history-a")
assert.NilError(t, err)
resp, err := apiClient.ImageRemove(ctx, "history-a", image.RemoveOptions{})
resp, err := apiClient.ImageRemove(ctx, "history-a", client.ImageRemoveOptions{})
assert.NilError(t, err)
assert.Check(t, slices.ContainsFunc(resp, func(r image.DeleteResponse) bool {
return r.Deleted != ""

View File

@@ -6,7 +6,7 @@ import (
"testing"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/client"
"github.com/moby/moby/client/pkg/jsonmessage"
"github.com/moby/moby/v2/integration/internal/container"
"github.com/moby/moby/v2/testutil"
@@ -30,10 +30,10 @@ func TestExportContainerAndImportImage(t *testing.T) {
reference := "repo/" + strings.ToLower(t.Name()) + ":v1"
exportResp, err := apiClient.ContainerExport(ctx, cID)
assert.NilError(t, err)
importResp, err := apiClient.ImageImport(ctx, image.ImportSource{
importResp, err := apiClient.ImageImport(ctx, client.ImageImportSource{
Source: exportResp,
SourceName: "-",
}, reference, image.ImportOptions{})
}, reference, client.ImageImportOptions{})
assert.NilError(t, err)
// If the import is successfully, then the message output should contain
@@ -44,7 +44,7 @@ func TestExportContainerAndImportImage(t *testing.T) {
err = dec.Decode(&jm)
assert.NilError(t, err)
images, err := apiClient.ImageList(ctx, image.ListOptions{
images, err := apiClient.ImageList(ctx, client.ImageListOptions{
Filters: filters.NewArgs(filters.Arg("reference", reference)),
})
assert.NilError(t, err)

View File

@@ -17,9 +17,9 @@ import (
cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/pkg/stdcopy"
containertypes "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/mount"
"github.com/moby/moby/api/types/volume"
"github.com/moby/moby/client"
"github.com/moby/moby/v2/daemon/config"
"github.com/moby/moby/v2/integration/internal/container"
"github.com/moby/moby/v2/integration/internal/process"
@@ -297,12 +297,12 @@ func TestDaemonProxy(t *testing.T) {
assert.Check(t, is.Equal(info.HTTPSProxy, proxyServer.URL))
assert.Check(t, is.Equal(info.NoProxy, "example.com"))
_, err := c.ImagePull(ctx, "example.org:5000/some/image:latest", image.PullOptions{})
_, err := c.ImagePull(ctx, "example.org:5000/some/image:latest", client.ImagePullOptions{})
assert.ErrorContains(t, err, "", "pulling should have failed")
assert.Equal(t, received, "example.org:5000")
// Test NoProxy: example.com should not hit the proxy, and "received" variable should not be changed.
_, err = c.ImagePull(ctx, "example.com/some/image:latest", image.PullOptions{})
_, err = c.ImagePull(ctx, "example.com/some/image:latest", client.ImagePullOptions{})
assert.ErrorContains(t, err, "", "pulling should have failed")
assert.Equal(t, received, "example.org:5000", "should not have used proxy")
})
@@ -349,12 +349,12 @@ func TestDaemonProxy(t *testing.T) {
ok, logs := d.ScanLogsT(ctx, t, daemon.ScanLogsMatchString(userPass))
assert.Assert(t, !ok, "logs should not contain the non-sanitized proxy URL: %s", logs)
_, err := c.ImagePull(ctx, "example.org:5001/some/image:latest", image.PullOptions{})
_, err := c.ImagePull(ctx, "example.org:5001/some/image:latest", client.ImagePullOptions{})
assert.ErrorContains(t, err, "", "pulling should have failed")
assert.Equal(t, received, "example.org:5001")
// Test NoProxy: example.com should not hit the proxy, and "received" variable should not be changed.
_, err = c.ImagePull(ctx, "example.com/some/image:latest", image.PullOptions{})
_, err = c.ImagePull(ctx, "example.com/some/image:latest", client.ImagePullOptions{})
assert.ErrorContains(t, err, "", "pulling should have failed")
assert.Equal(t, received, "example.org:5001", "should not have used proxy")
})
@@ -400,12 +400,12 @@ func TestDaemonProxy(t *testing.T) {
"NO_PROXY",
))
_, err := c.ImagePull(ctx, "example.org:5002/some/image:latest", image.PullOptions{})
_, err := c.ImagePull(ctx, "example.org:5002/some/image:latest", client.ImagePullOptions{})
assert.ErrorContains(t, err, "", "pulling should have failed")
assert.Equal(t, received, "example.org:5002")
// Test NoProxy: example.com should not hit the proxy, and "received" variable should not be changed.
_, err = c.ImagePull(ctx, "example.com/some/image:latest", image.PullOptions{})
_, err = c.ImagePull(ctx, "example.com/some/image:latest", client.ImagePullOptions{})
assert.ErrorContains(t, err, "", "pulling should have failed")
assert.Equal(t, received, "example.org:5002", "should not have used proxy")
})
@@ -700,7 +700,7 @@ func testLiveRestoreVolumeReferences(t *testing.T) {
poll.WaitOn(t, waitFn)
})
_, err := c.ImageRemove(ctx, mountedImage, image.RemoveOptions{})
_, err := c.ImageRemove(ctx, mountedImage, client.ImageRemoveOptions{})
assert.ErrorContains(t, err, fmt.Sprintf("container %s is using its referenced image", cID[:12]))
// Remove that container which should free the references in the volume
@@ -708,7 +708,7 @@ func testLiveRestoreVolumeReferences(t *testing.T) {
assert.NilError(t, err)
// Now we should be able to remove the volume
_, err = c.ImageRemove(ctx, mountedImage, image.RemoveOptions{})
_, err = c.ImageRemove(ctx, mountedImage, client.ImageRemoveOptions{})
assert.NilError(t, err)
})

View File

@@ -7,7 +7,6 @@ import (
"testing"
containertypes "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/client"
"github.com/moby/moby/v2/integration/internal/container"
"github.com/moby/moby/v2/testutil"
@@ -136,10 +135,10 @@ func TestMigrateSaveLoad(t *testing.T) {
rdr.Close()
// Delete all images
list, err := apiClient.ImageList(ctx, image.ListOptions{})
list, err := apiClient.ImageList(ctx, client.ImageListOptions{})
assert.NilError(t, err)
for _, i := range list {
_, err = apiClient.ImageRemove(ctx, i.ID, image.RemoveOptions{Force: true})
_, err = apiClient.ImageRemove(ctx, i.ID, client.ImageRemoveOptions{Force: true})
assert.NilError(t, err)
}

View File

@@ -11,7 +11,7 @@ import (
cerrdefs "github.com/containerd/errdefs"
"github.com/containerd/platforms"
imagetypes "github.com/moby/moby/api/types/image"
"github.com/moby/moby/client"
"github.com/moby/moby/v2/testutil"
"github.com/moby/moby/v2/testutil/daemon"
"gotest.tools/v3/assert"
@@ -33,7 +33,7 @@ func TestImportExtremelyLargeImageWorks(t *testing.T) {
d.Start(t, "--iptables=false", "--ip6tables=false")
defer d.Stop(t)
client := d.NewClientT(t)
apiClient := d.NewClientT(t)
// Construct an empty tar archive with about 8GB of junk padding at the
// end. This should not cause any crashes (the padding should be mostly
@@ -46,10 +46,10 @@ func TestImportExtremelyLargeImageWorks(t *testing.T) {
imageRdr := io.MultiReader(&tarBuffer, io.LimitReader(testutil.DevZero, 8*1024*1024*1024))
reference := strings.ToLower(t.Name()) + ":v42"
_, err = client.ImageImport(ctx,
imagetypes.ImportSource{Source: imageRdr, SourceName: "-"},
_, err = apiClient.ImageImport(ctx,
client.ImageImportSource{Source: imageRdr, SourceName: "-"},
reference,
imagetypes.ImportOptions{})
client.ImageImportOptions{})
assert.NilError(t, err)
}
@@ -58,7 +58,7 @@ func TestImportWithCustomPlatform(t *testing.T) {
ctx := setupTest(t)
client := testEnv.APIClient()
apiClient := testEnv.APIClient()
// Construct an empty tar archive.
var tarBuffer bytes.Buffer
@@ -108,13 +108,13 @@ func TestImportWithCustomPlatform(t *testing.T) {
ctx := testutil.StartSpan(ctx, t)
reference := "import-with-platform:tc-" + strconv.Itoa(i)
_, err = client.ImageImport(ctx,
imagetypes.ImportSource{Source: imageRdr, SourceName: "-"},
_, err = apiClient.ImageImport(ctx,
client.ImageImportSource{Source: imageRdr, SourceName: "-"},
reference,
imagetypes.ImportOptions{Platform: tc.platform})
client.ImageImportOptions{Platform: tc.platform})
assert.NilError(t, err)
inspect, err := client.ImageInspect(ctx, reference)
inspect, err := apiClient.ImageInspect(ctx, reference)
assert.NilError(t, err)
assert.Equal(t, inspect.Os, tc.expected.OS)
assert.Equal(t, inspect.Architecture, tc.expected.Architecture)
@@ -128,7 +128,7 @@ func TestImportWithCustomPlatformReject(t *testing.T) {
ctx := setupTest(t)
client := testEnv.APIClient()
apiClient := testEnv.APIClient()
// Construct an empty tar archive.
var tarBuffer bytes.Buffer
@@ -172,10 +172,10 @@ func TestImportWithCustomPlatformReject(t *testing.T) {
t.Run(tc.platform, func(t *testing.T) {
ctx := testutil.StartSpan(ctx, t)
reference := "import-with-platform:tc-" + strconv.Itoa(i)
_, err = client.ImageImport(ctx,
imagetypes.ImportSource{Source: imageRdr, SourceName: "-"},
_, err = apiClient.ImageImport(ctx,
client.ImageImportSource{Source: imageRdr, SourceName: "-"},
reference,
imagetypes.ImportOptions{Platform: tc.platform})
client.ImageImportOptions{Platform: tc.platform})
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
assert.Check(t, is.ErrorContains(err, tc.expectedErr))

View File

@@ -5,7 +5,6 @@ import (
"encoding/json"
"testing"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/client"
iimage "github.com/moby/moby/v2/integration/internal/image"
"github.com/moby/moby/v2/internal/testutils/specialimage"
@@ -55,7 +54,7 @@ func TestImageInspectUniqueRepoDigests(t *testing.T) {
err := apiClient.ImageTag(ctx, "busybox", imgName)
assert.NilError(t, err)
defer func() {
_, _ = apiClient.ImageRemove(ctx, imgName, image.RemoveOptions{Force: true})
_, _ = apiClient.ImageRemove(ctx, imgName, client.ImageRemoveOptions{Force: true})
}()
}

View File

@@ -48,7 +48,7 @@ func TestImagesFilterMultiReference(t *testing.T) {
filter.Add("reference", repoTags[0])
filter.Add("reference", repoTags[1])
filter.Add("reference", repoTags[2])
options := image.ListOptions{
options := client.ImageListOptions{
Filters: filter,
}
images, err := apiClient.ImageList(ctx, options)
@@ -96,7 +96,7 @@ func TestImagesFilterUntil(t *testing.T) {
filters.Arg("until", laterUntil),
filters.Arg("before", imgs[len(imgs)-1]),
)
list, err := apiClient.ImageList(ctx, image.ListOptions{Filters: filter})
list, err := apiClient.ImageList(ctx, client.ImageListOptions{Filters: filter})
assert.NilError(t, err)
var listedIDs []string
@@ -130,7 +130,7 @@ func TestImagesFilterBeforeSince(t *testing.T) {
filters.Arg("since", imgs[0]),
filters.Arg("before", imgs[len(imgs)-1]),
)
list, err := apiClient.ImageList(ctx, image.ListOptions{Filters: filter})
list, err := apiClient.ImageList(ctx, client.ImageListOptions{Filters: filter})
assert.NilError(t, err)
var listedIDs []string
@@ -191,7 +191,7 @@ func TestAPIImagesFilters(t *testing.T) {
t.Parallel()
ctx := testutil.StartSpan(ctx, t)
images, err := apiClient.ImageList(ctx, image.ListOptions{
images, err := apiClient.ImageList(ctx, client.ImageListOptions{
Filters: filters.NewArgs(tc.filters...),
})
assert.Check(t, err)
@@ -228,7 +228,7 @@ func TestAPIImagesListSizeShared(t *testing.T) {
})
})
_, err := apiClient.ImageList(ctx, image.ListOptions{SharedSize: true})
_, err := apiClient.ImageList(ctx, client.ImageListOptions{SharedSize: true})
assert.NilError(t, err)
}
@@ -265,7 +265,7 @@ func TestAPIImagesListManifests(t *testing.T) {
// TODO: Remove when MinSupportedAPIVersion >= 1.47
c := d.NewClientT(t, client.WithVersion(api.MinSupportedAPIVersion))
images, err := c.ImageList(ctx, image.ListOptions{Manifests: true})
images, err := c.ImageList(ctx, client.ImageListOptions{Manifests: true})
assert.NilError(t, err)
assert.Assert(t, is.Len(images, 1))
@@ -277,14 +277,14 @@ func TestAPIImagesListManifests(t *testing.T) {
api147 := d.NewClientT(t, client.WithVersion("1.47"))
t.Run("no manifests if not requested", func(t *testing.T) {
images, err := api147.ImageList(ctx, image.ListOptions{})
images, 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))
})
images, err := api147.ImageList(ctx, image.ListOptions{Manifests: true})
images, err := api147.ImageList(ctx, client.ImageListOptions{Manifests: true})
assert.NilError(t, err)
assert.Check(t, is.Len(images, 1))

View File

@@ -6,6 +6,7 @@ import (
cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/client"
iimage "github.com/moby/moby/v2/integration/internal/image"
"github.com/moby/moby/v2/internal/testutils/specialimage"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@@ -19,16 +20,16 @@ func TestLoadDanglingImages(t *testing.T) {
ctx := setupTest(t)
client := testEnv.APIClient()
apiClient := testEnv.APIClient()
iimage.Load(ctx, t, client, func(dir string) (*ocispec.Index, error) {
iimage.Load(ctx, t, apiClient, func(dir string) (*ocispec.Index, error) {
return specialimage.MultiLayerCustom(dir, "namedimage:latest", []specialimage.SingleFileLayer{
{Name: "bar", Content: []byte("1")},
})
})
// Should be one image.
images, err := client.ImageList(ctx, image.ListOptions{})
images, err := apiClient.ImageList(ctx, client.ImageListOptions{})
assert.NilError(t, err)
findImageByName := func(images []image.Summary, imageName string) (image.Summary, error) {
@@ -45,13 +46,13 @@ func TestLoadDanglingImages(t *testing.T) {
assert.NilError(t, err)
// Retain a copy of the old image and then replace it with a new one.
iimage.Load(ctx, t, client, func(dir string) (*ocispec.Index, error) {
iimage.Load(ctx, t, apiClient, func(dir string) (*ocispec.Index, error) {
return specialimage.MultiLayerCustom(dir, "namedimage:latest", []specialimage.SingleFileLayer{
{Name: "bar", Content: []byte("2")},
})
})
images, err = client.ImageList(ctx, image.ListOptions{})
images, err = apiClient.ImageList(ctx, client.ImageListOptions{})
assert.NilError(t, err)
newImage, err := findImageByName(images, "namedimage:latest")

View File

@@ -82,7 +82,7 @@ func TestPruneLexographicalOrder(t *testing.T) {
err = apiClient.ImageTag(ctx, id, "busybox:z")
assert.NilError(t, err)
_, err = apiClient.ImageRemove(ctx, "busybox:latest", image.RemoveOptions{Force: true})
_, err = apiClient.ImageRemove(ctx, "busybox:latest", client.ImageRemoveOptions{Force: true})
assert.NilError(t, err)
// run container

View File

@@ -17,7 +17,7 @@ import (
"github.com/containerd/containerd/v2/plugins/content/local"
cerrdefs "github.com/containerd/errdefs"
"github.com/containerd/platforms"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/client"
"github.com/moby/moby/v2/testutil/daemon"
"github.com/moby/moby/v2/testutil/registry"
"github.com/opencontainers/go-digest"
@@ -31,9 +31,9 @@ import (
func TestImagePullPlatformInvalid(t *testing.T) {
ctx := setupTest(t)
client := testEnv.APIClient()
apiClient := testEnv.APIClient()
_, err := client.ImagePull(ctx, "docker.io/library/hello-world:latest", image.PullOptions{Platform: "foobar"})
_, err := apiClient.ImagePull(ctx, "docker.io/library/hello-world:latest", client.ImagePullOptions{Platform: "foobar"})
assert.Assert(t, err != nil)
assert.Check(t, is.ErrorContains(err, "unknown operating system or architecture"))
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
@@ -144,15 +144,15 @@ func TestImagePullStoredDigestForOtherRepo(t *testing.T) {
err = c8dClient.Push(ctx, remote, desc)
assert.NilError(t, err)
client := testEnv.APIClient()
rdr, err := client.ImagePull(ctx, remote, image.PullOptions{})
apiClient := testEnv.APIClient()
rdr, err := apiClient.ImagePull(ctx, remote, client.ImagePullOptions{})
assert.NilError(t, err)
defer rdr.Close()
_, err = io.Copy(io.Discard, rdr)
assert.Check(t, err)
// Now, pull a totally different repo with a the same digest
rdr, err = client.ImagePull(ctx, path.Join(registry.DefaultURL, "other:image@"+desc.Digest.String()), image.PullOptions{})
rdr, err = apiClient.ImagePull(ctx, path.Join(registry.DefaultURL, "other:image@"+desc.Digest.String()), client.ImagePullOptions{})
if rdr != nil {
assert.Check(t, rdr.Close())
}
@@ -178,8 +178,8 @@ func TestImagePullNonExisting(t *testing.T) {
t.Run(ref, func(t *testing.T) {
t.Parallel()
client := testEnv.APIClient()
rdr, err := client.ImagePull(ctx, ref, image.PullOptions{
apiClient := testEnv.APIClient()
rdr, err := apiClient.ImagePull(ctx, ref, client.ImagePullOptions{
All: all,
})
if err == nil {
@@ -218,10 +218,10 @@ func TestImagePullKeepOldAsDangling(t *testing.T) {
assert.NilError(t, apiClient.ImageTag(ctx, "busybox:latest", "alpine:latest"))
_, err = apiClient.ImageRemove(ctx, "busybox:latest", image.RemoveOptions{})
_, err = apiClient.ImageRemove(ctx, "busybox:latest", client.ImageRemoveOptions{})
assert.NilError(t, err)
rc, err := apiClient.ImagePull(ctx, "alpine:latest", image.PullOptions{})
rc, err := apiClient.ImagePull(ctx, "alpine:latest", client.ImagePullOptions{})
assert.NilError(t, err)
defer rc.Close()

View File

@@ -9,6 +9,7 @@ import (
containertypes "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/client"
"github.com/moby/moby/v2/integration/internal/container"
iimage "github.com/moby/moby/v2/integration/internal/image"
"github.com/moby/moby/v2/internal/testutils/specialimage"
@@ -21,47 +22,47 @@ import (
func TestRemoveImageOrphaning(t *testing.T) {
ctx := setupTest(t)
client := testEnv.APIClient()
apiClient := testEnv.APIClient()
imgName := strings.ToLower(t.Name())
// Create a container from busybox, and commit a small change so we have a new image
cID1 := container.Create(ctx, t, client, container.WithCmd(""))
commitResp1, err := client.ContainerCommit(ctx, cID1, containertypes.CommitOptions{
cID1 := container.Create(ctx, t, apiClient, container.WithCmd(""))
commitResp1, err := apiClient.ContainerCommit(ctx, cID1, containertypes.CommitOptions{
Changes: []string{`ENTRYPOINT ["true"]`},
Reference: imgName,
})
assert.NilError(t, err)
// verifies that reference now points to first image
resp, err := client.ImageInspect(ctx, imgName)
resp, err := apiClient.ImageInspect(ctx, imgName)
assert.NilError(t, err)
assert.Check(t, is.Equal(resp.ID, commitResp1.ID))
// Create a container from created image, and commit a small change with same reference name
cID2 := container.Create(ctx, t, client, container.WithImage(imgName), container.WithCmd(""))
commitResp2, err := client.ContainerCommit(ctx, cID2, containertypes.CommitOptions{
cID2 := container.Create(ctx, t, apiClient, container.WithImage(imgName), container.WithCmd(""))
commitResp2, err := apiClient.ContainerCommit(ctx, cID2, containertypes.CommitOptions{
Changes: []string{`LABEL Maintainer="Integration Tests"`},
Reference: imgName,
})
assert.NilError(t, err)
// verifies that reference now points to second image
resp, err = client.ImageInspect(ctx, imgName)
resp, err = apiClient.ImageInspect(ctx, imgName)
assert.NilError(t, err)
assert.Check(t, is.Equal(resp.ID, commitResp2.ID))
// try to remove the image, should not error out.
_, err = client.ImageRemove(ctx, imgName, image.RemoveOptions{})
_, err = apiClient.ImageRemove(ctx, imgName, client.ImageRemoveOptions{})
assert.NilError(t, err)
// check if the first image is still there
resp, err = client.ImageInspect(ctx, commitResp1.ID)
resp, err = apiClient.ImageInspect(ctx, commitResp1.ID)
assert.NilError(t, err)
assert.Check(t, is.Equal(resp.ID, commitResp1.ID))
// check if the second image has been deleted
_, err = client.ImageInspect(ctx, commitResp2.ID)
_, err = apiClient.ImageInspect(ctx, commitResp2.ID)
assert.Check(t, is.ErrorContains(err, "No such image:"))
}
@@ -69,12 +70,12 @@ func TestRemoveByDigest(t *testing.T) {
skip.If(t, !testEnv.UsingSnapshotter(), "RepoDigests doesn't include tags when using graphdrivers")
ctx := setupTest(t)
client := testEnv.APIClient()
apiClient := testEnv.APIClient()
err := client.ImageTag(ctx, "busybox", "test-remove-by-digest:latest")
err := apiClient.ImageTag(ctx, "busybox", "test-remove-by-digest:latest")
assert.NilError(t, err)
inspect, err := client.ImageInspect(ctx, "test-remove-by-digest")
inspect, err := apiClient.ImageInspect(ctx, "test-remove-by-digest")
assert.NilError(t, err)
id := ""
@@ -86,13 +87,13 @@ func TestRemoveByDigest(t *testing.T) {
}
assert.Assert(t, id != "")
_, err = client.ImageRemove(ctx, id, image.RemoveOptions{})
_, err = apiClient.ImageRemove(ctx, id, client.ImageRemoveOptions{})
assert.NilError(t, err, "error removing %s", id)
_, err = client.ImageInspect(ctx, "busybox")
_, err = apiClient.ImageInspect(ctx, "busybox")
assert.NilError(t, err, "busybox image got deleted")
inspect, err = client.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.DeepEqual(inspect, image.InspectResponse{}))
}
@@ -142,7 +143,7 @@ func TestRemoveWithPlatform(t *testing.T) {
{&platformHost, descs[0]},
{&someOtherPlatform, descs[3]},
} {
resp, err := apiClient.ImageRemove(ctx, imgName, image.RemoveOptions{
resp, err := apiClient.ImageRemove(ctx, imgName, client.ImageRemoveOptions{
Platforms: []ocispec.Platform{*tc.platform},
Force: true,
})
@@ -155,7 +156,7 @@ func TestRemoveWithPlatform(t *testing.T) {
}
// Delete the rest
resp, err := apiClient.ImageRemove(ctx, imgName, image.RemoveOptions{})
resp, err := apiClient.ImageRemove(ctx, imgName, client.ImageRemoveOptions{})
assert.NilError(t, err)
assert.Check(t, is.Len(resp, 2))

View File

@@ -16,7 +16,6 @@ import (
"github.com/cpuguy83/tar2go"
"github.com/moby/go-archive/compression"
containertypes "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/versions"
"github.com/moby/moby/client"
"github.com/moby/moby/v2/integration/internal/build"
@@ -315,7 +314,7 @@ func TestSaveAndLoadPlatform(t *testing.T) {
t.Run(tc.testName, func(t *testing.T) {
// pull the image
for _, p := range tc.pullPlatforms {
resp, err := apiClient.ImagePull(ctx, repoName, image.PullOptions{Platform: p})
resp, err := apiClient.ImagePull(ctx, repoName, client.ImagePullOptions{Platform: p})
assert.NilError(t, err)
_, err = io.ReadAll(resp)
resp.Close()
@@ -327,7 +326,7 @@ func TestSaveAndLoadPlatform(t *testing.T) {
assert.NilError(t, err)
// remove the pulled image
_, err = apiClient.ImageRemove(ctx, repoName, image.RemoveOptions{})
_, err = apiClient.ImageRemove(ctx, repoName, client.ImageRemoveOptions{})
assert.NilError(t, err)
// load the full exported image (all platforms in it)
@@ -348,12 +347,12 @@ func TestSaveAndLoadPlatform(t *testing.T) {
}
// remove the loaded image
_, err = apiClient.ImageRemove(ctx, repoName, image.RemoveOptions{})
_, err = apiClient.ImageRemove(ctx, repoName, client.ImageRemoveOptions{})
assert.NilError(t, err)
// pull the image again (start fresh)
for _, p := range tc.pullPlatforms {
resp, err := apiClient.ImagePull(ctx, repoName, image.PullOptions{Platform: p})
resp, err := apiClient.ImagePull(ctx, repoName, client.ImagePullOptions{Platform: p})
assert.NilError(t, err)
_, err = io.ReadAll(resp)
resp.Close()
@@ -365,7 +364,7 @@ func TestSaveAndLoadPlatform(t *testing.T) {
assert.NilError(t, err)
// remove the pulled image
_, err = apiClient.ImageRemove(ctx, repoName, image.RemoveOptions{})
_, err = apiClient.ImageRemove(ctx, repoName, client.ImageRemoveOptions{})
assert.NilError(t, err)
// load the exported image on the specified platforms only

View File

@@ -7,7 +7,6 @@ import (
"testing"
"github.com/moby/moby/api/types/build"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/client"
"github.com/moby/moby/client/pkg/jsonmessage"
"github.com/moby/moby/v2/testutil/fakecontext"
@@ -15,15 +14,15 @@ import (
)
// Do builds an image from the given context and returns the image ID.
func Do(ctx context.Context, t *testing.T, client client.APIClient, buildCtx *fakecontext.Fake) string {
resp, err := client.ImageBuild(ctx, buildCtx.AsTarReader(t), build.ImageBuildOptions{})
func Do(ctx context.Context, t *testing.T, apiClient client.APIClient, buildCtx *fakecontext.Fake) string {
resp, err := apiClient.ImageBuild(ctx, buildCtx.AsTarReader(t), build.ImageBuildOptions{})
if resp.Body != nil {
defer resp.Body.Close()
}
assert.NilError(t, err)
img := GetImageIDFromBody(t, resp.Body)
t.Cleanup(func() {
client.ImageRemove(ctx, img, image.RemoveOptions{Force: true})
apiClient.ImageRemove(ctx, img, client.ImageRemoveOptions{Force: true})
})
return img
}

View File

@@ -21,7 +21,6 @@ import (
"github.com/moby/go-archive"
containertypes "github.com/moby/moby/api/types/container"
eventtypes "github.com/moby/moby/api/types/events"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/client"
"github.com/moby/moby/v2/integration/internal/container"
"github.com/moby/moby/v2/pkg/authorization"
@@ -460,9 +459,9 @@ func imageImport(ctx context.Context, apiClient client.APIClient, path string) e
return err
}
defer file.Close()
options := image.ImportOptions{}
options := client.ImageImportOptions{}
ref := ""
source := image.ImportSource{
source := client.ImageImportSource{
Source: file,
SourceName: "-",
}

View File

@@ -11,7 +11,6 @@ import (
"github.com/moby/moby/api/types/build"
containertypes "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/mount"
"github.com/moby/moby/api/types/network"
"github.com/moby/moby/api/types/versions"
@@ -149,7 +148,7 @@ func TestRunMountImage(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
testImage := setupTestImage(t, ctx, apiClient, tc.name)
if testImage != "" {
defer apiClient.ImageRemove(ctx, testImage, image.RemoveOptions{Force: true})
defer apiClient.ImageRemove(ctx, testImage, client.ImageRemoveOptions{Force: true})
}
cfg := containertypes.Config{
@@ -195,7 +194,7 @@ func TestRunMountImage(t *testing.T) {
if tc.name == "image_remove" {
img, _ := apiClient.ImageInspect(ctx, testImage)
imgId := strings.Split(img.ID, ":")[1]
_, removeErr := apiClient.ImageRemove(ctx, testImage, image.RemoveOptions{})
_, removeErr := apiClient.ImageRemove(ctx, testImage, client.ImageRemoveOptions{})
assert.ErrorContains(t, removeErr, fmt.Sprintf(`container %s is using its referenced image %s`, id[:12], imgId[:12]))
}
@@ -204,7 +203,7 @@ func TestRunMountImage(t *testing.T) {
stopErr := apiClient.ContainerStop(ctx, id, containertypes.StopOptions{})
assert.NilError(t, stopErr)
_, removeErr := apiClient.ImageRemove(ctx, testImage, image.RemoveOptions{Force: true})
_, removeErr := apiClient.ImageRemove(ctx, testImage, client.ImageRemoveOptions{Force: true})
assert.NilError(t, removeErr)
startContainer(id)

View File

@@ -8,7 +8,6 @@ import (
cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/network"
"github.com/moby/moby/client"
"go.opentelemetry.io/otel"
@@ -96,7 +95,7 @@ func getAllContainers(ctx context.Context, t testing.TB, client client.Container
func deleteAllImages(ctx context.Context, t testing.TB, apiclient client.ImageAPIClient, protectedImages map[string]struct{}) {
t.Helper()
images, err := apiclient.ImageList(ctx, image.ListOptions{})
images, err := apiclient.ImageList(ctx, client.ImageListOptions{})
assert.Check(t, err, "failed to list images")
for _, img := range images {
@@ -118,7 +117,7 @@ func deleteAllImages(ctx context.Context, t testing.TB, apiclient client.ImageAP
func removeImage(ctx context.Context, t testing.TB, apiclient client.ImageAPIClient, ref string) {
t.Helper()
_, err := apiclient.ImageRemove(ctx, ref, image.RemoveOptions{
_, err := apiclient.ImageRemove(ctx, ref, client.ImageRemoveOptions{
Force: true,
})
if cerrdefs.IsNotFound(err) {

View File

@@ -10,7 +10,6 @@ import (
"github.com/moby/moby/api/types"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/system"
"github.com/moby/moby/client"
"github.com/moby/moby/v2/testutil/fixtures/load"
@@ -198,7 +197,7 @@ func (e *Execution) UsingSnapshotter() bool {
// Note that this is done by filtering and then checking whether there were any
// results -- so ambiguous references might result in false-positives.
func (e *Execution) HasExistingImage(t testing.TB, reference string) bool {
imageList, err := e.APIClient().ImageList(context.Background(), image.ListOptions{
imageList, err := e.APIClient().ImageList(context.Background(), client.ImageListOptions{
All: true,
Filters: filters.NewArgs(
filters.Arg("dangling", "false"),

View File

@@ -116,8 +116,8 @@ func ProtectImages(ctx context.Context, t testing.TB, testEnv *Execution) {
func getExistingImages(ctx context.Context, t testing.TB, testEnv *Execution) []string {
t.Helper()
client := testEnv.APIClient()
imageList, err := client.ImageList(ctx, image.ListOptions{
apiClient := testEnv.APIClient()
imageList, err := apiClient.ImageList(ctx, client.ImageListOptions{
All: true,
Filters: filters.NewArgs(filters.Arg("dangling", "false")),
})

View File

@@ -13,7 +13,6 @@ import (
"github.com/moby/moby/api/types/build"
containertypes "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/client"
"github.com/moby/moby/v2/testutil"
"github.com/moby/moby/v2/testutil/environment"
@@ -114,7 +113,7 @@ func (f *remoteFileServer) Close() error {
}
}
if f.image != "" {
if _, err := f.client.ImageRemove(context.Background(), f.image, image.RemoveOptions{Force: true}); err != nil {
if _, err := f.client.ImageRemove(context.Background(), f.image, client.ImageRemoveOptions{Force: true}); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Error closing remote file server: removing image: %v\n", err)
}
}

View File

@@ -10,7 +10,6 @@ import (
"strings"
"sync"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/client"
"github.com/moby/moby/client/pkg/jsonmessage"
"github.com/moby/term"
@@ -28,13 +27,13 @@ const frozenImgDir = "/docker-frozen-images"
// TODO: This loads whatever is in the frozen image dir, regardless of what
// images were passed in. If the images need to be downloaded, then it will respect
// the passed in images
func FrozenImagesLinux(ctx context.Context, client client.APIClient, images ...string) error {
func FrozenImagesLinux(ctx context.Context, apiClient client.APIClient, images ...string) error {
ctx, span := otel.Tracer("").Start(ctx, "LoadFrozenImages")
defer span.End()
var loadImages []struct{ srcName, destName string }
for _, img := range images {
if !imageExists(ctx, client, img) {
if !imageExists(ctx, apiClient, img) {
srcName := img
// hello-world:latest gets re-tagged as hello-world:frozen
// there are some tests that use hello-world:latest specifically so it pulls
@@ -60,21 +59,21 @@ func FrozenImagesLinux(ctx context.Context, client client.APIClient, images ...s
for _, img := range loadImages {
srcImages = append(srcImages, img.srcName)
}
if err := pullImages(ctx, client, srcImages); err != nil {
if err := pullImages(ctx, apiClient, srcImages); err != nil {
return errors.Wrap(err, "error pulling image list")
}
} else {
if err := loadFrozenImages(ctx, client); err != nil {
if err := loadFrozenImages(ctx, apiClient); err != nil {
return err
}
}
for _, img := range loadImages {
if img.srcName != img.destName {
if err := client.ImageTag(ctx, img.srcName, img.destName); err != nil {
if err := apiClient.ImageTag(ctx, img.srcName, img.destName); err != nil {
return errors.Wrapf(err, "failed to tag %s as %s", img.srcName, img.destName)
}
if _, err := client.ImageRemove(ctx, img.srcName, image.RemoveOptions{}); err != nil {
if _, err := apiClient.ImageRemove(ctx, img.srcName, client.ImageRemoveOptions{}); err != nil {
return errors.Wrapf(err, "failed to remove %s", img.srcName)
}
}
@@ -152,7 +151,7 @@ func pullImages(ctx context.Context, client client.APIClient, images []string) e
return <-chErr
}
func pullTagAndRemove(ctx context.Context, client client.APIClient, ref string, tag string) (retErr error) {
func pullTagAndRemove(ctx context.Context, apiClient client.APIClient, ref string, tag string) (retErr error) {
ctx, span := otel.Tracer("").Start(ctx, "pull image: "+ref+" with tag: "+tag)
defer func() {
if retErr != nil {
@@ -162,7 +161,7 @@ func pullTagAndRemove(ctx context.Context, client client.APIClient, ref string,
span.End()
}()
resp, err := client.ImagePull(ctx, ref, image.PullOptions{})
resp, err := apiClient.ImagePull(ctx, ref, client.ImagePullOptions{})
if err != nil {
return errors.Wrapf(err, "failed to pull %s", ref)
}
@@ -172,10 +171,10 @@ func pullTagAndRemove(ctx context.Context, client client.APIClient, ref string,
return err
}
if err := client.ImageTag(ctx, ref, tag); err != nil {
if err := apiClient.ImageTag(ctx, ref, tag); err != nil {
return errors.Wrapf(err, "failed to tag %s as %s", ref, tag)
}
_, err = client.ImageRemove(ctx, ref, image.RemoveOptions{})
_, err = apiClient.ImageRemove(ctx, ref, client.ImageRemoveOptions{})
return errors.Wrapf(err, "failed to remove %s", ref)
}

View File

@@ -1,124 +0,0 @@
package image
import (
"context"
"io"
"github.com/moby/moby/api/types/filters"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// ImportSource holds source information for ImageImport
type ImportSource struct {
Source io.Reader // Source is the data to send to the server to create this image from. You must set SourceName to "-" to leverage this.
SourceName string // SourceName is the name of the image to pull. Set to "-" to leverage the Source attribute.
}
// ImportOptions holds information to import images from the client host.
type ImportOptions struct {
Tag string // Tag is the name to tag this image with. This attribute is deprecated.
Message string // Message is the message to tag the image with
Changes []string // Changes are the raw changes to apply to this image
Platform string // Platform is the target platform of the image
}
// CreateOptions holds information to create images.
type CreateOptions 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.
}
// PullOptions holds information to pull images.
type PullOptions struct {
All bool
RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry
// PrivilegeFunc is a function that clients can supply to retry operations
// after getting an authorization error. This function returns the registry
// authentication header value in base64 encoded format, or an error if the
// privilege request fails.
//
// For details, refer to [github.com/moby/moby/api/types/registry.RequestAuthConfig].
PrivilegeFunc func(context.Context) (string, error)
Platform string
}
// PushOptions holds information to push images.
type PushOptions struct {
All bool
RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry
// PrivilegeFunc is a function that clients can supply to retry operations
// after getting an authorization error. This function returns the registry
// authentication header value in base64 encoded format, or an error if the
// privilege request fails.
//
// For details, refer to [github.com/moby/moby/api/types/registry.RequestAuthConfig].
PrivilegeFunc func(context.Context) (string, error)
// Platform is an optional field that selects a specific platform to push
// when the image is a multi-platform image.
// Using this will only push a single platform-specific manifest.
Platform *ocispec.Platform `json:",omitempty"`
}
// ListOptions holds parameters to list images with.
type ListOptions struct {
// All controls whether all images in the graph are filtered, or just
// the heads.
All bool
// Filters is a JSON-encoded set of filter arguments.
Filters filters.Args
// SharedSize indicates whether the shared size of images should be computed.
SharedSize bool
// ContainerCount indicates whether container count should be computed.
//
// Deprecated: This field has been unused and is no longer required and will be removed in a future version.
ContainerCount bool
// Manifests indicates whether the image manifests should be returned.
Manifests bool
}
// RemoveOptions holds parameters to remove images.
type RemoveOptions struct {
Platforms []ocispec.Platform
Force bool
PruneChildren bool
}
// HistoryOptions holds parameters to get image history.
type HistoryOptions struct {
// Platform from the manifest list to use for history.
Platform *ocispec.Platform
}
// LoadOptions holds parameters to load images.
type LoadOptions struct {
// Quiet suppresses progress output
Quiet bool
// Platforms selects the platforms to load if the image is a
// multi-platform image and has multiple variants.
Platforms []ocispec.Platform
}
type InspectOptions struct {
// Manifests returns the image manifests.
Manifests bool
// Platform selects the specific platform of a multi-platform image to inspect.
//
// This option is only available for API version 1.49 and up.
Platform *ocispec.Platform
}
// SaveOptions holds parameters to save images.
type SaveOptions struct {
// Platforms selects the platforms to save if the image is a
// multi-platform image and has multiple variants.
Platforms []ocispec.Platform
}

View File

@@ -109,13 +109,13 @@ type ImageAPIClient interface {
ImageBuild(ctx context.Context, context io.Reader, options build.ImageBuildOptions) (build.ImageBuildResponse, error)
BuildCachePrune(ctx context.Context, opts build.CachePruneOptions) (*build.CachePruneReport, error)
BuildCancel(ctx context.Context, id string) error
ImageCreate(ctx context.Context, parentReference string, options image.CreateOptions) (io.ReadCloser, error)
ImageImport(ctx context.Context, source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, 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)
ImageList(ctx context.Context, options image.ListOptions) ([]image.Summary, error)
ImagePull(ctx context.Context, ref string, options image.PullOptions) (io.ReadCloser, error)
ImagePush(ctx context.Context, ref string, options image.PushOptions) (io.ReadCloser, error)
ImageRemove(ctx context.Context, image string, options image.RemoveOptions) ([]image.DeleteResponse, error)
ImageList(ctx context.Context, options ImageListOptions) ([]image.Summary, error)
ImagePull(ctx context.Context, ref string, options ImagePullOptions) (io.ReadCloser, error)
ImagePush(ctx context.Context, ref string, options ImagePushOptions) (io.ReadCloser, error)
ImageRemove(ctx context.Context, image string, options ImageRemoveOptions) ([]image.DeleteResponse, error)
ImageSearch(ctx context.Context, term string, options ImageSearchOptions) ([]registry.SearchResult, error)
ImageTag(ctx context.Context, image, ref string) error
ImagesPrune(ctx context.Context, pruneFilter filters.Args) (image.PruneReport, error)

View File

@@ -8,13 +8,12 @@ import (
"strings"
"github.com/distribution/reference"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/registry"
)
// 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 image.CreateOptions) (io.ReadCloser, error) {
func (cli *Client) ImageCreate(ctx context.Context, parentReference string, options ImageCreateOptions) (io.ReadCloser, error) {
ref, err := reference.ParseNormalizedNamed(parentReference)
if err != nil {
return nil, err

View File

@@ -0,0 +1,7 @@
package client
// 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.
}

View File

@@ -1,8 +1,6 @@
package client
import (
"github.com/moby/moby/api/types/image"
)
import ocispec "github.com/opencontainers/image-spec/specs-go/v1"
// ImageHistoryOption is a type representing functional options for the image history operation.
type ImageHistoryOption interface {
@@ -15,5 +13,10 @@ func (f imageHistoryOptionFunc) Apply(o *imageHistoryOpts) error {
}
type imageHistoryOpts struct {
apiOptions image.HistoryOptions
apiOptions imageHistoryOptions
}
type imageHistoryOptions struct {
// Platform from the manifest list to use for history.
Platform *ocispec.Platform
}

View File

@@ -7,12 +7,11 @@ import (
"strings"
"github.com/distribution/reference"
"github.com/moby/moby/api/types/image"
)
// 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 image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) {
func (cli *Client) ImageImport(ctx context.Context, source ImageImportSource, ref string, options ImageImportOptions) (io.ReadCloser, error) {
if ref != "" {
// Check if the given image name can be resolved
if _, err := reference.ParseNormalizedNamed(ref); err != nil {

View File

@@ -0,0 +1,19 @@
package client
import (
"io"
)
// ImageImportSource holds source information for ImageImport
type ImageImportSource struct {
Source io.Reader // Source is the data to send to the server to create this image from. You must set SourceName to "-" to leverage this.
SourceName string // SourceName is the name of the image to pull. Set to "-" to leverage the Source attribute.
}
// ImageImportOptions holds information to import images from the client host.
type ImageImportOptions struct {
Tag string // Tag is the name to tag this image with. This attribute is deprecated.
Message string // Message is the message to tag the image with
Changes []string // Changes are the raw changes to apply to this image
Platform string // Platform is the target platform of the image
}

View File

@@ -3,7 +3,6 @@ package client
import (
"bytes"
"github.com/moby/moby/api/types/image"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
@@ -50,7 +49,7 @@ func ImageInspectWithPlatform(platform *ocispec.Platform) ImageInspectOption {
}
// ImageInspectWithAPIOpts sets the API options for the image inspect operation.
func ImageInspectWithAPIOpts(opts image.InspectOptions) ImageInspectOption {
func ImageInspectWithAPIOpts(opts ImageInspectOptions) ImageInspectOption {
return imageInspectOptionFunc(func(clientOpts *imageInspectOpts) error {
clientOpts.apiOptions = opts
return nil
@@ -59,5 +58,15 @@ func ImageInspectWithAPIOpts(opts image.InspectOptions) ImageInspectOption {
type imageInspectOpts struct {
raw *bytes.Buffer
apiOptions image.InspectOptions
apiOptions ImageInspectOptions
}
type ImageInspectOptions struct {
// Manifests returns the image manifests.
Manifests bool
// Platform selects the specific platform of a multi-platform image to inspect.
//
// This option is only available for API version 1.49 and up.
Platform *ocispec.Platform
}

View File

@@ -16,7 +16,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 image.ListOptions) ([]image.Summary, error) {
func (cli *Client) ImageList(ctx context.Context, options ImageListOptions) ([]image.Summary, error) {
var images []image.Summary
// Make sure we negotiated (if the client is configured to do so),

24
vendor/github.com/moby/moby/client/image_list_opts.go generated vendored Normal file
View File

@@ -0,0 +1,24 @@
package client
import "github.com/moby/moby/api/types/filters"
// ImageListOptions holds parameters to list images with.
type ImageListOptions struct {
// All controls whether all images in the graph are filtered, or just
// the heads.
All bool
// Filters is a JSON-encoded set of filter arguments.
Filters filters.Args
// SharedSize indicates whether the shared size of images should be computed.
SharedSize bool
// ContainerCount indicates whether container count should be computed.
//
// Deprecated: This field has been unused and is no longer required and will be removed in a future version.
ContainerCount bool
// Manifests indicates whether the image manifests should be returned.
Manifests bool
}

View File

@@ -3,7 +3,6 @@ package client
import (
"fmt"
"github.com/moby/moby/api/types/image"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
@@ -18,7 +17,16 @@ func (f imageLoadOptionFunc) Apply(o *imageLoadOpts) error {
}
type imageLoadOpts struct {
apiOptions image.LoadOptions
apiOptions imageLoadOptions
}
type imageLoadOptions struct {
// Quiet suppresses progress output
Quiet bool
// Platforms selects the platforms to load if the image is a
// multi-platform image and has multiple variants.
Platforms []ocispec.Platform
}
// ImageLoadWithQuiet sets the quiet option for the image load operation.

View File

@@ -8,14 +8,13 @@ import (
cerrdefs "github.com/containerd/errdefs"
"github.com/distribution/reference"
"github.com/moby/moby/api/types/image"
)
// ImagePull requests the docker host to pull an image from a remote registry.
// It executes the privileged function if the operation is unauthorized
// and it tries one more time.
// It's up to the caller to handle the [io.ReadCloser] and close it.
func (cli *Client) ImagePull(ctx context.Context, refStr string, options image.PullOptions) (io.ReadCloser, error) {
func (cli *Client) ImagePull(ctx context.Context, refStr string, options ImagePullOptions) (io.ReadCloser, error) {
// FIXME(vdemeester): there is currently used in a few way in docker/docker
// - if not in trusted content, ref is used to pass the whole reference, and tag is empty
// - if in trusted content, ref is used to pass the reference name, and tag for the digest

18
vendor/github.com/moby/moby/client/image_pull_opts.go generated vendored Normal file
View File

@@ -0,0 +1,18 @@
package client
import "context"
// ImagePullOptions holds information to pull images.
type ImagePullOptions struct {
All bool
RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry
// PrivilegeFunc is a function that clients can supply to retry operations
// after getting an authorization error. This function returns the registry
// authentication header value in base64 encoded format, or an error if the
// privilege request fails.
//
// For details, refer to [github.com/moby/moby/api/types/registry.RequestAuthConfig].
PrivilegeFunc func(context.Context) (string, error)
Platform string
}

View File

@@ -11,7 +11,6 @@ import (
cerrdefs "github.com/containerd/errdefs"
"github.com/distribution/reference"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/registry"
)
@@ -19,7 +18,7 @@ import (
// It executes the privileged function if the operation is unauthorized
// and it tries one more time.
// It's up to the caller to handle the [io.ReadCloser] and close it.
func (cli *Client) ImagePush(ctx context.Context, image string, options image.PushOptions) (io.ReadCloser, error) {
func (cli *Client) ImagePush(ctx context.Context, image string, options ImagePushOptions) (io.ReadCloser, error) {
ref, err := reference.ParseNormalizedNamed(image)
if err != nil {
return nil, err

26
vendor/github.com/moby/moby/client/image_push_opts.go generated vendored Normal file
View File

@@ -0,0 +1,26 @@
package client
import (
"context"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// ImagePushOptions holds information to push images.
type ImagePushOptions struct {
All bool
RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry
// PrivilegeFunc is a function that clients can supply to retry operations
// after getting an authorization error. This function returns the registry
// authentication header value in base64 encoded format, or an error if the
// privilege request fails.
//
// For details, refer to [github.com/moby/moby/api/types/registry.RequestAuthConfig].
PrivilegeFunc func(context.Context) (string, error)
// Platform is an optional field that selects a specific platform to push
// when the image is a multi-platform image.
// Using this will only push a single platform-specific manifest.
Platform *ocispec.Platform `json:",omitempty"`
}

View File

@@ -9,7 +9,7 @@ import (
)
// ImageRemove removes an image from the docker host.
func (cli *Client) ImageRemove(ctx context.Context, imageID string, options image.RemoveOptions) ([]image.DeleteResponse, error) {
func (cli *Client) ImageRemove(ctx context.Context, imageID string, options ImageRemoveOptions) ([]image.DeleteResponse, error) {
query := url.Values{}
if options.Force {

View File

@@ -0,0 +1,10 @@
package client
import ocispec "github.com/opencontainers/image-spec/specs-go/v1"
// ImageRemoveOptions holds parameters to remove images.
type ImageRemoveOptions struct {
Platforms []ocispec.Platform
Force bool
PruneChildren bool
}

View File

@@ -3,7 +3,6 @@ package client
import (
"fmt"
"github.com/moby/moby/api/types/image"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
@@ -29,5 +28,11 @@ func ImageSaveWithPlatforms(platforms ...ocispec.Platform) ImageSaveOption {
}
type imageSaveOpts struct {
apiOptions image.SaveOptions
apiOptions imageSaveOptions
}
type imageSaveOptions struct {
// Platforms selects the platforms to save if the image is a
// multi-platform image and has multiple variants.
Platforms []ocispec.Platform
}