github.com/gravitational/moby@v1.13.1/daemon/search.go (about)

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