From 853aed171b168eedff0cc6e959982bd6c1cf4827 Mon Sep 17 00:00:00 2001 From: Austin Vazquez Date: Wed, 20 Aug 2025 10:28:23 -0500 Subject: [PATCH] api/types/image: move image option types to client Signed-off-by: Austin Vazquez --- api/types/image/opts.go | 124 ------------------ client/client_interfaces.go | 12 +- client/image_create.go | 3 +- client/image_create_opts.go | 7 + client/image_create_test.go | 5 +- client/image_history_opts.go | 11 +- client/image_import.go | 3 +- client/image_import_opts.go | 19 +++ client/image_import_test.go | 11 +- client/image_inspect_opts.go | 15 ++- client/image_list.go | 2 +- client/image_list_opts.go | 24 ++++ client/image_list_test.go | 20 +-- client/image_load_opts.go | 12 +- client/image_pull.go | 3 +- client/image_pull_opts.go | 18 +++ client/image_pull_test.go | 15 +-- client/image_push.go | 3 +- client/image_push_opts.go | 26 ++++ client/image_push_test.go | 17 ++- client/image_remove.go | 2 +- client/image_remove_opts.go | 10 ++ client/image_remove_test.go | 6 +- client/image_save_opts.go | 9 +- daemon/containerd/image_delete.go | 3 +- daemon/containerd/image_delete_test.go | 4 +- daemon/containerd/image_list.go | 5 +- daemon/containerd/image_list_test.go | 9 +- daemon/containerd/image_load_test.go | 6 +- daemon/disk_usage.go | 3 +- daemon/image_service.go | 5 +- daemon/images/image_delete.go | 3 +- daemon/images/image_list.go | 3 +- daemon/images/image_prune.go | 5 +- daemon/server/imagebackend/image.go | 27 ++++ daemon/server/router/image/backend.go | 5 +- daemon/server/router/image/image_routes.go | 6 +- integration-cli/docker_api_build_test.go | 8 +- integration-cli/docker_api_images_test.go | 11 +- integration/build/build_test.go | 2 +- integration/container/export_test.go | 8 +- integration/daemon/daemon_test.go | 18 +-- integration/daemon/migration_test.go | 5 +- integration/image/import_test.go | 28 ++-- integration/image/inspect_test.go | 3 +- integration/image/list_test.go | 16 +-- integration/image/load_test.go | 11 +- integration/image/prune_test.go | 2 +- integration/image/pull_test.go | 20 +-- integration/image/remove_test.go | 37 +++--- integration/image/save_test.go | 11 +- integration/internal/build/build.go | 7 +- integration/plugin/authz/authz_plugin_test.go | 5 +- integration/volume/mount_test.go | 7 +- testutil/environment/clean.go | 5 +- testutil/environment/environment.go | 3 +- testutil/environment/protect.go | 4 +- testutil/fakestorage/storage.go | 3 +- testutil/fixtures/load/frozen.go | 21 ++- .../moby/moby/api/types/image/opts.go | 124 ------------------ .../moby/moby/client/client_interfaces.go | 12 +- .../moby/moby/client/image_create.go | 3 +- .../moby/moby/client/image_create_opts.go | 7 + .../moby/moby/client/image_history_opts.go | 11 +- .../moby/moby/client/image_import.go | 3 +- .../moby/moby/client/image_import_opts.go | 19 +++ .../moby/moby/client/image_inspect_opts.go | 15 ++- .../github.com/moby/moby/client/image_list.go | 2 +- .../moby/moby/client/image_list_opts.go | 24 ++++ .../moby/moby/client/image_load_opts.go | 12 +- .../github.com/moby/moby/client/image_pull.go | 3 +- .../moby/moby/client/image_pull_opts.go | 18 +++ .../github.com/moby/moby/client/image_push.go | 3 +- .../moby/moby/client/image_push_opts.go | 26 ++++ .../moby/moby/client/image_remove.go | 2 +- .../moby/moby/client/image_remove_opts.go | 10 ++ .../moby/moby/client/image_save_opts.go | 9 +- 77 files changed, 512 insertions(+), 487 deletions(-) delete mode 100644 api/types/image/opts.go create mode 100644 client/image_create_opts.go create mode 100644 client/image_import_opts.go create mode 100644 client/image_list_opts.go create mode 100644 client/image_pull_opts.go create mode 100644 client/image_push_opts.go create mode 100644 client/image_remove_opts.go create mode 100644 daemon/server/imagebackend/image.go delete mode 100644 vendor/github.com/moby/moby/api/types/image/opts.go create mode 100644 vendor/github.com/moby/moby/client/image_create_opts.go create mode 100644 vendor/github.com/moby/moby/client/image_import_opts.go create mode 100644 vendor/github.com/moby/moby/client/image_list_opts.go create mode 100644 vendor/github.com/moby/moby/client/image_pull_opts.go create mode 100644 vendor/github.com/moby/moby/client/image_push_opts.go create mode 100644 vendor/github.com/moby/moby/client/image_remove_opts.go diff --git a/api/types/image/opts.go b/api/types/image/opts.go deleted file mode 100644 index 789037a59d..0000000000 --- a/api/types/image/opts.go +++ /dev/null @@ -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 -} diff --git a/client/client_interfaces.go b/client/client_interfaces.go index f24da421d7..6b2f968bc4 100644 --- a/client/client_interfaces.go +++ b/client/client_interfaces.go @@ -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) diff --git a/client/image_create.go b/client/image_create.go index 4282158d21..12bd38f3db 100644 --- a/client/image_create.go +++ b/client/image_create.go @@ -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 diff --git a/client/image_create_opts.go b/client/image_create_opts.go new file mode 100644 index 0000000000..a55f35d4db --- /dev/null +++ b/client/image_create_opts.go @@ -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. +} diff --git a/client/image_create_test.go b/client/image_create_test.go index 1412565528..13d819daaa 100644 --- a/client/image_create_test.go +++ b/client/image_create_test.go @@ -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) diff --git a/client/image_history_opts.go b/client/image_history_opts.go index 9641219f3f..744d9fac9e 100644 --- a/client/image_history_opts.go +++ b/client/image_history_opts.go @@ -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 } diff --git a/client/image_import.go b/client/image_import.go index b95438fbe8..9db6a21033 100644 --- a/client/image_import.go +++ b/client/image_import.go @@ -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 { diff --git a/client/image_import_opts.go b/client/image_import_opts.go new file mode 100644 index 0000000000..c0c1c1b6de --- /dev/null +++ b/client/image_import_opts.go @@ -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 +} diff --git a/client/image_import_test.go b/client/image_import_test.go index ce9b4c45fa..cc50adda70 100644 --- a/client/image_import_test.go +++ b/client/image_import_test.go @@ -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) diff --git a/client/image_inspect_opts.go b/client/image_inspect_opts.go index 8b67519e75..93b5a95696 100644 --- a/client/image_inspect_opts.go +++ b/client/image_inspect_opts.go @@ -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 } diff --git a/client/image_list.go b/client/image_list.go index d29a7300ed..fe5e0ea6a6 100644 --- a/client/image_list.go +++ b/client/image_list.go @@ -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), diff --git a/client/image_list_opts.go b/client/image_list_opts.go new file mode 100644 index 0000000000..a4f76818eb --- /dev/null +++ b/client/image_list_opts.go @@ -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 +} diff --git a/client/image_list_test.go b/client/image_list_test.go index fd32f58fc9..4b92011087 100644 --- a/client/image_list_test.go +++ b/client/image_list_test.go @@ -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() diff --git a/client/image_load_opts.go b/client/image_load_opts.go index 6681a63ddd..8792f64a0c 100644 --- a/client/image_load_opts.go +++ b/client/image_load_opts.go @@ -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. diff --git a/client/image_pull.go b/client/image_pull.go index 2a9613db9a..6cefaa9479 100644 --- a/client/image_pull.go +++ b/client/image_pull.go @@ -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 diff --git a/client/image_pull_opts.go b/client/image_pull_opts.go new file mode 100644 index 0000000000..618540902c --- /dev/null +++ b/client/image_pull_opts.go @@ -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 +} diff --git a/client/image_pull_test.go b/client/image_pull_test.go index 1a37a2b4b9..1a6aed88bf 100644 --- a/client/image_pull_test.go +++ b/client/image_pull_test.go @@ -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) diff --git a/client/image_push.go b/client/image_push.go index 1ac5f43f55..1bab22d16c 100644 --- a/client/image_push.go +++ b/client/image_push.go @@ -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 diff --git a/client/image_push_opts.go b/client/image_push_opts.go new file mode 100644 index 0000000000..591c6b6057 --- /dev/null +++ b/client/image_push_opts.go @@ -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"` +} diff --git a/client/image_push_test.go b/client/image_push_test.go index 37a4833304..db8ff00ed1 100644 --- a/client/image_push_test.go +++ b/client/image_push_test.go @@ -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) diff --git a/client/image_remove.go b/client/image_remove.go index fb3175e6ab..738e647b31 100644 --- a/client/image_remove.go +++ b/client/image_remove.go @@ -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 { diff --git a/client/image_remove_opts.go b/client/image_remove_opts.go new file mode 100644 index 0000000000..07161f58ed --- /dev/null +++ b/client/image_remove_opts.go @@ -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 +} diff --git a/client/image_remove_test.go b/client/image_remove_test.go index c0e91af9f9..b2bc446a22 100644 --- a/client/image_remove_test.go +++ b/client/image_remove_test.go @@ -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, } diff --git a/client/image_save_opts.go b/client/image_save_opts.go index 787e78bda9..c51c2d5354 100644 --- a/client/image_save_opts.go +++ b/client/image_save_opts.go @@ -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 } diff --git a/daemon/containerd/image_delete.go b/daemon/containerd/image_delete.go index 314dc385a6..c4c06c58ac 100644 --- a/daemon/containerd/image_delete.go +++ b/daemon/containerd/image_delete.go @@ -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 { diff --git a/daemon/containerd/image_delete_test.go b/daemon/containerd/image_delete_test.go index 062a10ab5f..b2eca925d3 100644 --- a/daemon/containerd/image_delete_test.go +++ b/daemon/containerd/image_delete_test.go @@ -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 { diff --git a/daemon/containerd/image_list.go b/daemon/containerd/image_list.go index 9863cb8517..bd584b2d65 100644 --- a/daemon/containerd/image_list.go +++ b/daemon/containerd/image_list.go @@ -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 { diff --git a/daemon/containerd/image_list_test.go b/daemon/containerd/image_list_test.go index 179e22117a..5217cd3f11 100644 --- a/daemon/containerd/image_list_test.go +++ b/daemon/containerd/image_list_test.go @@ -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, } diff --git a/daemon/containerd/image_load_test.go b/daemon/containerd/image_load_test.go index 5ca4ecaaf6..2396f3c95f 100644 --- a/daemon/containerd/image_load_test.go +++ b/daemon/containerd/image_load_test.go @@ -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) } diff --git a/daemon/disk_usage.go b/daemon/disk_usage.go index 1ba3990ba4..0da2c9cbc5 100644 --- a/daemon/disk_usage.go +++ b/daemon/disk_usage.go @@ -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, }) diff --git a/daemon/image_service.go b/daemon/image_service.go index ab7a160bc6..4683035874 100644 --- a/daemon/image_service.go +++ b/daemon/image_service.go @@ -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) diff --git a/daemon/images/image_delete.go b/daemon/images/image_delete.go index 811b73218e..cc62450035 100644 --- a/daemon/images/image_delete.go +++ b/daemon/images/image_delete.go @@ -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{} diff --git a/daemon/images/image_list.go b/daemon/images/image_list.go index bc0c5d8102..4870758d9c 100644 --- a/daemon/images/image_list.go +++ b/daemon/images/image_list.go @@ -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 } diff --git a/daemon/images/image_prune.go b/daemon/images/image_prune.go index 3dc10fa9e0..8c454d51e7 100644 --- a/daemon/images/image_prune.go +++ b/daemon/images/image_prune.go @@ -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) { diff --git a/daemon/server/imagebackend/image.go b/daemon/server/imagebackend/image.go new file mode 100644 index 0000000000..ae284bc027 --- /dev/null +++ b/daemon/server/imagebackend/image.go @@ -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 +} diff --git a/daemon/server/router/image/backend.go b/daemon/server/router/image/backend.go index 216046854a..7bf5d69cba 100644 --- a/daemon/server/router/image/backend.go +++ b/daemon/server/router/image/backend.go @@ -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 diff --git a/daemon/server/router/image/image_routes.go b/daemon/server/router/image/image_routes.go index 57cd8bb92a..813e7c5f22 100644 --- a/daemon/server/router/image/image_routes.go +++ b/daemon/server/router/image/image_routes.go @@ -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, diff --git a/integration-cli/docker_api_build_test.go b/integration-cli/docker_api_build_test.go index ea4534e047..09cf93ba45 100644 --- a/integration-cli/docker_api_build_test.go +++ b/integration-cli/docker_api_build_test.go @@ -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) diff --git a/integration-cli/docker_api_images_test.go b/integration-cli/docker_api_images_test.go index 08b2d87685..4d29db7ee8 100644 --- a/integration-cli/docker_api_images_test.go +++ b/integration-cli/docker_api_images_test.go @@ -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 { diff --git a/integration/build/build_test.go b/integration/build/build_test.go index 1d41098736..48c47b00d4 100644 --- a/integration/build/build_test.go +++ b/integration/build/build_test.go @@ -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 != "" diff --git a/integration/container/export_test.go b/integration/container/export_test.go index fd8a9c1667..cc0d935de3 100644 --- a/integration/container/export_test.go +++ b/integration/container/export_test.go @@ -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) diff --git a/integration/daemon/daemon_test.go b/integration/daemon/daemon_test.go index b50a1f0e99..2ddef62271 100644 --- a/integration/daemon/daemon_test.go +++ b/integration/daemon/daemon_test.go @@ -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) }) diff --git a/integration/daemon/migration_test.go b/integration/daemon/migration_test.go index 78f45de791..822e538f14 100644 --- a/integration/daemon/migration_test.go +++ b/integration/daemon/migration_test.go @@ -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) } diff --git a/integration/image/import_test.go b/integration/image/import_test.go index 63113afd26..ba3652424a 100644 --- a/integration/image/import_test.go +++ b/integration/image/import_test.go @@ -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)) diff --git a/integration/image/inspect_test.go b/integration/image/inspect_test.go index d3d20ffaf4..35836fd625 100644 --- a/integration/image/inspect_test.go +++ b/integration/image/inspect_test.go @@ -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}) }() } diff --git a/integration/image/list_test.go b/integration/image/list_test.go index 35531229a1..68b301b5d2 100644 --- a/integration/image/list_test.go +++ b/integration/image/list_test.go @@ -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)) diff --git a/integration/image/load_test.go b/integration/image/load_test.go index c6656d80f3..c9a81bd328 100644 --- a/integration/image/load_test.go +++ b/integration/image/load_test.go @@ -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") diff --git a/integration/image/prune_test.go b/integration/image/prune_test.go index e27849f4d6..832a60c05f 100644 --- a/integration/image/prune_test.go +++ b/integration/image/prune_test.go @@ -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 diff --git a/integration/image/pull_test.go b/integration/image/pull_test.go index abb6f12c82..76a1cc4a45 100644 --- a/integration/image/pull_test.go +++ b/integration/image/pull_test.go @@ -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() diff --git a/integration/image/remove_test.go b/integration/image/remove_test.go index 1603f1d38e..a780e40f97 100644 --- a/integration/image/remove_test.go +++ b/integration/image/remove_test.go @@ -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)) diff --git a/integration/image/save_test.go b/integration/image/save_test.go index f36a14bb76..cd99dc43a2 100644 --- a/integration/image/save_test.go +++ b/integration/image/save_test.go @@ -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 diff --git a/integration/internal/build/build.go b/integration/internal/build/build.go index 4b8e06c974..b22719f1dc 100644 --- a/integration/internal/build/build.go +++ b/integration/internal/build/build.go @@ -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 } diff --git a/integration/plugin/authz/authz_plugin_test.go b/integration/plugin/authz/authz_plugin_test.go index 866c0fc462..2ebf26b045 100644 --- a/integration/plugin/authz/authz_plugin_test.go +++ b/integration/plugin/authz/authz_plugin_test.go @@ -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: "-", } diff --git a/integration/volume/mount_test.go b/integration/volume/mount_test.go index e4d6641f32..d7265354e3 100644 --- a/integration/volume/mount_test.go +++ b/integration/volume/mount_test.go @@ -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) diff --git a/testutil/environment/clean.go b/testutil/environment/clean.go index 3650e3f684..a217c0b499 100644 --- a/testutil/environment/clean.go +++ b/testutil/environment/clean.go @@ -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) { diff --git a/testutil/environment/environment.go b/testutil/environment/environment.go index 2ab1f6433e..9a30fab7f2 100644 --- a/testutil/environment/environment.go +++ b/testutil/environment/environment.go @@ -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"), diff --git a/testutil/environment/protect.go b/testutil/environment/protect.go index ac983dbc67..1bdacf6487 100644 --- a/testutil/environment/protect.go +++ b/testutil/environment/protect.go @@ -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")), }) diff --git a/testutil/fakestorage/storage.go b/testutil/fakestorage/storage.go index 0aba810618..e8f4960798 100644 --- a/testutil/fakestorage/storage.go +++ b/testutil/fakestorage/storage.go @@ -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) } } diff --git a/testutil/fixtures/load/frozen.go b/testutil/fixtures/load/frozen.go index d14a10144d..6e6e21d760 100644 --- a/testutil/fixtures/load/frozen.go +++ b/testutil/fixtures/load/frozen.go @@ -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) } diff --git a/vendor/github.com/moby/moby/api/types/image/opts.go b/vendor/github.com/moby/moby/api/types/image/opts.go deleted file mode 100644 index 789037a59d..0000000000 --- a/vendor/github.com/moby/moby/api/types/image/opts.go +++ /dev/null @@ -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 -} diff --git a/vendor/github.com/moby/moby/client/client_interfaces.go b/vendor/github.com/moby/moby/client/client_interfaces.go index f24da421d7..6b2f968bc4 100644 --- a/vendor/github.com/moby/moby/client/client_interfaces.go +++ b/vendor/github.com/moby/moby/client/client_interfaces.go @@ -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) diff --git a/vendor/github.com/moby/moby/client/image_create.go b/vendor/github.com/moby/moby/client/image_create.go index 4282158d21..12bd38f3db 100644 --- a/vendor/github.com/moby/moby/client/image_create.go +++ b/vendor/github.com/moby/moby/client/image_create.go @@ -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 diff --git a/vendor/github.com/moby/moby/client/image_create_opts.go b/vendor/github.com/moby/moby/client/image_create_opts.go new file mode 100644 index 0000000000..a55f35d4db --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_create_opts.go @@ -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. +} diff --git a/vendor/github.com/moby/moby/client/image_history_opts.go b/vendor/github.com/moby/moby/client/image_history_opts.go index 9641219f3f..744d9fac9e 100644 --- a/vendor/github.com/moby/moby/client/image_history_opts.go +++ b/vendor/github.com/moby/moby/client/image_history_opts.go @@ -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 } diff --git a/vendor/github.com/moby/moby/client/image_import.go b/vendor/github.com/moby/moby/client/image_import.go index b95438fbe8..9db6a21033 100644 --- a/vendor/github.com/moby/moby/client/image_import.go +++ b/vendor/github.com/moby/moby/client/image_import.go @@ -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 { diff --git a/vendor/github.com/moby/moby/client/image_import_opts.go b/vendor/github.com/moby/moby/client/image_import_opts.go new file mode 100644 index 0000000000..c0c1c1b6de --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_import_opts.go @@ -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 +} diff --git a/vendor/github.com/moby/moby/client/image_inspect_opts.go b/vendor/github.com/moby/moby/client/image_inspect_opts.go index 8b67519e75..93b5a95696 100644 --- a/vendor/github.com/moby/moby/client/image_inspect_opts.go +++ b/vendor/github.com/moby/moby/client/image_inspect_opts.go @@ -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 } diff --git a/vendor/github.com/moby/moby/client/image_list.go b/vendor/github.com/moby/moby/client/image_list.go index d29a7300ed..fe5e0ea6a6 100644 --- a/vendor/github.com/moby/moby/client/image_list.go +++ b/vendor/github.com/moby/moby/client/image_list.go @@ -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), diff --git a/vendor/github.com/moby/moby/client/image_list_opts.go b/vendor/github.com/moby/moby/client/image_list_opts.go new file mode 100644 index 0000000000..a4f76818eb --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_list_opts.go @@ -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 +} diff --git a/vendor/github.com/moby/moby/client/image_load_opts.go b/vendor/github.com/moby/moby/client/image_load_opts.go index 6681a63ddd..8792f64a0c 100644 --- a/vendor/github.com/moby/moby/client/image_load_opts.go +++ b/vendor/github.com/moby/moby/client/image_load_opts.go @@ -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. diff --git a/vendor/github.com/moby/moby/client/image_pull.go b/vendor/github.com/moby/moby/client/image_pull.go index 2a9613db9a..6cefaa9479 100644 --- a/vendor/github.com/moby/moby/client/image_pull.go +++ b/vendor/github.com/moby/moby/client/image_pull.go @@ -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 diff --git a/vendor/github.com/moby/moby/client/image_pull_opts.go b/vendor/github.com/moby/moby/client/image_pull_opts.go new file mode 100644 index 0000000000..618540902c --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_pull_opts.go @@ -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 +} diff --git a/vendor/github.com/moby/moby/client/image_push.go b/vendor/github.com/moby/moby/client/image_push.go index 1ac5f43f55..1bab22d16c 100644 --- a/vendor/github.com/moby/moby/client/image_push.go +++ b/vendor/github.com/moby/moby/client/image_push.go @@ -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 diff --git a/vendor/github.com/moby/moby/client/image_push_opts.go b/vendor/github.com/moby/moby/client/image_push_opts.go new file mode 100644 index 0000000000..591c6b6057 --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_push_opts.go @@ -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"` +} diff --git a/vendor/github.com/moby/moby/client/image_remove.go b/vendor/github.com/moby/moby/client/image_remove.go index fb3175e6ab..738e647b31 100644 --- a/vendor/github.com/moby/moby/client/image_remove.go +++ b/vendor/github.com/moby/moby/client/image_remove.go @@ -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 { diff --git a/vendor/github.com/moby/moby/client/image_remove_opts.go b/vendor/github.com/moby/moby/client/image_remove_opts.go new file mode 100644 index 0000000000..07161f58ed --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_remove_opts.go @@ -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 +} diff --git a/vendor/github.com/moby/moby/client/image_save_opts.go b/vendor/github.com/moby/moby/client/image_save_opts.go index 787e78bda9..c51c2d5354 100644 --- a/vendor/github.com/moby/moby/client/image_save_opts.go +++ b/vendor/github.com/moby/moby/client/image_save_opts.go @@ -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 }