github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/daemon/images/image_search.go (about)

     1  package images // import "github.com/docker/docker/daemon/images"
     2  
     3  import (
     4  	"context"
     5  	"strconv"
     6  
     7  	"github.com/docker/docker/api/types/filters"
     8  	"github.com/docker/docker/api/types/registry"
     9  	"github.com/docker/docker/dockerversion"
    10  )
    11  
    12  var acceptedSearchFilterTags = map[string]bool{
    13  	"is-automated": true,
    14  	"is-official":  true,
    15  	"stars":        true,
    16  }
    17  
    18  // SearchRegistryForImages queries the registry for images matching
    19  // term. authConfig is used to login.
    20  //
    21  // TODO: this could be implemented in a registry service instead of the image
    22  // service.
    23  func (i *ImageService) SearchRegistryForImages(ctx context.Context, searchFilters filters.Args, term string, limit int,
    24  	authConfig *registry.AuthConfig,
    25  	headers map[string][]string) (*registry.SearchResults, error) {
    26  	if err := searchFilters.Validate(acceptedSearchFilterTags); err != nil {
    27  		return nil, err
    28  	}
    29  
    30  	var isAutomated, isOfficial bool
    31  	var hasStarFilter = 0
    32  	if searchFilters.Contains("is-automated") {
    33  		if searchFilters.UniqueExactMatch("is-automated", "true") {
    34  			isAutomated = true
    35  		} else if !searchFilters.UniqueExactMatch("is-automated", "false") {
    36  			return nil, invalidFilter{"is-automated", searchFilters.Get("is-automated")}
    37  		}
    38  	}
    39  	if searchFilters.Contains("is-official") {
    40  		if searchFilters.UniqueExactMatch("is-official", "true") {
    41  			isOfficial = true
    42  		} else if !searchFilters.UniqueExactMatch("is-official", "false") {
    43  			return nil, invalidFilter{"is-official", searchFilters.Get("is-official")}
    44  		}
    45  	}
    46  	if searchFilters.Contains("stars") {
    47  		hasStars := searchFilters.Get("stars")
    48  		for _, hasStar := range hasStars {
    49  			iHasStar, err := strconv.Atoi(hasStar)
    50  			if err != nil {
    51  				return nil, invalidFilter{"stars", hasStar}
    52  			}
    53  			if iHasStar > hasStarFilter {
    54  				hasStarFilter = iHasStar
    55  			}
    56  		}
    57  	}
    58  
    59  	unfilteredResult, err := i.registryService.Search(ctx, term, limit, authConfig, dockerversion.DockerUserAgent(ctx), headers)
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  
    64  	filteredResults := []registry.SearchResult{}
    65  	for _, result := range unfilteredResult.Results {
    66  		if searchFilters.Contains("is-automated") {
    67  			if isAutomated != result.IsAutomated {
    68  				continue
    69  			}
    70  		}
    71  		if searchFilters.Contains("is-official") {
    72  			if isOfficial != result.IsOfficial {
    73  				continue
    74  			}
    75  		}
    76  		if searchFilters.Contains("stars") {
    77  			if result.StarCount < hasStarFilter {
    78  				continue
    79  			}
    80  		}
    81  		filteredResults = append(filteredResults, result)
    82  	}
    83  
    84  	return &registry.SearchResults{
    85  		Query:      unfilteredResult.Query,
    86  		NumResults: len(filteredResults),
    87  		Results:    filteredResults,
    88  	}, nil
    89  }