| package images // import "github.com/docker/docker/daemon/images" |
| |
| import ( |
| "context" |
| "strconv" |
| |
| "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/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. |
| // |
| // 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, |
| 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 |
| } |
| |
| var isAutomated, isOfficial bool |
| var hasStarFilter = 0 |
| if searchFilters.Contains("is-automated") { |
| if searchFilters.UniqueExactMatch("is-automated", "true") { |
| isAutomated = true |
| } else if !searchFilters.UniqueExactMatch("is-automated", "false") { |
| return nil, invalidFilter{"is-automated", searchFilters.Get("is-automated")} |
| } |
| } |
| if searchFilters.Contains("is-official") { |
| if searchFilters.UniqueExactMatch("is-official", "true") { |
| isOfficial = true |
| } else if !searchFilters.UniqueExactMatch("is-official", "false") { |
| return nil, invalidFilter{"is-official", searchFilters.Get("is-official")} |
| } |
| } |
| if searchFilters.Contains("stars") { |
| hasStars := searchFilters.Get("stars") |
| for _, hasStar := range hasStars { |
| iHasStar, err := strconv.Atoi(hasStar) |
| if err != nil { |
| return nil, invalidFilter{"stars", hasStar} |
| } |
| if iHasStar > hasStarFilter { |
| hasStarFilter = iHasStar |
| } |
| } |
| } |
| |
| unfilteredResult, err := i.registryService.Search(ctx, term, limit, authConfig, dockerversion.DockerUserAgent(ctx), headers) |
| if err != nil { |
| return nil, err |
| } |
| |
| filteredResults := []registrytypes.SearchResult{} |
| for _, result := range unfilteredResult.Results { |
| if searchFilters.Contains("is-automated") { |
| if isAutomated != result.IsAutomated { |
| continue |
| } |
| } |
| if searchFilters.Contains("is-official") { |
| if isOfficial != result.IsOfficial { |
| continue |
| } |
| } |
| if searchFilters.Contains("stars") { |
| if result.StarCount < hasStarFilter { |
| continue |
| } |
| } |
| filteredResults = append(filteredResults, result) |
| } |
| |
| return ®istrytypes.SearchResults{ |
| Query: unfilteredResult.Query, |
| NumResults: len(filteredResults), |
| Results: filteredResults, |
| }, nil |
| } |