From f04e8fdb9bbcdad28de5c328b7de3f3abdae0b5a Mon Sep 17 00:00:00 2001 From: Hu Keping Date: Tue, 22 Sep 2015 19:44:40 +0800 Subject: [PATCH] Fix docker search problem Search terms shouldn't be restricted to only full valid repository names. It should be perfectly valid to search using a part of a name, even if it ends with a period, dash or underscore. Signed-off-by: Hu Keping --- api/client/search.go | 5 +++-- integration-cli/docker_cli_search_test.go | 8 ++++++++ registry/config.go | 22 ++++++++++++++++++---- registry/service.go | 11 +++++++++-- 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/api/client/search.go b/api/client/search.go index 2305d08343..81f80b26e7 100644 --- a/api/client/search.go +++ b/api/client/search.go @@ -41,12 +41,13 @@ func (cli *DockerCli) CmdSearch(args ...string) error { // Resolve the Repository name from fqn to hostname + name taglessRemote, _ := parsers.ParseRepositoryTag(name) - repoInfo, err := registry.ParseRepositoryInfo(taglessRemote) + + indexInfo, err := registry.ParseIndexInfo(taglessRemote) if err != nil { return err } - rdr, _, err := cli.clientRequestAttemptLogin("GET", "/images/search?"+v.Encode(), nil, nil, repoInfo.Index, "search") + rdr, _, err := cli.clientRequestAttemptLogin("GET", "/images/search?"+v.Encode(), nil, nil, indexInfo, "search") if err != nil { return err } diff --git a/integration-cli/docker_cli_search_test.go b/integration-cli/docker_cli_search_test.go index 3707b883c9..44f9b2c76a 100644 --- a/integration-cli/docker_cli_search_test.go +++ b/integration-cli/docker_cli_search_test.go @@ -89,3 +89,11 @@ func (s *DockerSuite) TestSearchCmdOptions(c *check.C) { c.Fatalf("failed to search with stars&automated&no-trunc options on the central registry: %s", out) } } + +// search for repos which start with "ubuntu-" on the central registry +func (s *DockerSuite) TestSearchOnCentralRegistryWithDash(c *check.C) { + testRequires(c, Network, DaemonIsLinux) + + out, exitCode := dockerCmd(c, "search", "ubuntu-") + c.Assert(exitCode, check.Equals, 0, check.Commentf("failed to search on the central registry: %s", out)) +} diff --git a/registry/config.go b/registry/config.go index 5fca9df07c..c73b6c5dde 100644 --- a/registry/config.go +++ b/registry/config.go @@ -295,14 +295,17 @@ func splitReposName(reposName string) (string, string) { } // NewRepositoryInfo validates and breaks down a repository name into a RepositoryInfo -func (config *ServiceConfig) NewRepositoryInfo(reposName string) (*RepositoryInfo, error) { +func (config *ServiceConfig) NewRepositoryInfo(reposName string, bySearch bool) (*RepositoryInfo, error) { if err := validateNoSchema(reposName); err != nil { return nil, err } indexName, remoteName := splitReposName(reposName) - if err := validateRemoteName(remoteName); err != nil { - return nil, err + + if !bySearch { + if err := validateRemoteName(remoteName); err != nil { + return nil, err + } } repoInfo := &RepositoryInfo{ @@ -354,7 +357,18 @@ func (repoInfo *RepositoryInfo) GetSearchTerm() string { // ParseRepositoryInfo performs the breakdown of a repository name into a RepositoryInfo, but // lacks registry configuration. func ParseRepositoryInfo(reposName string) (*RepositoryInfo, error) { - return emptyServiceConfig.NewRepositoryInfo(reposName) + return emptyServiceConfig.NewRepositoryInfo(reposName, false) +} + +// ParseIndexInfo will use repository name to get back an indexInfo. +func ParseIndexInfo(reposName string) (*IndexInfo, error) { + indexName, _ := splitReposName(reposName) + + indexInfo, err := emptyServiceConfig.NewIndexInfo(indexName) + if err != nil { + return nil, err + } + return indexInfo, nil } // NormalizeLocalName transforms a repository name into a normalize LocalName diff --git a/registry/service.go b/registry/service.go index 36d63091f7..bb38b2c070 100644 --- a/registry/service.go +++ b/registry/service.go @@ -51,7 +51,8 @@ func (s *Service) Auth(authConfig *cliconfig.AuthConfig) (string, error) { // Search queries the public registry for images matching the specified // search terms, and returns the results. func (s *Service) Search(term string, authConfig *cliconfig.AuthConfig, headers map[string][]string) (*SearchResults, error) { - repoInfo, err := s.ResolveRepository(term) + + repoInfo, err := s.ResolveRepositoryBySearch(term) if err != nil { return nil, err } @@ -71,7 +72,13 @@ func (s *Service) Search(term string, authConfig *cliconfig.AuthConfig, headers // ResolveRepository splits a repository name into its components // and configuration of the associated registry. func (s *Service) ResolveRepository(name string) (*RepositoryInfo, error) { - return s.Config.NewRepositoryInfo(name) + return s.Config.NewRepositoryInfo(name, false) +} + +// ResolveRepositoryBySearch splits a repository name into its components +// and configuration of the associated registry. +func (s *Service) ResolveRepositoryBySearch(name string) (*RepositoryInfo, error) { + return s.Config.NewRepositoryInfo(name, true) } // ResolveIndex takes indexName and returns index info