64e50ce86a
All other endpoints handle this in the API; given that the JSON format for filters is part of the API, it makes sense to handle it there, and not have that concept leak into further down the code. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
91 lines
2.6 KiB
Go
91 lines
2.6 KiB
Go
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, searchFilters filters.Args, term string, limit int,
|
|
authConfig *types.AuthConfig,
|
|
headers map[string][]string) (*registrytypes.SearchResults, error) {
|
|
|
|
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
|
|
}
|