The field will still be present in the response, but will always be
`false`.
Searching for `is-automated=true` will yield no results, while
`is-automated=false` will effectively be a no-op.
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
| ... | ... |
@@ -8774,8 +8774,7 @@ paths: |
| 8774 | 8774 |
|
| 8775 | 8775 |
<p><br /></p> |
| 8776 | 8776 |
|
| 8777 |
- > **Deprecated**: This field is deprecated and will always |
|
| 8778 |
- > be "false" in future. |
|
| 8777 |
+ > **Deprecated**: This field is deprecated and will always be "false". |
|
| 8779 | 8778 |
type: "boolean" |
| 8780 | 8779 |
example: false |
| 8781 | 8780 |
name: |
| ... | ... |
@@ -8818,13 +8817,8 @@ paths: |
| 8818 | 8818 |
description: | |
| 8819 | 8819 |
A JSON encoded value of the filters (a `map[string][]string`) to process on the images list. Available filters: |
| 8820 | 8820 |
|
| 8821 |
- - `is-automated=(true|false)` (deprecated, see below) |
|
| 8822 | 8821 |
- `is-official=(true|false)` |
| 8823 | 8822 |
- `stars=<number>` Matches images that has at least 'number' stars. |
| 8824 |
- |
|
| 8825 |
- The `is-automated` filter is deprecated. The `is_automated` field has |
|
| 8826 |
- been deprecated by Docker Hub's search API. Consequently, searching |
|
| 8827 |
- for `is-automated=true` will yield no results. |
|
| 8828 | 8823 |
type: "string" |
| 8829 | 8824 |
tags: ["Image"] |
| 8830 | 8825 |
/images/prune: |
| ... | ... |
@@ -94,7 +94,7 @@ type SearchResult struct {
|
| 94 | 94 |
Name string `json:"name"` |
| 95 | 95 |
// IsAutomated indicates whether the result is automated. |
| 96 | 96 |
// |
| 97 |
- // Deprecated: the "is_automated" field is deprecated and will always be "false" in the future. |
|
| 97 |
+ // Deprecated: the "is_automated" field is deprecated and will always be "false". |
|
| 98 | 98 |
IsAutomated bool `json:"is_automated"` |
| 99 | 99 |
// Description is a textual description of the repository |
| 100 | 100 |
Description string `json:"description"` |
| ... | ... |
@@ -19,6 +19,9 @@ keywords: "API, Docker, rcli, REST, documentation" |
| 19 | 19 |
|
| 20 | 20 |
* `POST /containers/create` now supports `VolumeOptions.Subpath` which allows a |
| 21 | 21 |
subpath of a named volume to be mounted. |
| 22 |
+* `POST /images/search` will always assume a `false` value for the `is-automated` |
|
| 23 |
+ field. Consequently, searching for `is-automated=true` will yield no results, |
|
| 24 |
+ while `is-automated=false` will be a no-op. |
|
| 22 | 25 |
|
| 23 | 26 |
## v1.44 API changes |
| 24 | 27 |
|
| ... | ... |
@@ -8,6 +8,7 @@ import ( |
| 8 | 8 |
|
| 9 | 9 |
"github.com/docker/docker/integration-cli/cli" |
| 10 | 10 |
"gotest.tools/v3/assert" |
| 11 |
+ is "gotest.tools/v3/assert/cmp" |
|
| 11 | 12 |
) |
| 12 | 13 |
|
| 13 | 14 |
type DockerCLISearchSuite struct {
|
| ... | ... |
@@ -52,9 +53,9 @@ func (s *DockerCLISearchSuite) TestSearchCmdOptions(c *testing.T) {
|
| 52 | 52 |
|
| 53 | 53 |
outSearchCmdautomated := cli.DockerCmd(c, "search", "--filter", "is-automated=true", "busybox").Combined() // The busybox is a busybox base image, not an AUTOMATED image. |
| 54 | 54 |
outSearchCmdautomatedSlice := strings.Split(outSearchCmdautomated, "\n") |
| 55 |
- for i := range outSearchCmdautomatedSlice {
|
|
| 56 |
- assert.Assert(c, !strings.HasPrefix(outSearchCmdautomatedSlice[i], "busybox "), "The busybox is not an AUTOMATED image: %s", outSearchCmdautomated) |
|
| 57 |
- } |
|
| 55 |
+ |
|
| 56 |
+ // is-automated=true should produce no results (only a header) |
|
| 57 |
+ assert.Check(c, is.Len(outSearchCmdautomatedSlice, 2)) |
|
| 58 | 58 |
|
| 59 | 59 |
outSearchCmdNotOfficial := cli.DockerCmd(c, "search", "--filter", "is-official=false", "busybox").Combined() // The busybox is a busybox base image, official image. |
| 60 | 60 |
outSearchCmdNotOfficialSlice := strings.Split(outSearchCmdNotOfficial, "\n") |
| ... | ... |
@@ -27,11 +27,16 @@ func (s *Service) Search(ctx context.Context, searchFilters filters.Args, term s |
| 27 | 27 |
return nil, err |
| 28 | 28 |
} |
| 29 | 29 |
|
| 30 |
- // TODO(thaJeztah): the "is-automated" field is deprecated; reset the field for the next release (v26.0.0). Return early when using "is-automated=true", and ignore "is-automated=false". |
|
| 31 | 30 |
isAutomated, err := searchFilters.GetBoolOrDefault("is-automated", false)
|
| 32 | 31 |
if err != nil {
|
| 33 | 32 |
return nil, err |
| 34 | 33 |
} |
| 34 |
+ |
|
| 35 |
+ // "is-automated" is deprecated and filtering for `true` will yield no results. |
|
| 36 |
+ if isAutomated {
|
|
| 37 |
+ return []registry.SearchResult{}, nil
|
|
| 38 |
+ } |
|
| 39 |
+ |
|
| 35 | 40 |
isOfficial, err := searchFilters.GetBoolOrDefault("is-official", false)
|
| 36 | 41 |
if err != nil {
|
| 37 | 42 |
return nil, err |
| ... | ... |
@@ -51,7 +56,6 @@ func (s *Service) Search(ctx context.Context, searchFilters filters.Args, term s |
| 51 | 51 |
} |
| 52 | 52 |
} |
| 53 | 53 |
|
| 54 |
- // TODO(thaJeztah): the "is-automated" field is deprecated. Reset the field for the next release (v26.0.0) if any "true" values are present. |
|
| 55 | 54 |
unfilteredResult, err := s.searchUnfiltered(ctx, term, limit, authConfig, headers) |
| 56 | 55 |
if err != nil {
|
| 57 | 56 |
return nil, err |
| ... | ... |
@@ -59,11 +63,6 @@ func (s *Service) Search(ctx context.Context, searchFilters filters.Args, term s |
| 59 | 59 |
|
| 60 | 60 |
filteredResults := []registry.SearchResult{}
|
| 61 | 61 |
for _, result := range unfilteredResult.Results {
|
| 62 |
- if searchFilters.Contains("is-automated") {
|
|
| 63 |
- if isAutomated != result.IsAutomated { //nolint:staticcheck // ignore SA1019 for old API versions.
|
|
| 64 |
- continue |
|
| 65 |
- } |
|
| 66 |
- } |
|
| 67 | 62 |
if searchFilters.Contains("is-official") {
|
| 68 | 63 |
if isOfficial != result.IsOfficial {
|
| 69 | 64 |
continue |
| ... | ... |
@@ -74,6 +73,10 @@ func (s *Service) Search(ctx context.Context, searchFilters filters.Args, term s |
| 74 | 74 |
continue |
| 75 | 75 |
} |
| 76 | 76 |
} |
| 77 |
+ // "is-automated" is deprecated and the value in Docker Hub search |
|
| 78 |
+ // results is untrustworthy. Force it to false so as to not mislead our |
|
| 79 |
+ // clients. |
|
| 80 |
+ result.IsAutomated = false //nolint:staticcheck // ignore SA1019 (field is deprecated) |
|
| 77 | 81 |
filteredResults = append(filteredResults, result) |
| 78 | 82 |
} |
| 79 | 83 |
|
| ... | ... |
@@ -206,25 +206,25 @@ func TestSearch(t *testing.T) {
|
| 206 | 206 |
IsAutomated: true, //nolint:staticcheck // ignore SA1019 (field is deprecated). |
| 207 | 207 |
}, |
| 208 | 208 |
}, |
| 209 |
- expectedResults: []registry.SearchResult{
|
|
| 209 |
+ expectedResults: []registry.SearchResult{},
|
|
| 210 |
+ }, |
|
| 211 |
+ {
|
|
| 212 |
+ name: "is-automated=false, IsAutomated reset to false", |
|
| 213 |
+ filtersArgs: filters.NewArgs(filters.Arg("is-automated", "false")),
|
|
| 214 |
+ registryResults: []registry.SearchResult{
|
|
| 210 | 215 |
{
|
| 211 | 216 |
Name: "name", |
| 212 | 217 |
Description: "description", |
| 213 | 218 |
IsAutomated: true, //nolint:staticcheck // ignore SA1019 (field is deprecated). |
| 214 | 219 |
}, |
| 215 | 220 |
}, |
| 216 |
- }, |
|
| 217 |
- {
|
|
| 218 |
- name: "is-automated=false, no results", |
|
| 219 |
- filtersArgs: filters.NewArgs(filters.Arg("is-automated", "false")),
|
|
| 220 |
- registryResults: []registry.SearchResult{
|
|
| 221 |
+ expectedResults: []registry.SearchResult{
|
|
| 221 | 222 |
{
|
| 222 | 223 |
Name: "name", |
| 223 | 224 |
Description: "description", |
| 224 |
- IsAutomated: true, //nolint:staticcheck // ignore SA1019 (field is deprecated). |
|
| 225 |
+ IsAutomated: false, //nolint:staticcheck // ignore SA1019 (field is deprecated). |
|
| 225 | 226 |
}, |
| 226 | 227 |
}, |
| 227 |
- expectedResults: []registry.SearchResult{},
|
|
| 228 | 228 |
}, |
| 229 | 229 |
{
|
| 230 | 230 |
name: "is-automated=false", |
| ... | ... |
@@ -390,15 +390,7 @@ func TestSearch(t *testing.T) {
|
| 390 | 390 |
IsAutomated: true, //nolint:staticcheck // ignore SA1019 (field is deprecated). |
| 391 | 391 |
}, |
| 392 | 392 |
}, |
| 393 |
- expectedResults: []registry.SearchResult{
|
|
| 394 |
- {
|
|
| 395 |
- Name: "name3", |
|
| 396 |
- Description: "description3", |
|
| 397 |
- StarCount: 2, |
|
| 398 |
- IsOfficial: true, |
|
| 399 |
- IsAutomated: true, //nolint:staticcheck // ignore SA1019 (field is deprecated). |
|
| 400 |
- }, |
|
| 401 |
- }, |
|
| 393 |
+ expectedResults: []registry.SearchResult{},
|
|
| 402 | 394 |
}, |
| 403 | 395 |
} |
| 404 | 396 |
for _, tc := range successCases {
|