diff --git a/api/swagger.yaml b/api/swagger.yaml
index b58310f327..5677340dbd 100644
--- a/api/swagger.yaml
+++ b/api/swagger.yaml
@@ -8774,8 +8774,7 @@ paths:
- > **Deprecated**: This field is deprecated and will always
- > be "false" in future.
+ > **Deprecated**: This field is deprecated and will always be "false".
type: "boolean"
example: false
name:
@@ -8818,13 +8817,8 @@ paths:
description: |
A JSON encoded value of the filters (a `map[string][]string`) to process on the images list. Available filters:
- - `is-automated=(true|false)` (deprecated, see below)
- `is-official=(true|false)`
- `stars=` Matches images that has at least 'number' stars.
-
- The `is-automated` filter is deprecated. The `is_automated` field has
- been deprecated by Docker Hub's search API. Consequently, searching
- for `is-automated=true` will yield no results.
type: "string"
tags: ["Image"]
/images/prune:
diff --git a/api/types/registry/registry.go b/api/types/registry/registry.go
index 05cb31075f..6bbae93ef2 100644
--- a/api/types/registry/registry.go
+++ b/api/types/registry/registry.go
@@ -94,7 +94,7 @@ type SearchResult struct {
Name string `json:"name"`
// IsAutomated indicates whether the result is automated.
//
- // Deprecated: the "is_automated" field is deprecated and will always be "false" in the future.
+ // Deprecated: the "is_automated" field is deprecated and will always be "false".
IsAutomated bool `json:"is_automated"`
// Description is a textual description of the repository
Description string `json:"description"`
diff --git a/docs/api/version-history.md b/docs/api/version-history.md
index b1f701b74b..a91d01237e 100644
--- a/docs/api/version-history.md
+++ b/docs/api/version-history.md
@@ -19,6 +19,9 @@ keywords: "API, Docker, rcli, REST, documentation"
* `POST /containers/create` now supports `VolumeOptions.Subpath` which allows a
subpath of a named volume to be mounted.
+* `POST /images/search` will always assume a `false` value for the `is-automated`
+ field. Consequently, searching for `is-automated=true` will yield no results,
+ while `is-automated=false` will be a no-op.
## v1.44 API changes
diff --git a/integration-cli/docker_cli_search_test.go b/integration-cli/docker_cli_search_test.go
index 09c3a85720..2a0691bbf4 100644
--- a/integration-cli/docker_cli_search_test.go
+++ b/integration-cli/docker_cli_search_test.go
@@ -8,6 +8,7 @@ import (
"github.com/docker/docker/integration-cli/cli"
"gotest.tools/v3/assert"
+ is "gotest.tools/v3/assert/cmp"
)
type DockerCLISearchSuite struct {
@@ -52,9 +53,9 @@ func (s *DockerCLISearchSuite) TestSearchCmdOptions(c *testing.T) {
outSearchCmdautomated := cli.DockerCmd(c, "search", "--filter", "is-automated=true", "busybox").Combined() // The busybox is a busybox base image, not an AUTOMATED image.
outSearchCmdautomatedSlice := strings.Split(outSearchCmdautomated, "\n")
- for i := range outSearchCmdautomatedSlice {
- assert.Assert(c, !strings.HasPrefix(outSearchCmdautomatedSlice[i], "busybox "), "The busybox is not an AUTOMATED image: %s", outSearchCmdautomated)
- }
+
+ // is-automated=true should produce no results (only a header)
+ assert.Check(c, is.Len(outSearchCmdautomatedSlice, 2))
outSearchCmdNotOfficial := cli.DockerCmd(c, "search", "--filter", "is-official=false", "busybox").Combined() // The busybox is a busybox base image, official image.
outSearchCmdNotOfficialSlice := strings.Split(outSearchCmdNotOfficial, "\n")
diff --git a/registry/search.go b/registry/search.go
index 75a5444109..5c79e9968b 100644
--- a/registry/search.go
+++ b/registry/search.go
@@ -27,11 +27,16 @@ func (s *Service) Search(ctx context.Context, searchFilters filters.Args, term s
return nil, err
}
- // 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".
isAutomated, err := searchFilters.GetBoolOrDefault("is-automated", false)
if err != nil {
return nil, err
}
+
+ // "is-automated" is deprecated and filtering for `true` will yield no results.
+ if isAutomated {
+ return []registry.SearchResult{}, nil
+ }
+
isOfficial, err := searchFilters.GetBoolOrDefault("is-official", false)
if err != nil {
return nil, err
@@ -51,7 +56,6 @@ func (s *Service) Search(ctx context.Context, searchFilters filters.Args, term s
}
}
- // TODO(thaJeztah): the "is-automated" field is deprecated. Reset the field for the next release (v26.0.0) if any "true" values are present.
unfilteredResult, err := s.searchUnfiltered(ctx, term, limit, authConfig, headers)
if err != nil {
return nil, err
@@ -59,11 +63,6 @@ func (s *Service) Search(ctx context.Context, searchFilters filters.Args, term s
filteredResults := []registry.SearchResult{}
for _, result := range unfilteredResult.Results {
- if searchFilters.Contains("is-automated") {
- if isAutomated != result.IsAutomated { //nolint:staticcheck // ignore SA1019 for old API versions.
- continue
- }
- }
if searchFilters.Contains("is-official") {
if isOfficial != result.IsOfficial {
continue
@@ -74,6 +73,10 @@ func (s *Service) Search(ctx context.Context, searchFilters filters.Args, term s
continue
}
}
+ // "is-automated" is deprecated and the value in Docker Hub search
+ // results is untrustworthy. Force it to false so as to not mislead our
+ // clients.
+ result.IsAutomated = false //nolint:staticcheck // ignore SA1019 (field is deprecated)
filteredResults = append(filteredResults, result)
}
diff --git a/registry/search_test.go b/registry/search_test.go
index f9e1bd95ed..82b7757963 100644
--- a/registry/search_test.go
+++ b/registry/search_test.go
@@ -206,16 +206,10 @@ func TestSearch(t *testing.T) {
IsAutomated: true, //nolint:staticcheck // ignore SA1019 (field is deprecated).
},
},
- expectedResults: []registry.SearchResult{
- {
- Name: "name",
- Description: "description",
- IsAutomated: true, //nolint:staticcheck // ignore SA1019 (field is deprecated).
- },
- },
+ expectedResults: []registry.SearchResult{},
},
{
- name: "is-automated=false, no results",
+ name: "is-automated=false, IsAutomated reset to false",
filtersArgs: filters.NewArgs(filters.Arg("is-automated", "false")),
registryResults: []registry.SearchResult{
{
@@ -224,7 +218,13 @@ func TestSearch(t *testing.T) {
IsAutomated: true, //nolint:staticcheck // ignore SA1019 (field is deprecated).
},
},
- expectedResults: []registry.SearchResult{},
+ expectedResults: []registry.SearchResult{
+ {
+ Name: "name",
+ Description: "description",
+ IsAutomated: false, //nolint:staticcheck // ignore SA1019 (field is deprecated).
+ },
+ },
},
{
name: "is-automated=false",
@@ -390,15 +390,7 @@ func TestSearch(t *testing.T) {
IsAutomated: true, //nolint:staticcheck // ignore SA1019 (field is deprecated).
},
},
- expectedResults: []registry.SearchResult{
- {
- Name: "name3",
- Description: "description3",
- StarCount: 2,
- IsOfficial: true,
- IsAutomated: true, //nolint:staticcheck // ignore SA1019 (field is deprecated).
- },
- },
+ expectedResults: []registry.SearchResult{},
},
}
for _, tc := range successCases {