Add `--limit` option to `docker search`
This fix tries to address the issue raised in #23055. Currently `docker search` result caps at 25 and there is no way to allow getting more results (if exist). This fix adds the flag `--limit` so that it is possible to return more results from the `docker search`. Related documentation has been updated. Additional tests have been added to cover the changes. This fix fixes #23055. Signed-off-by: Yong Tang <yong.tang.github@outlook.com>master
							parent
							
								
									d265da7356
								
							
						
					
					
						commit
						08426ad10d
					
				| 
						 | 
					@ -730,7 +730,7 @@ func TestPushImageJSONIndex(t *testing.T) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestSearchRepositories(t *testing.T) {
 | 
					func TestSearchRepositories(t *testing.T) {
 | 
				
			||||||
	r := spawnTestRegistrySession(t)
 | 
						r := spawnTestRegistrySession(t)
 | 
				
			||||||
	results, err := r.SearchRepositories("fakequery")
 | 
						results, err := r.SearchRepositories("fakequery", 25)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,11 @@ import (
 | 
				
			||||||
	registrytypes "github.com/docker/engine-api/types/registry"
 | 
						registrytypes "github.com/docker/engine-api/types/registry"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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.
 | 
					// Service is the interface defining what a registry service should implement.
 | 
				
			||||||
type Service interface {
 | 
					type Service interface {
 | 
				
			||||||
	Auth(ctx context.Context, authConfig *types.AuthConfig, userAgent string) (status, token string, err error)
 | 
						Auth(ctx context.Context, authConfig *types.AuthConfig, userAgent string) (status, token string, err error)
 | 
				
			||||||
| 
						 | 
					@ -22,7 +27,7 @@ type Service interface {
 | 
				
			||||||
	LookupPushEndpoints(hostname string) (endpoints []APIEndpoint, err error)
 | 
						LookupPushEndpoints(hostname string) (endpoints []APIEndpoint, err error)
 | 
				
			||||||
	ResolveRepository(name reference.Named) (*RepositoryInfo, error)
 | 
						ResolveRepository(name reference.Named) (*RepositoryInfo, error)
 | 
				
			||||||
	ResolveIndex(name string) (*registrytypes.IndexInfo, error)
 | 
						ResolveIndex(name string) (*registrytypes.IndexInfo, error)
 | 
				
			||||||
	Search(ctx context.Context, term string, authConfig *types.AuthConfig, userAgent string, headers map[string][]string) (*registrytypes.SearchResults, error)
 | 
						Search(ctx context.Context, term string, limit int, authConfig *types.AuthConfig, userAgent string, headers map[string][]string) (*registrytypes.SearchResults, error)
 | 
				
			||||||
	ServiceConfig() *registrytypes.ServiceConfig
 | 
						ServiceConfig() *registrytypes.ServiceConfig
 | 
				
			||||||
	TLSConfig(hostname string) (*tls.Config, error)
 | 
						TLSConfig(hostname string) (*tls.Config, error)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -108,7 +113,7 @@ func splitReposSearchTerm(reposName string) (string, string) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Search queries the public registry for images matching the specified
 | 
					// Search queries the public registry for images matching the specified
 | 
				
			||||||
// search terms, and returns the results.
 | 
					// search terms, and returns the results.
 | 
				
			||||||
func (s *DefaultService) Search(ctx context.Context, term string, authConfig *types.AuthConfig, userAgent string, headers map[string][]string) (*registrytypes.SearchResults, error) {
 | 
					func (s *DefaultService) Search(ctx context.Context, term string, limit int, authConfig *types.AuthConfig, userAgent string, headers map[string][]string) (*registrytypes.SearchResults, error) {
 | 
				
			||||||
	// TODO Use ctx when searching for repositories
 | 
						// TODO Use ctx when searching for repositories
 | 
				
			||||||
	if err := validateNoScheme(term); err != nil {
 | 
						if err := validateNoScheme(term); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
| 
						 | 
					@ -139,9 +144,9 @@ func (s *DefaultService) Search(ctx context.Context, term string, authConfig *ty
 | 
				
			||||||
			localName = strings.SplitN(localName, "/", 2)[1]
 | 
								localName = strings.SplitN(localName, "/", 2)[1]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return r.SearchRepositories(localName)
 | 
							return r.SearchRepositories(localName, limit)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return r.SearchRepositories(remoteName)
 | 
						return r.SearchRepositories(remoteName, limit)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ResolveRepository splits a repository name into its components
 | 
					// ResolveRepository splits a repository name into its components
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -721,9 +721,12 @@ func shouldRedirect(response *http.Response) bool {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SearchRepositories performs a search against the remote repository
 | 
					// SearchRepositories performs a search against the remote repository
 | 
				
			||||||
func (r *Session) SearchRepositories(term string) (*registrytypes.SearchResults, error) {
 | 
					func (r *Session) SearchRepositories(term string, limit int) (*registrytypes.SearchResults, error) {
 | 
				
			||||||
 | 
						if limit < 1 || limit > 100 {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("Limit %d is outside the range of [1, 100]", limit)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	logrus.Debugf("Index server: %s", r.indexEndpoint)
 | 
						logrus.Debugf("Index server: %s", r.indexEndpoint)
 | 
				
			||||||
	u := r.indexEndpoint.String() + "search?q=" + url.QueryEscape(term)
 | 
						u := r.indexEndpoint.String() + "search?q=" + url.QueryEscape(term) + "&n=" + url.QueryEscape(fmt.Sprintf("%d", limit))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	req, err := http.NewRequest("GET", u, nil)
 | 
						req, err := http.NewRequest("GET", u, nil)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue