daemon/search.go
636c276f
 package daemon
 
 import (
 	"strconv"
 
 	"golang.org/x/net/context"
 
91e197d6
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/filters"
 	registrytypes "github.com/docker/docker/api/types/registry"
636c276f
 	"github.com/docker/docker/dockerversion"
 )
 
 var acceptedSearchFilterTags = map[string]bool{
 	"is-automated": true,
 	"is-official":  true,
 	"stars":        true,
 }
 
 // SearchRegistryForImages queries the registry for images matching
 // term. authConfig is used to login.
92f10fe2
 func (daemon *Daemon) SearchRegistryForImages(ctx context.Context, filtersArgs string, term string, limit int,
636c276f
 	authConfig *types.AuthConfig,
 	headers map[string][]string) (*registrytypes.SearchResults, error) {
 
a4efe66c
 	searchFilters, err := filters.FromJSON(filtersArgs)
636c276f
 	if err != nil {
 		return nil, err
 	}
 	if err := searchFilters.Validate(acceptedSearchFilterTags); err != nil {
 		return nil, err
 	}
 
 	var isAutomated, isOfficial bool
 	var hasStarFilter = 0
97c5ae25
 	if searchFilters.Contains("is-automated") {
636c276f
 		if searchFilters.UniqueExactMatch("is-automated", "true") {
 			isAutomated = true
 		} else if !searchFilters.UniqueExactMatch("is-automated", "false") {
ebcb7d6b
 			return nil, invalidFilter{"is-automated", searchFilters.Get("is-automated")}
636c276f
 		}
 	}
97c5ae25
 	if searchFilters.Contains("is-official") {
636c276f
 		if searchFilters.UniqueExactMatch("is-official", "true") {
 			isOfficial = true
 		} else if !searchFilters.UniqueExactMatch("is-official", "false") {
ebcb7d6b
 			return nil, invalidFilter{"is-official", searchFilters.Get("is-official")}
636c276f
 		}
 	}
97c5ae25
 	if searchFilters.Contains("stars") {
636c276f
 		hasStars := searchFilters.Get("stars")
 		for _, hasStar := range hasStars {
 			iHasStar, err := strconv.Atoi(hasStar)
 			if err != nil {
ebcb7d6b
 				return nil, invalidFilter{"stars", hasStar}
636c276f
 			}
 			if iHasStar > hasStarFilter {
 				hasStarFilter = iHasStar
 			}
 		}
 	}
 
92f10fe2
 	unfilteredResult, err := daemon.RegistryService.Search(ctx, term, limit, authConfig, dockerversion.DockerUserAgent(ctx), headers)
cd012efa
 	if err != nil {
 		return nil, err
 	}
 
636c276f
 	filteredResults := []registrytypes.SearchResult{}
 	for _, result := range unfilteredResult.Results {
97c5ae25
 		if searchFilters.Contains("is-automated") {
636c276f
 			if isAutomated != result.IsAutomated {
 				continue
 			}
 		}
97c5ae25
 		if searchFilters.Contains("is-official") {
636c276f
 			if isOfficial != result.IsOfficial {
 				continue
 			}
 		}
97c5ae25
 		if searchFilters.Contains("stars") {
636c276f
 			if result.StarCount < hasStarFilter {
 				continue
 			}
 		}
 		filteredResults = append(filteredResults, result)
 	}
 
 	return &registrytypes.SearchResults{
 		Query:      unfilteredResult.Query,
 		NumResults: len(filteredResults),
 		Results:    filteredResults,
 	}, nil
 }