diff --git a/api/server/router/container/container_routes.go b/api/server/router/container/container_routes.go index 5a2883324c..524d9f197f 100644 --- a/api/server/router/container/container_routes.go +++ b/api/server/router/container/container_routes.go @@ -721,7 +721,7 @@ func (s *containerRouter) postContainersPrune(ctx context.Context, w http.Respon pruneFilters, err := filters.FromJSON(r.Form.Get("filters")) if err != nil { - return errdefs.InvalidParameter(err) + return err } pruneReport, err := s.backend.ContainersPrune(ctx, pruneFilters) diff --git a/api/server/router/image/backend.go b/api/server/router/image/backend.go index d54d2c0e6c..c67093950d 100644 --- a/api/server/router/image/backend.go +++ b/api/server/router/image/backend.go @@ -37,5 +37,5 @@ type importExportBackend interface { type registryBackend interface { PullImage(ctx context.Context, image, tag string, platform *specs.Platform, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error PushImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error - SearchRegistryForImages(ctx context.Context, filtersArgs string, term string, limit int, authConfig *types.AuthConfig, metaHeaders map[string][]string) (*registry.SearchResults, error) + SearchRegistryForImages(ctx context.Context, searchFilters filters.Args, term string, limit int, authConfig *types.AuthConfig, metaHeaders map[string][]string) (*registry.SearchResults, error) } diff --git a/api/server/router/image/image_routes.go b/api/server/router/image/image_routes.go index 71b0c14f64..05a7d6bfbb 100644 --- a/api/server/router/image/image_routes.go +++ b/api/server/router/image/image_routes.go @@ -16,7 +16,6 @@ import ( "github.com/docker/docker/errdefs" "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/streamformatter" - "github.com/docker/docker/registry" specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" ) @@ -290,15 +289,21 @@ func (s *imageRouter) getImagesSearch(ctx context.Context, w http.ResponseWriter headers[k] = v } } - limit := registry.DefaultSearchLimit + + var limit int if r.Form.Get("limit") != "" { - limitValue, err := strconv.Atoi(r.Form.Get("limit")) - if err != nil { - return err + var err error + limit, err = strconv.Atoi(r.Form.Get("limit")) + if err != nil || limit < 0 { + return errdefs.InvalidParameter(errors.Wrap(err, "invalid limit specified")) } - limit = limitValue } - query, err := s.backend.SearchRegistryForImages(ctx, r.Form.Get("filters"), r.Form.Get("term"), limit, config, headers) + searchFilters, err := filters.FromJSON(r.Form.Get("filters")) + if err != nil { + return err + } + + query, err := s.backend.SearchRegistryForImages(ctx, searchFilters, r.Form.Get("term"), limit, config, headers) if err != nil { return err } diff --git a/api/server/router/network/network_routes.go b/api/server/router/network/network_routes.go index 96b65c3777..69fc26a129 100644 --- a/api/server/router/network/network_routes.go +++ b/api/server/router/network/network_routes.go @@ -30,7 +30,7 @@ func (n *networkRouter) getNetworksList(ctx context.Context, w http.ResponseWrit } if err := network.ValidateFilters(filter); err != nil { - return errdefs.InvalidParameter(err) + return err } var list []types.NetworkResource diff --git a/api/server/router/swarm/cluster_routes.go b/api/server/router/swarm/cluster_routes.go index 6ab097b4fd..0751617450 100644 --- a/api/server/router/swarm/cluster_routes.go +++ b/api/server/router/swarm/cluster_routes.go @@ -164,7 +164,7 @@ func (sr *swarmRouter) getServices(ctx context.Context, w http.ResponseWriter, r } filter, err := filters.FromJSON(r.Form.Get("filters")) if err != nil { - return errdefs.InvalidParameter(err) + return err } // the status query parameter is only support in API versions >= 1.41. If diff --git a/api/server/router/volume/volume_routes.go b/api/server/router/volume/volume_routes.go index 4fa4cb53aa..e08e724579 100644 --- a/api/server/router/volume/volume_routes.go +++ b/api/server/router/volume/volume_routes.go @@ -21,7 +21,7 @@ func (v *volumeRouter) getVolumesList(ctx context.Context, w http.ResponseWriter filters, err := filters.FromJSON(r.Form.Get("filters")) if err != nil { - return errdefs.InvalidParameter(errors.Wrap(err, "error reading volume filters")) + return errors.Wrap(err, "error reading volume filters") } volumes, warnings, err := v.backend.List(ctx, filters) if err != nil { diff --git a/api/types/filters/parse.go b/api/types/filters/parse.go index 4bc91cffd6..6a2139adb3 100644 --- a/api/types/filters/parse.go +++ b/api/types/filters/parse.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/docker/docker/api/types/versions" + "github.com/pkg/errors" ) // Args stores a mapping of keys to a set of multiple values. @@ -97,7 +98,7 @@ func FromJSON(p string) (Args, error) { // Fallback to parsing arguments in the legacy slice format deprecated := map[string][]string{} if legacyErr := json.Unmarshal(raw, &deprecated); legacyErr != nil { - return args, err + return args, invalidFilter{errors.Wrap(err, "invalid filter")} } args.fields = deprecatedArgs(deprecated) @@ -247,10 +248,10 @@ func (args Args) Contains(field string) bool { return ok } -type invalidFilter string +type invalidFilter struct{ error } func (e invalidFilter) Error() string { - return "Invalid filter '" + string(e) + "'" + return e.error.Error() } func (invalidFilter) InvalidParameter() {} @@ -260,7 +261,7 @@ func (invalidFilter) InvalidParameter() {} func (args Args) Validate(accepted map[string]bool) error { for name := range args.fields { if !accepted[name] { - return invalidFilter(name) + return invalidFilter{errors.New("invalid filter '" + name + "'")} } } return nil diff --git a/api/types/filters/parse_test.go b/api/types/filters/parse_test.go index 4b68c9685d..fe7958cf5b 100644 --- a/api/types/filters/parse_test.go +++ b/api/types/filters/parse_test.go @@ -69,9 +69,14 @@ func TestFromJSON(t *testing.T) { } for _, invalid := range invalids { - if _, err := FromJSON(invalid); err == nil { + _, err := FromJSON(invalid) + if err == nil { t.Fatalf("Expected an error with %v, got nothing", invalid) } + var invalidFilterError invalidFilter + if !errors.As(err, &invalidFilterError) { + t.Fatalf("Expected an invalidFilter error, got %T", err) + } } for expectedArgs, matchers := range valid { @@ -327,9 +332,14 @@ func TestValidate(t *testing.T) { } f.Add("bogus", "running") - if err := f.Validate(valid); err == nil { + err := f.Validate(valid) + if err == nil { t.Fatal("Expected to return an error, got nil") } + var invalidFilterError invalidFilter + if !errors.As(err, &invalidFilterError) { + t.Fatalf("Expected an invalidFilter error, got %T", err) + } } func TestWalkValues(t *testing.T) { diff --git a/daemon/errors.go b/daemon/errors.go index 6f9eb54039..6ab45f30e3 100644 --- a/daemon/errors.go +++ b/daemon/errors.go @@ -115,7 +115,7 @@ type invalidFilter struct { } func (e invalidFilter) Error() string { - msg := "Invalid filter '" + e.filter + msg := "invalid filter '" + e.filter if e.value != nil { msg += fmt.Sprintf("=%s", e.value) } diff --git a/daemon/images/image_search.go b/daemon/images/image_search.go index 8b65ec709c..d991ce837c 100644 --- a/daemon/images/image_search.go +++ b/daemon/images/image_search.go @@ -21,14 +21,10 @@ var acceptedSearchFilterTags = map[string]bool{ // // TODO: this could be implemented in a registry service instead of the image // service. -func (i *ImageService) SearchRegistryForImages(ctx context.Context, filtersArgs string, term string, limit int, +func (i *ImageService) SearchRegistryForImages(ctx context.Context, searchFilters filters.Args, term string, limit int, authConfig *types.AuthConfig, headers map[string][]string) (*registrytypes.SearchResults, error) { - searchFilters, err := filters.FromJSON(filtersArgs) - if err != nil { - return nil, err - } if err := searchFilters.Validate(acceptedSearchFilterTags); err != nil { return nil, err } diff --git a/daemon/images/image_search_test.go b/daemon/images/image_search_test.go index 725349bbae..112802496c 100644 --- a/daemon/images/image_search_test.go +++ b/daemon/images/image_search_test.go @@ -7,7 +7,9 @@ import ( "testing" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/filters" registrytypes "github.com/docker/docker/api/types/registry" + "github.com/docker/docker/errdefs" "github.com/docker/docker/registry" ) @@ -21,7 +23,7 @@ type fakeService struct { func (s *fakeService) Search(ctx context.Context, term string, limit int, authConfig *types.AuthConfig, userAgent string, headers map[string][]string) (*registrytypes.SearchResults, error) { if s.shouldReturnError { - return nil, errors.New("Search unknown error") + return nil, errdefs.Unknown(errors.New("search unknown error")) } return ®istrytypes.SearchResults{ Query: s.term, @@ -32,45 +34,50 @@ func (s *fakeService) Search(ctx context.Context, term string, limit int, authCo func TestSearchRegistryForImagesErrors(t *testing.T) { errorCases := []struct { - filtersArgs string + filtersArgs filters.Args shouldReturnError bool expectedError string }{ { - expectedError: "Search unknown error", + expectedError: "search unknown error", shouldReturnError: true, }, { - filtersArgs: "invalid json", - expectedError: "invalid character 'i' looking for beginning of value", + filtersArgs: filters.NewArgs(filters.Arg("type", "custom")), + expectedError: "invalid filter 'type'", }, { - filtersArgs: `{"type":{"custom":true}}`, - expectedError: "Invalid filter 'type'", + filtersArgs: filters.NewArgs(filters.Arg("is-automated", "invalid")), + expectedError: "invalid filter 'is-automated=[invalid]'", }, { - filtersArgs: `{"is-automated":{"invalid":true}}`, - expectedError: "Invalid filter 'is-automated=[invalid]'", + filtersArgs: filters.NewArgs( + filters.Arg("is-automated", "true"), + filters.Arg("is-automated", "false"), + ), + expectedError: "invalid filter 'is-automated", }, { - filtersArgs: `{"is-automated":{"true":true,"false":true}}`, - expectedError: "Invalid filter 'is-automated", + filtersArgs: filters.NewArgs(filters.Arg("is-official", "invalid")), + expectedError: "invalid filter 'is-official=[invalid]'", }, { - filtersArgs: `{"is-official":{"invalid":true}}`, - expectedError: "Invalid filter 'is-official=[invalid]'", + filtersArgs: filters.NewArgs( + filters.Arg("is-official", "true"), + filters.Arg("is-official", "false"), + ), + expectedError: "invalid filter 'is-official", }, { - filtersArgs: `{"is-official":{"true":true,"false":true}}`, - expectedError: "Invalid filter 'is-official", + filtersArgs: filters.NewArgs(filters.Arg("stars", "invalid")), + expectedError: "invalid filter 'stars=invalid'", }, { - filtersArgs: `{"stars":{"invalid":true}}`, - expectedError: "Invalid filter 'stars=invalid'", - }, - { - filtersArgs: `{"stars":{"1":true,"invalid":true}}`, - expectedError: "Invalid filter 'stars=invalid'", + filtersArgs: filters.NewArgs( + filters.Arg("stars", "1"), + filters.Arg("stars", "invalid"), + ), + expectedError: "invalid filter 'stars=invalid'", }, } for index, e := range errorCases { @@ -79,30 +86,37 @@ func TestSearchRegistryForImagesErrors(t *testing.T) { shouldReturnError: e.shouldReturnError, }, } - _, err := daemon.SearchRegistryForImages(context.Background(), e.filtersArgs, "term", 25, nil, map[string][]string{}) + _, err := daemon.SearchRegistryForImages(context.Background(), e.filtersArgs, "term", 0, nil, map[string][]string{}) if err == nil { t.Errorf("%d: expected an error, got nothing", index) } if !strings.Contains(err.Error(), e.expectedError) { t.Errorf("%d: expected error to contain %s, got %s", index, e.expectedError, err.Error()) } + if e.shouldReturnError { + if !errdefs.IsUnknown(err) { + t.Errorf("%d: expected expected an errdefs.ErrUnknown, got: %T: %v", index, err, err) + } + continue + } + if !errdefs.IsInvalidParameter(err) { + t.Errorf("%d: expected expected an errdefs.ErrInvalidParameter, got: %T: %v", index, err, err) + } } } func TestSearchRegistryForImages(t *testing.T) { term := "term" successCases := []struct { - filtersArgs string + filtersArgs filters.Args registryResults []registrytypes.SearchResult expectedResults []registrytypes.SearchResult }{ { - filtersArgs: "", registryResults: []registrytypes.SearchResult{}, expectedResults: []registrytypes.SearchResult{}, }, { - filtersArgs: "", registryResults: []registrytypes.SearchResult{ { Name: "name", @@ -117,7 +131,7 @@ func TestSearchRegistryForImages(t *testing.T) { }, }, { - filtersArgs: `{"is-automated":{"true":true}}`, + filtersArgs: filters.NewArgs(filters.Arg("is-automated", "true")), registryResults: []registrytypes.SearchResult{ { Name: "name", @@ -127,7 +141,7 @@ func TestSearchRegistryForImages(t *testing.T) { expectedResults: []registrytypes.SearchResult{}, }, { - filtersArgs: `{"is-automated":{"true":true}}`, + filtersArgs: filters.NewArgs(filters.Arg("is-automated", "true")), registryResults: []registrytypes.SearchResult{ { Name: "name", @@ -144,7 +158,7 @@ func TestSearchRegistryForImages(t *testing.T) { }, }, { - filtersArgs: `{"is-automated":{"false":true}}`, + filtersArgs: filters.NewArgs(filters.Arg("is-automated", "false")), registryResults: []registrytypes.SearchResult{ { Name: "name", @@ -155,7 +169,7 @@ func TestSearchRegistryForImages(t *testing.T) { expectedResults: []registrytypes.SearchResult{}, }, { - filtersArgs: `{"is-automated":{"false":true}}`, + filtersArgs: filters.NewArgs(filters.Arg("is-automated", "false")), registryResults: []registrytypes.SearchResult{ { Name: "name", @@ -172,7 +186,7 @@ func TestSearchRegistryForImages(t *testing.T) { }, }, { - filtersArgs: `{"is-official":{"true":true}}`, + filtersArgs: filters.NewArgs(filters.Arg("is-official", "true")), registryResults: []registrytypes.SearchResult{ { Name: "name", @@ -182,7 +196,7 @@ func TestSearchRegistryForImages(t *testing.T) { expectedResults: []registrytypes.SearchResult{}, }, { - filtersArgs: `{"is-official":{"true":true}}`, + filtersArgs: filters.NewArgs(filters.Arg("is-official", "true")), registryResults: []registrytypes.SearchResult{ { Name: "name", @@ -199,7 +213,7 @@ func TestSearchRegistryForImages(t *testing.T) { }, }, { - filtersArgs: `{"is-official":{"false":true}}`, + filtersArgs: filters.NewArgs(filters.Arg("is-official", "false")), registryResults: []registrytypes.SearchResult{ { Name: "name", @@ -210,7 +224,7 @@ func TestSearchRegistryForImages(t *testing.T) { expectedResults: []registrytypes.SearchResult{}, }, { - filtersArgs: `{"is-official":{"false":true}}`, + filtersArgs: filters.NewArgs(filters.Arg("is-official", "false")), registryResults: []registrytypes.SearchResult{ { Name: "name", @@ -227,7 +241,7 @@ func TestSearchRegistryForImages(t *testing.T) { }, }, { - filtersArgs: `{"stars":{"0":true}}`, + filtersArgs: filters.NewArgs(filters.Arg("stars", "0")), registryResults: []registrytypes.SearchResult{ { Name: "name", @@ -244,7 +258,7 @@ func TestSearchRegistryForImages(t *testing.T) { }, }, { - filtersArgs: `{"stars":{"1":true}}`, + filtersArgs: filters.NewArgs(filters.Arg("stars", "1")), registryResults: []registrytypes.SearchResult{ { Name: "name", @@ -255,7 +269,7 @@ func TestSearchRegistryForImages(t *testing.T) { expectedResults: []registrytypes.SearchResult{}, }, { - filtersArgs: `{"stars":{"1":true}}`, + filtersArgs: filters.NewArgs(filters.Arg("stars", "1")), registryResults: []registrytypes.SearchResult{ { Name: "name0", @@ -277,7 +291,11 @@ func TestSearchRegistryForImages(t *testing.T) { }, }, { - filtersArgs: `{"stars":{"1":true}, "is-official":{"true":true}, "is-automated":{"true":true}}`, + filtersArgs: filters.NewArgs( + filters.Arg("stars", "1"), + filters.Arg("is-official", "true"), + filters.Arg("is-automated", "true"), + ), registryResults: []registrytypes.SearchResult{ { Name: "name0", @@ -326,7 +344,7 @@ func TestSearchRegistryForImages(t *testing.T) { results: s.registryResults, }, } - results, err := daemon.SearchRegistryForImages(context.Background(), s.filtersArgs, term, 25, nil, map[string][]string{}) + results, err := daemon.SearchRegistryForImages(context.Background(), s.filtersArgs, term, 0, nil, map[string][]string{}) if err != nil { t.Errorf("%d: %v", index, err) } diff --git a/daemon/images/locals.go b/daemon/images/locals.go index a57ea2da60..d62c345b72 100644 --- a/daemon/images/locals.go +++ b/daemon/images/locals.go @@ -12,7 +12,7 @@ type invalidFilter struct { } func (e invalidFilter) Error() string { - msg := "Invalid filter '" + e.filter + msg := "invalid filter '" + e.filter if e.value != nil { msg += fmt.Sprintf("=%s", e.value) } diff --git a/daemon/list_test.go b/daemon/list_test.go index 1db783ff52..955d137aa1 100644 --- a/daemon/list_test.go +++ b/daemon/list_test.go @@ -91,7 +91,7 @@ func TestListInvalidFilter(t *testing.T) { _, err = d.Containers(&types.ContainerListOptions{ Filters: f, }) - assert.Assert(t, is.Error(err, "Invalid filter 'invalid'")) + assert.Assert(t, is.Error(err, "invalid filter 'invalid'")) } func TestNameFilter(t *testing.T) { diff --git a/integration-cli/docker_cli_images_test.go b/integration-cli/docker_cli_images_test.go index 193cb20ab0..dbb9f893a9 100644 --- a/integration-cli/docker_cli_images_test.go +++ b/integration-cli/docker_cli_images_test.go @@ -68,7 +68,7 @@ func (s *DockerSuite) TestImagesOrderedByCreationDate(c *testing.T) { func (s *DockerSuite) TestImagesErrorWithInvalidFilterNameTest(c *testing.T) { out, _, err := dockerCmdWithError("images", "-f", "FOO=123") assert.ErrorContains(c, err, "") - assert.Assert(c, strings.Contains(out, "Invalid filter")) + assert.Assert(c, strings.Contains(out, "invalid filter")) } func (s *DockerSuite) TestImagesFilterLabelMatch(c *testing.T) { @@ -252,7 +252,7 @@ func (s *DockerSuite) TestImagesEnsureDanglingImageOnlyListedOnce(c *testing.T) func (s *DockerSuite) TestImagesWithIncorrectFilter(c *testing.T) { out, _, err := dockerCmdWithError("images", "-f", "dangling=invalid") assert.ErrorContains(c, err, "") - assert.Assert(c, strings.Contains(out, "Invalid filter")) + assert.Assert(c, strings.Contains(out, "invalid filter")) } func (s *DockerSuite) TestImagesEnsureOnlyHeadsImagesShown(c *testing.T) { diff --git a/integration-cli/docker_cli_ps_test.go b/integration-cli/docker_cli_ps_test.go index fe625263bc..ad0fbfb1c4 100644 --- a/integration-cli/docker_cli_ps_test.go +++ b/integration-cli/docker_cli_ps_test.go @@ -203,7 +203,7 @@ func (s *DockerSuite) TestPsListContainersFilterStatus(c *testing.T) { assert.Equal(c, RemoveOutputForExistingElements(containerOut, existingContainers), secondID) result := cli.Docker(cli.Args("ps", "-a", "-q", "--filter=status=rubbish"), cli.WithTimeout(time.Second*60)) - err := "Invalid filter 'status=rubbish'" + err := "invalid filter 'status=rubbish'" if versions.LessThan(testEnv.DaemonAPIVersion(), "1.32") { err = "Unrecognised filter value for status: rubbish" } diff --git a/integration-cli/docker_cli_search_test.go b/integration-cli/docker_cli_search_test.go index baace44fb3..a61c5e7cdc 100644 --- a/integration-cli/docker_cli_search_test.go +++ b/integration-cli/docker_cli_search_test.go @@ -17,19 +17,19 @@ func (s *DockerSuite) TestSearchOnCentralRegistry(c *testing.T) { func (s *DockerSuite) TestSearchStarsOptionWithWrongParameter(c *testing.T) { out, _, err := dockerCmdWithError("search", "--filter", "stars=a", "busybox") assert.ErrorContains(c, err, "", out) - assert.Assert(c, strings.Contains(out, "Invalid filter"), "couldn't find the invalid filter warning") + assert.Assert(c, strings.Contains(out, "invalid filter"), "couldn't find the invalid filter warning") out, _, err = dockerCmdWithError("search", "-f", "stars=a", "busybox") assert.ErrorContains(c, err, "", out) - assert.Assert(c, strings.Contains(out, "Invalid filter"), "couldn't find the invalid filter warning") + assert.Assert(c, strings.Contains(out, "invalid filter"), "couldn't find the invalid filter warning") out, _, err = dockerCmdWithError("search", "-f", "is-automated=a", "busybox") assert.ErrorContains(c, err, "", out) - assert.Assert(c, strings.Contains(out, "Invalid filter"), "couldn't find the invalid filter warning") + assert.Assert(c, strings.Contains(out, "invalid filter"), "couldn't find the invalid filter warning") out, _, err = dockerCmdWithError("search", "-f", "is-official=a", "busybox") assert.ErrorContains(c, err, "", out) - assert.Assert(c, strings.Contains(out, "Invalid filter"), "couldn't find the invalid filter warning") + assert.Assert(c, strings.Contains(out, "invalid filter"), "couldn't find the invalid filter warning") } func (s *DockerSuite) TestSearchCmdOptions(c *testing.T) { @@ -73,7 +73,7 @@ func (s *DockerSuite) TestSearchWithLimit(c *testing.T) { assert.Equal(c, len(outSlice), limit+2) // 1 header, 1 carriage return } - for _, limit := range []int{-1, 0, 101} { + for _, limit := range []int{-1, 101} { _, _, err := dockerCmdWithError("search", fmt.Sprintf("--limit=%d", limit), "docker") assert.ErrorContains(c, err, "") } diff --git a/integration-cli/docker_cli_volume_test.go b/integration-cli/docker_cli_volume_test.go index b7424c82af..2dae8ff43b 100644 --- a/integration-cli/docker_cli_volume_test.go +++ b/integration-cli/docker_cli_volume_test.go @@ -166,13 +166,13 @@ func (s *DockerSuite) TestVolumeCLILsFilterDangling(c *testing.T) { func (s *DockerSuite) TestVolumeCLILsErrorWithInvalidFilterName(c *testing.T) { out, _, err := dockerCmdWithError("volume", "ls", "-f", "FOO=123") assert.ErrorContains(c, err, "") - assert.Assert(c, strings.Contains(out, "Invalid filter")) + assert.Assert(c, strings.Contains(out, "invalid filter")) } func (s *DockerSuite) TestVolumeCLILsWithIncorrectFilterValue(c *testing.T) { out, _, err := dockerCmdWithError("volume", "ls", "-f", "dangling=invalid") assert.ErrorContains(c, err, "") - assert.Assert(c, strings.Contains(out, "Invalid filter")) + assert.Assert(c, strings.Contains(out, "invalid filter")) } func (s *DockerSuite) TestVolumeCLIRm(c *testing.T) { diff --git a/plugin/errors.go b/plugin/errors.go index 44d99b39b2..4aca5ff71d 100644 --- a/plugin/errors.go +++ b/plugin/errors.go @@ -32,7 +32,7 @@ type invalidFilter struct { } func (e invalidFilter) Error() string { - msg := "Invalid filter '" + e.filter + msg := "invalid filter '" + e.filter if len(e.value) > 0 { msg += fmt.Sprintf("=%s", e.value) } diff --git a/registry/service.go b/registry/service.go index 0cda3a8806..4b38349de6 100644 --- a/registry/service.go +++ b/registry/service.go @@ -16,11 +16,6 @@ import ( "github.com/sirupsen/logrus" ) -const ( - // DefaultSearchLimit is the default value for maximum number of returned search results. - DefaultSearchLimit = 25 -) - // Service is the interface defining what a registry service should implement. type Service interface { Auth(ctx context.Context, authConfig *types.AuthConfig, userAgent string) (status, token string, err error) diff --git a/registry/session.go b/registry/session.go index bf222e43e8..525739990c 100644 --- a/registry/session.go +++ b/registry/session.go @@ -184,8 +184,14 @@ func newSession(client *http.Client, endpoint *v1Endpoint) *session { } } +// defaultSearchLimit is the default value for maximum number of returned search results. +const defaultSearchLimit = 25 + // searchRepositories performs a search against the remote repository func (r *session) searchRepositories(term string, limit int) (*registry.SearchResults, error) { + if limit == 0 { + limit = defaultSearchLimit + } if limit < 1 || limit > 100 { return nil, invalidParamf("limit %d is outside the range of [1, 100]", limit) } diff --git a/volume/service/errors.go b/volume/service/errors.go index ce2d678dab..c735fca6cd 100644 --- a/volume/service/errors.go +++ b/volume/service/errors.go @@ -101,7 +101,7 @@ type invalidFilter struct { } func (e invalidFilter) Error() string { - msg := "Invalid filter '" + e.filter + msg := "invalid filter '" + e.filter if e.value != nil { msg += fmt.Sprintf("=%s", e.value) }