Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
| ... | ... |
@@ -8,7 +8,6 @@ import ( |
| 8 | 8 |
"github.com/moby/moby/api/types" |
| 9 | 9 |
"github.com/moby/moby/api/types/container" |
| 10 | 10 |
"github.com/moby/moby/api/types/events" |
| 11 |
- "github.com/moby/moby/api/types/image" |
|
| 12 | 11 |
"github.com/moby/moby/api/types/network" |
| 13 | 12 |
"github.com/moby/moby/api/types/plugin" |
| 14 | 13 |
"github.com/moby/moby/api/types/registry" |
| ... | ... |
@@ -114,8 +113,8 @@ type ImageAPIClient interface {
|
| 114 | 114 |
ImageList(ctx context.Context, options ImageListOptions) (ImageListResult, error) |
| 115 | 115 |
ImagePull(ctx context.Context, ref string, options ImagePullOptions) (ImagePullResponse, error) |
| 116 | 116 |
ImagePush(ctx context.Context, ref string, options ImagePushOptions) (ImagePushResponse, error) |
| 117 |
- ImageRemove(ctx context.Context, image string, options ImageRemoveOptions) ([]image.DeleteResponse, error) |
|
| 118 |
- ImageSearch(ctx context.Context, term string, options ImageSearchOptions) ([]registry.SearchResult, error) |
|
| 117 |
+ ImageRemove(ctx context.Context, image string, options ImageRemoveOptions) (ImageRemoveResult, error) |
|
| 118 |
+ ImageSearch(ctx context.Context, term string, options ImageSearchOptions) (ImageSearchResult, error) |
|
| 119 | 119 |
ImageTag(ctx context.Context, image, ref string) error |
| 120 | 120 |
ImagesPrune(ctx context.Context, opts ImagePruneOptions) (ImagePruneResult, error) |
| 121 | 121 |
|
| ... | ... |
@@ -9,7 +9,7 @@ import ( |
| 9 | 9 |
) |
| 10 | 10 |
|
| 11 | 11 |
// ImageRemove removes an image from the docker host. |
| 12 |
-func (cli *Client) ImageRemove(ctx context.Context, imageID string, options ImageRemoveOptions) ([]image.DeleteResponse, error) {
|
|
| 12 |
+func (cli *Client) ImageRemove(ctx context.Context, imageID string, options ImageRemoveOptions) (ImageRemoveResult, error) {
|
|
| 13 | 13 |
query := url.Values{}
|
| 14 | 14 |
|
| 15 | 15 |
if options.Force {
|
| ... | ... |
@@ -22,7 +22,7 @@ func (cli *Client) ImageRemove(ctx context.Context, imageID string, options Imag |
| 22 | 22 |
if len(options.Platforms) > 0 {
|
| 23 | 23 |
p, err := encodePlatforms(options.Platforms...) |
| 24 | 24 |
if err != nil {
|
| 25 |
- return nil, err |
|
| 25 |
+ return ImageRemoveResult{}, err
|
|
| 26 | 26 |
} |
| 27 | 27 |
query["platforms"] = p |
| 28 | 28 |
} |
| ... | ... |
@@ -30,10 +30,10 @@ func (cli *Client) ImageRemove(ctx context.Context, imageID string, options Imag |
| 30 | 30 |
resp, err := cli.delete(ctx, "/images/"+imageID, query, nil) |
| 31 | 31 |
defer ensureReaderClosed(resp) |
| 32 | 32 |
if err != nil {
|
| 33 |
- return nil, err |
|
| 33 |
+ return ImageRemoveResult{}, err
|
|
| 34 | 34 |
} |
| 35 | 35 |
|
| 36 | 36 |
var dels []image.DeleteResponse |
| 37 | 37 |
err = json.NewDecoder(resp.Body).Decode(&dels) |
| 38 |
- return dels, err |
|
| 38 |
+ return ImageRemoveResult{Deleted: dels}, err
|
|
| 39 | 39 |
} |
| ... | ... |
@@ -1,6 +1,9 @@ |
| 1 | 1 |
package client |
| 2 | 2 |
|
| 3 |
-import ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
|
| 3 |
+import ( |
|
| 4 |
+ "github.com/moby/moby/api/types/image" |
|
| 5 |
+ ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
|
| 6 |
+) |
|
| 4 | 7 |
|
| 5 | 8 |
// ImageRemoveOptions holds parameters to remove images. |
| 6 | 9 |
type ImageRemoveOptions struct {
|
| ... | ... |
@@ -8,3 +11,8 @@ type ImageRemoveOptions struct {
|
| 8 | 8 |
Force bool |
| 9 | 9 |
PruneChildren bool |
| 10 | 10 |
} |
| 11 |
+ |
|
| 12 |
+// ImageRemoveResult holds the delete responses returned by the daemon. |
|
| 13 |
+type ImageRemoveResult struct {
|
|
| 14 |
+ Deleted []image.DeleteResponse |
|
| 15 |
+} |
| ... | ... |
@@ -108,6 +108,6 @@ func TestImageRemove(t *testing.T) {
|
| 108 | 108 |
|
| 109 | 109 |
imageDeletes, err := client.ImageRemove(context.Background(), "image_id", opts) |
| 110 | 110 |
assert.NilError(t, err) |
| 111 |
- assert.Check(t, is.Len(imageDeletes, 2)) |
|
| 111 |
+ assert.Check(t, is.Len(imageDeletes.Deleted, 2)) |
|
| 112 | 112 |
} |
| 113 | 113 |
} |
| ... | ... |
@@ -13,7 +13,7 @@ import ( |
| 13 | 13 |
|
| 14 | 14 |
// ImageSearch makes the docker host search by a term in a remote registry. |
| 15 | 15 |
// The list of results is not sorted in any fashion. |
| 16 |
-func (cli *Client) ImageSearch(ctx context.Context, term string, options ImageSearchOptions) ([]registry.SearchResult, error) {
|
|
| 16 |
+func (cli *Client) ImageSearch(ctx context.Context, term string, options ImageSearchOptions) (ImageSearchResult, error) {
|
|
| 17 | 17 |
var results []registry.SearchResult |
| 18 | 18 |
query := url.Values{}
|
| 19 | 19 |
query.Set("term", term)
|
| ... | ... |
@@ -28,16 +28,16 @@ func (cli *Client) ImageSearch(ctx context.Context, term string, options ImageSe |
| 28 | 28 |
if cerrdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil {
|
| 29 | 29 |
newAuthHeader, privilegeErr := options.PrivilegeFunc(ctx) |
| 30 | 30 |
if privilegeErr != nil {
|
| 31 |
- return results, privilegeErr |
|
| 31 |
+ return ImageSearchResult{}, privilegeErr
|
|
| 32 | 32 |
} |
| 33 | 33 |
resp, err = cli.tryImageSearch(ctx, query, newAuthHeader) |
| 34 | 34 |
} |
| 35 | 35 |
if err != nil {
|
| 36 |
- return results, err |
|
| 36 |
+ return ImageSearchResult{}, err
|
|
| 37 | 37 |
} |
| 38 | 38 |
|
| 39 | 39 |
err = json.NewDecoder(resp.Body).Decode(&results) |
| 40 |
- return results, err |
|
| 40 |
+ return ImageSearchResult{Items: results}, err
|
|
| 41 | 41 |
} |
| 42 | 42 |
|
| 43 | 43 |
func (cli *Client) tryImageSearch(ctx context.Context, query url.Values, registryAuth string) (*http.Response, error) {
|
| ... | ... |
@@ -2,8 +2,15 @@ package client |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"context" |
| 5 |
+ |
|
| 6 |
+ "github.com/moby/moby/api/types/registry" |
|
| 5 | 7 |
) |
| 6 | 8 |
|
| 9 |
+// ImageSearchResult wraps results returned by ImageSearch. |
|
| 10 |
+type ImageSearchResult struct {
|
|
| 11 |
+ Items []registry.SearchResult |
|
| 12 |
+} |
|
| 13 |
+ |
|
| 7 | 14 |
// ImageSearchOptions holds parameters to search images with. |
| 8 | 15 |
type ImageSearchOptions struct {
|
| 9 | 16 |
RegistryAuth string |
| ... | ... |
@@ -97,7 +97,7 @@ func TestImageSearchWithPrivilegedFuncNoError(t *testing.T) {
|
| 97 | 97 |
PrivilegeFunc: privilegeFunc, |
| 98 | 98 |
}) |
| 99 | 99 |
assert.NilError(t, err) |
| 100 |
- assert.Check(t, is.Len(results, 1)) |
|
| 100 |
+ assert.Check(t, is.Len(results.Items, 1)) |
|
| 101 | 101 |
} |
| 102 | 102 |
|
| 103 | 103 |
func TestImageSearchWithoutErrors(t *testing.T) {
|
| ... | ... |
@@ -135,5 +135,5 @@ func TestImageSearchWithoutErrors(t *testing.T) {
|
| 135 | 135 |
Filters: make(Filters).Add("is-automated", "true").Add("stars", "3"),
|
| 136 | 136 |
}) |
| 137 | 137 |
assert.NilError(t, err) |
| 138 |
- assert.Check(t, is.Len(results, 1)) |
|
| 138 |
+ assert.Check(t, is.Len(results.Items, 1)) |
|
| 139 | 139 |
} |
| ... | ... |
@@ -800,9 +800,9 @@ func TestBuildHistoryDoesNotPreventRemoval(t *testing.T) {
|
| 800 | 800 |
err := buildImage("history-a")
|
| 801 | 801 |
assert.NilError(t, err) |
| 802 | 802 |
|
| 803 |
- resp, err := apiClient.ImageRemove(ctx, "history-a", client.ImageRemoveOptions{})
|
|
| 803 |
+ res, err := apiClient.ImageRemove(ctx, "history-a", client.ImageRemoveOptions{})
|
|
| 804 | 804 |
assert.NilError(t, err) |
| 805 |
- assert.Check(t, slices.ContainsFunc(resp, func(r image.DeleteResponse) bool {
|
|
| 805 |
+ assert.Check(t, slices.ContainsFunc(res.Deleted, func(r image.DeleteResponse) bool {
|
|
| 806 | 806 |
return r.Deleted != "" |
| 807 | 807 |
})) |
| 808 | 808 |
} |
| ... | ... |
@@ -142,25 +142,25 @@ func TestRemoveWithPlatform(t *testing.T) {
|
| 142 | 142 |
{platform: &platformHost, deleted: descs[0]},
|
| 143 | 143 |
{platform: &someOtherPlatform, deleted: descs[3]},
|
| 144 | 144 |
} {
|
| 145 |
- resp, err := apiClient.ImageRemove(ctx, imgName, client.ImageRemoveOptions{
|
|
| 145 |
+ res, err := apiClient.ImageRemove(ctx, imgName, client.ImageRemoveOptions{
|
|
| 146 | 146 |
Platforms: []ocispec.Platform{*tc.platform},
|
| 147 | 147 |
Force: true, |
| 148 | 148 |
}) |
| 149 | 149 |
assert.NilError(t, err) |
| 150 |
- assert.Check(t, is.Len(resp, 1)) |
|
| 151 |
- for _, r := range resp {
|
|
| 150 |
+ assert.Check(t, is.Len(res.Deleted, 1)) |
|
| 151 |
+ for _, r := range res.Deleted {
|
|
| 152 | 152 |
assert.Check(t, is.Equal(r.Untagged, ""), "No image should be untagged") |
| 153 | 153 |
} |
| 154 |
- checkPlatformDeleted(t, imageIdx, resp, tc.deleted) |
|
| 154 |
+ checkPlatformDeleted(t, imageIdx, res.Deleted, tc.deleted) |
|
| 155 | 155 |
} |
| 156 | 156 |
|
| 157 | 157 |
// Delete the rest |
| 158 | 158 |
resp, err := apiClient.ImageRemove(ctx, imgName, client.ImageRemoveOptions{})
|
| 159 | 159 |
assert.NilError(t, err) |
| 160 | 160 |
|
| 161 |
- assert.Check(t, is.Len(resp, 2)) |
|
| 162 |
- assert.Check(t, is.Equal(resp[0].Untagged, imgName)) |
|
| 163 |
- assert.Check(t, is.Equal(resp[1].Deleted, imageIdx.Manifests[0].Digest.String())) |
|
| 161 |
+ assert.Check(t, is.Len(resp.Deleted, 2)) |
|
| 162 |
+ assert.Check(t, is.Equal(resp.Deleted[0].Untagged, imgName)) |
|
| 163 |
+ assert.Check(t, is.Equal(resp.Deleted[1].Deleted, imageIdx.Manifests[0].Digest.String())) |
|
| 164 | 164 |
// TODO(vvoland): Should it also include platform-specific manifests? https://github.com/moby/moby/pull/49982 |
| 165 | 165 |
} |
| 166 | 166 |
|
| ... | ... |
@@ -8,7 +8,6 @@ import ( |
| 8 | 8 |
"github.com/moby/moby/api/types" |
| 9 | 9 |
"github.com/moby/moby/api/types/container" |
| 10 | 10 |
"github.com/moby/moby/api/types/events" |
| 11 |
- "github.com/moby/moby/api/types/image" |
|
| 12 | 11 |
"github.com/moby/moby/api/types/network" |
| 13 | 12 |
"github.com/moby/moby/api/types/plugin" |
| 14 | 13 |
"github.com/moby/moby/api/types/registry" |
| ... | ... |
@@ -114,8 +113,8 @@ type ImageAPIClient interface {
|
| 114 | 114 |
ImageList(ctx context.Context, options ImageListOptions) (ImageListResult, error) |
| 115 | 115 |
ImagePull(ctx context.Context, ref string, options ImagePullOptions) (ImagePullResponse, error) |
| 116 | 116 |
ImagePush(ctx context.Context, ref string, options ImagePushOptions) (ImagePushResponse, error) |
| 117 |
- ImageRemove(ctx context.Context, image string, options ImageRemoveOptions) ([]image.DeleteResponse, error) |
|
| 118 |
- ImageSearch(ctx context.Context, term string, options ImageSearchOptions) ([]registry.SearchResult, error) |
|
| 117 |
+ ImageRemove(ctx context.Context, image string, options ImageRemoveOptions) (ImageRemoveResult, error) |
|
| 118 |
+ ImageSearch(ctx context.Context, term string, options ImageSearchOptions) (ImageSearchResult, error) |
|
| 119 | 119 |
ImageTag(ctx context.Context, image, ref string) error |
| 120 | 120 |
ImagesPrune(ctx context.Context, opts ImagePruneOptions) (ImagePruneResult, error) |
| 121 | 121 |
|
| ... | ... |
@@ -9,7 +9,7 @@ import ( |
| 9 | 9 |
) |
| 10 | 10 |
|
| 11 | 11 |
// ImageRemove removes an image from the docker host. |
| 12 |
-func (cli *Client) ImageRemove(ctx context.Context, imageID string, options ImageRemoveOptions) ([]image.DeleteResponse, error) {
|
|
| 12 |
+func (cli *Client) ImageRemove(ctx context.Context, imageID string, options ImageRemoveOptions) (ImageRemoveResult, error) {
|
|
| 13 | 13 |
query := url.Values{}
|
| 14 | 14 |
|
| 15 | 15 |
if options.Force {
|
| ... | ... |
@@ -22,7 +22,7 @@ func (cli *Client) ImageRemove(ctx context.Context, imageID string, options Imag |
| 22 | 22 |
if len(options.Platforms) > 0 {
|
| 23 | 23 |
p, err := encodePlatforms(options.Platforms...) |
| 24 | 24 |
if err != nil {
|
| 25 |
- return nil, err |
|
| 25 |
+ return ImageRemoveResult{}, err
|
|
| 26 | 26 |
} |
| 27 | 27 |
query["platforms"] = p |
| 28 | 28 |
} |
| ... | ... |
@@ -30,10 +30,10 @@ func (cli *Client) ImageRemove(ctx context.Context, imageID string, options Imag |
| 30 | 30 |
resp, err := cli.delete(ctx, "/images/"+imageID, query, nil) |
| 31 | 31 |
defer ensureReaderClosed(resp) |
| 32 | 32 |
if err != nil {
|
| 33 |
- return nil, err |
|
| 33 |
+ return ImageRemoveResult{}, err
|
|
| 34 | 34 |
} |
| 35 | 35 |
|
| 36 | 36 |
var dels []image.DeleteResponse |
| 37 | 37 |
err = json.NewDecoder(resp.Body).Decode(&dels) |
| 38 |
- return dels, err |
|
| 38 |
+ return ImageRemoveResult{Deleted: dels}, err
|
|
| 39 | 39 |
} |
| ... | ... |
@@ -1,6 +1,9 @@ |
| 1 | 1 |
package client |
| 2 | 2 |
|
| 3 |
-import ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
|
| 3 |
+import ( |
|
| 4 |
+ "github.com/moby/moby/api/types/image" |
|
| 5 |
+ ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
|
| 6 |
+) |
|
| 4 | 7 |
|
| 5 | 8 |
// ImageRemoveOptions holds parameters to remove images. |
| 6 | 9 |
type ImageRemoveOptions struct {
|
| ... | ... |
@@ -8,3 +11,8 @@ type ImageRemoveOptions struct {
|
| 8 | 8 |
Force bool |
| 9 | 9 |
PruneChildren bool |
| 10 | 10 |
} |
| 11 |
+ |
|
| 12 |
+// ImageRemoveResult holds the delete responses returned by the daemon. |
|
| 13 |
+type ImageRemoveResult struct {
|
|
| 14 |
+ Deleted []image.DeleteResponse |
|
| 15 |
+} |
| ... | ... |
@@ -13,7 +13,7 @@ import ( |
| 13 | 13 |
|
| 14 | 14 |
// ImageSearch makes the docker host search by a term in a remote registry. |
| 15 | 15 |
// The list of results is not sorted in any fashion. |
| 16 |
-func (cli *Client) ImageSearch(ctx context.Context, term string, options ImageSearchOptions) ([]registry.SearchResult, error) {
|
|
| 16 |
+func (cli *Client) ImageSearch(ctx context.Context, term string, options ImageSearchOptions) (ImageSearchResult, error) {
|
|
| 17 | 17 |
var results []registry.SearchResult |
| 18 | 18 |
query := url.Values{}
|
| 19 | 19 |
query.Set("term", term)
|
| ... | ... |
@@ -28,16 +28,16 @@ func (cli *Client) ImageSearch(ctx context.Context, term string, options ImageSe |
| 28 | 28 |
if cerrdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil {
|
| 29 | 29 |
newAuthHeader, privilegeErr := options.PrivilegeFunc(ctx) |
| 30 | 30 |
if privilegeErr != nil {
|
| 31 |
- return results, privilegeErr |
|
| 31 |
+ return ImageSearchResult{}, privilegeErr
|
|
| 32 | 32 |
} |
| 33 | 33 |
resp, err = cli.tryImageSearch(ctx, query, newAuthHeader) |
| 34 | 34 |
} |
| 35 | 35 |
if err != nil {
|
| 36 |
- return results, err |
|
| 36 |
+ return ImageSearchResult{}, err
|
|
| 37 | 37 |
} |
| 38 | 38 |
|
| 39 | 39 |
err = json.NewDecoder(resp.Body).Decode(&results) |
| 40 |
- return results, err |
|
| 40 |
+ return ImageSearchResult{Items: results}, err
|
|
| 41 | 41 |
} |
| 42 | 42 |
|
| 43 | 43 |
func (cli *Client) tryImageSearch(ctx context.Context, query url.Values, registryAuth string) (*http.Response, error) {
|
| ... | ... |
@@ -2,8 +2,15 @@ package client |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"context" |
| 5 |
+ |
|
| 6 |
+ "github.com/moby/moby/api/types/registry" |
|
| 5 | 7 |
) |
| 6 | 8 |
|
| 9 |
+// ImageSearchResult wraps results returned by ImageSearch. |
|
| 10 |
+type ImageSearchResult struct {
|
|
| 11 |
+ Items []registry.SearchResult |
|
| 12 |
+} |
|
| 13 |
+ |
|
| 7 | 14 |
// ImageSearchOptions holds parameters to search images with. |
| 8 | 15 |
type ImageSearchOptions struct {
|
| 9 | 16 |
RegistryAuth string |