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