2018-02-07 20:52:47 +00:00
|
|
|
package images // import "github.com/docker/docker/daemon/images"
|
2016-05-21 14:00:28 +00:00
|
|
|
|
|
|
|
import (
|
2018-04-19 22:30:59 +00:00
|
|
|
"context"
|
2016-05-21 14:00:28 +00:00
|
|
|
"strconv"
|
|
|
|
|
2016-09-06 18:18:12 +00:00
|
|
|
"github.com/docker/docker/api/types"
|
|
|
|
"github.com/docker/docker/api/types/filters"
|
|
|
|
registrytypes "github.com/docker/docker/api/types/registry"
|
2016-05-21 14:00:28 +00:00
|
|
|
"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.
|
2018-02-02 22:18:46 +00:00
|
|
|
//
|
|
|
|
// TODO: this could be implemented in a registry service instead of the image
|
|
|
|
// service.
|
2022-03-02 15:03:38 +00:00
|
|
|
func (i *ImageService) SearchRegistryForImages(ctx context.Context, searchFilters filters.Args, term string, limit int,
|
2016-05-21 14:00:28 +00:00
|
|
|
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
|
2017-09-26 11:39:56 +00:00
|
|
|
if searchFilters.Contains("is-automated") {
|
2016-05-21 14:00:28 +00:00
|
|
|
if searchFilters.UniqueExactMatch("is-automated", "true") {
|
|
|
|
isAutomated = true
|
|
|
|
} else if !searchFilters.UniqueExactMatch("is-automated", "false") {
|
2017-07-19 14:20:13 +00:00
|
|
|
return nil, invalidFilter{"is-automated", searchFilters.Get("is-automated")}
|
2016-05-21 14:00:28 +00:00
|
|
|
}
|
|
|
|
}
|
2017-09-26 11:39:56 +00:00
|
|
|
if searchFilters.Contains("is-official") {
|
2016-05-21 14:00:28 +00:00
|
|
|
if searchFilters.UniqueExactMatch("is-official", "true") {
|
|
|
|
isOfficial = true
|
|
|
|
} else if !searchFilters.UniqueExactMatch("is-official", "false") {
|
2017-07-19 14:20:13 +00:00
|
|
|
return nil, invalidFilter{"is-official", searchFilters.Get("is-official")}
|
2016-05-21 14:00:28 +00:00
|
|
|
}
|
|
|
|
}
|
2017-09-26 11:39:56 +00:00
|
|
|
if searchFilters.Contains("stars") {
|
2016-05-21 14:00:28 +00:00
|
|
|
hasStars := searchFilters.Get("stars")
|
|
|
|
for _, hasStar := range hasStars {
|
|
|
|
iHasStar, err := strconv.Atoi(hasStar)
|
|
|
|
if err != nil {
|
2017-07-19 14:20:13 +00:00
|
|
|
return nil, invalidFilter{"stars", hasStar}
|
2016-05-21 14:00:28 +00:00
|
|
|
}
|
|
|
|
if iHasStar > hasStarFilter {
|
|
|
|
hasStarFilter = iHasStar
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-02 22:18:46 +00:00
|
|
|
unfilteredResult, err := i.registryService.Search(ctx, term, limit, authConfig, dockerversion.DockerUserAgent(ctx), headers)
|
2016-05-27 09:13:12 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2016-05-21 14:00:28 +00:00
|
|
|
filteredResults := []registrytypes.SearchResult{}
|
|
|
|
for _, result := range unfilteredResult.Results {
|
2017-09-26 11:39:56 +00:00
|
|
|
if searchFilters.Contains("is-automated") {
|
2016-05-21 14:00:28 +00:00
|
|
|
if isAutomated != result.IsAutomated {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
2017-09-26 11:39:56 +00:00
|
|
|
if searchFilters.Contains("is-official") {
|
2016-05-21 14:00:28 +00:00
|
|
|
if isOfficial != result.IsOfficial {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
2017-09-26 11:39:56 +00:00
|
|
|
if searchFilters.Contains("stars") {
|
2016-05-21 14:00:28 +00:00
|
|
|
if result.StarCount < hasStarFilter {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
filteredResults = append(filteredResults, result)
|
|
|
|
}
|
|
|
|
|
|
|
|
return ®istrytypes.SearchResults{
|
|
|
|
Query: unfilteredResult.Query,
|
|
|
|
NumResults: len(filteredResults),
|
|
|
|
Results: filteredResults,
|
|
|
|
}, nil
|
|
|
|
}
|