func SearchRegistry(ctx context.Context, sys *types.SystemContext, registry, image string, limit int) ([]SearchResult, error) {
	type V2Results struct {
		// Repositories holds the results returned by the /v2/_catalog endpoint
		Repositories []string `json:"repositories"`
	}
	type V1Results struct {
		// Results holds the results returned by the /v1/search endpoint
		Results []SearchResult `json:"results"`
	}
	v2Res := &V2Results{}
	v1Res := &V1Results{}

	// Get credentials from authfile for the underlying hostname
	username, password, err := config.GetAuthentication(sys, registry)
	if err != nil {
		return nil, errors.Wrapf(err, "error getting username and password")
	}

	// The /v2/_catalog endpoint has been disabled for docker.io therefore
	// the call made to that endpoint will fail.  So using the v1 hostname
	// for docker.io for simplicity of implementation and the fact that it
	// returns search results.
	hostname := registry
	if registry == dockerHostname {
		hostname = dockerV1Hostname
	}

	client, err := newDockerClient(sys, hostname, registry)
	if err != nil {
		return nil, errors.Wrapf(err, "error creating new docker client")
	}
	client.username = username
	client.password = password

	// Only try the v1 search endpoint if the search query is not empty. If it is
	// empty skip to the v2 endpoint.
	if image != "" {
		// set up the query values for the v1 endpoint
		u := url.URL{
			Path: "/v1/search",
		}
		q := u.Query()
		q.Set("q", image)
		q.Set("n", strconv.Itoa(limit))
		u.RawQuery = q.Encode()

		logrus.Debugf("trying to talk to v1 search endpoint")
		resp, err := client.makeRequest(ctx, "GET", u.String(), nil, nil, noAuth, nil)
		if err != nil {
			logrus.Debugf("error getting search results from v1 endpoint %q: %v", registry, err)
		} else {
			defer resp.Body.Close()
			if resp.StatusCode != http.StatusOK {
				logrus.Debugf("error getting search results from v1 endpoint %q, status code %d (%s)", registry, resp.StatusCode, http.StatusText(resp.StatusCode))
			} else {
				if err := json.NewDecoder(resp.Body).Decode(v1Res); err != nil {
					return nil, err
				}
				return v1Res.Results, nil
			}
		}
	}

	logrus.Debugf("trying to talk to v2 search endpoint")
	resp, err := client.makeRequest(ctx, "GET", "/v2/_catalog", nil, nil, v2Auth, nil)
	if err != nil {
		logrus.Debugf("error getting search results from v2 endpoint %q: %v", registry, err)
	} else {
		defer resp.Body.Close()
		if resp.StatusCode != http.StatusOK {
			logrus.Errorf("error getting search results from v2 endpoint %q, status code %d (%s)", registry, resp.StatusCode, http.StatusText(resp.StatusCode))
		} else {
			if err := json.NewDecoder(resp.Body).Decode(v2Res); err != nil {
				return nil, err
			}
			searchRes := []SearchResult{}
			for _, repo := range v2Res.Repositories {
				if strings.Contains(repo, image) {
					res := SearchResult{
						Name: repo,
					}
					searchRes = append(searchRes, res)
				}
			}
			return searchRes, nil
		}
	}

	return nil, errors.Wrapf(err, "couldn't search registry %q", registry)
}
func SearchRegistry(ctx context.Context, sys *types.SystemContext, registry, image string, limit int) ([]SearchResult, error) {
	type V2Results struct {
		
		Repositories []string `json:"repositories"`
	}
	type V1Results struct {
		
		Results []SearchResult `json:"results"`
	}
	v2Res := &V2Results{}
	v1Res := &V1Results{}

	
	username, password, err := config.GetAuthentication(sys, registry)
	if err != nil {
		return nil, errors.Wrapf(err, "error getting username and password")
	}

	
	
	
	
	hostname := registry
	if registry == dockerHostname {
		hostname = dockerV1Hostname
	}

	client, err := newDockerClient(sys, hostname, registry)
	if err != nil {
		return nil, errors.Wrapf(err, "error creating new docker client")
	}
	client.username = username
	client.password = password

	
	
	if image != "" {
		
		u := url.URL{
			Path: "/v1/search",
		}
		q := u.Query()
		q.Set("q", image)
		q.Set("n", strconv.Itoa(limit))
		u.RawQuery = q.Encode()

		logrus.Debugf("trying to talk to v1 search endpoint")
		resp, err := client.makeRequest(ctx, "GET", u.String(), nil, nil, noAuth, nil)
		if err != nil {
			logrus.Debugf("error getting search results from v1 endpoint %q: %v", registry, err)
		} else {
			defer resp.Body.Close()
			if resp.StatusCode != http.StatusOK {
				logrus.Debugf("error getting search results from v1 endpoint %q, status code %d (%s)", registry, resp.StatusCode, http.StatusText(resp.StatusCode))
			} else {
				if err := json.NewDecoder(resp.Body).Decode(v1Res); err != nil {
					return nil, err
				}
				return v1Res.Results, nil
			}
		}
	}

	logrus.Debugf("trying to talk to v2 search endpoint")
	resp, err := client.makeRequest(ctx, "GET", "/v2/_catalog", nil, nil, v2Auth, nil)
	if err != nil {
		logrus.Debugf("error getting search results from v2 endpoint %q: %v", registry, err)
	} else {
		defer resp.Body.Close()
		if resp.StatusCode != http.StatusOK {
			logrus.Errorf("error getting search results from v2 endpoint %q, status code %d (%s)", registry, resp.StatusCode, http.StatusText(resp.StatusCode))
		} else {
			if err := json.NewDecoder(resp.Body).Decode(v2Res); err != nil {
				return nil, err
			}
			searchRes := []SearchResult{}
			for _, repo := range v2Res.Repositories {
				if strings.Contains(repo, image) {
					res := SearchResult{
						Name: repo,
					}
					searchRes = append(searchRes, res)
				}
			}
			return searchRes, nil
		}
	}

	return nil, errors.Wrapf(err, "couldn't search registry %q", registry)
}
func SearchRegistry ( ctx context . Context , sys * types . SystemContext , registry , image string , limit int ) ( [ ] SearchResult , error ) { type V2Results struct { // Repositories holds the results returned by the /v2/_catalog endpoint Repositories [ ] string `json:"repositories"` } type V1Results struct { // Results holds the results returned by the /v1/search endpoint Results [ ] SearchResult `json:"results"` } v2Res := & V2Results { } v1Res := & V1Results { } // Get credentials from authfile for the underlying hostname username , password , err := config . GetAuthentication ( sys , registry ) if err != nil { return nil , errors . Wrapf ( err , " " ) } // The /v2/_catalog endpoint has been disabled for docker.io therefore // the call made to that endpoint will fail.  So using the v1 hostname // for docker.io for simplicity of implementation and the fact that it // returns search results. hostname := registry if registry == dockerHostname { hostname = dockerV1Hostname } client , err := newDockerClient ( sys , hostname , registry ) if err != nil { return nil , errors . Wrapf ( err , " " ) } client . username = username client . password = password // Only try the v1 search endpoint if the search query is not empty. If it is // empty skip to the v2 endpoint. if image != " " { // set up the query values for the v1 endpoint u := url . URL { Path : " " , } q := u . Query ( ) q . Set ( " " , image ) q . Set ( " " , strconv . Itoa ( limit ) ) u . RawQuery = q . Encode ( ) logrus . Debugf ( " " ) resp , err := client . makeRequest ( ctx , " " , u . String ( ) , nil , nil , noAuth , nil ) if err != nil { logrus . Debugf ( " " , registry , err ) } else { defer resp . Body . Close ( ) if resp . StatusCode != http . StatusOK { logrus . Debugf ( " " , registry , resp . StatusCode , http . StatusText ( resp . StatusCode ) ) } else { if err := json . NewDecoder ( resp . Body ) . Decode ( v1Res ) ; err != nil { return nil , err } return v1Res . Results , nil } } } logrus . Debugf ( " " ) resp , err := client . makeRequest ( ctx , " " , " " , nil , nil , v2Auth , nil ) if err != nil { logrus . Debugf ( " " , registry , err ) } else { defer resp . Body . Close ( ) if resp . StatusCode != http . StatusOK { logrus . Errorf ( " " , registry , resp . StatusCode , http . StatusText ( resp . StatusCode ) ) } else { if err := json . NewDecoder ( resp . Body ) . Decode ( v2Res ) ; err != nil { return nil , err } searchRes := [ ] SearchResult { } for _ , repo := range v2Res . Repositories { if strings . Contains ( repo , image ) { res := SearchResult { Name : repo , } searchRes = append ( searchRes , res ) } } return searchRes , nil } } return nil , errors . Wrapf ( err , " " , registry ) }
// SearchRegistry queries a registry for images that contain "image" in their name
// The limit is the max number of results desired
// Note: The limit value doesn't work with all registries
// for example registry.access.redhat.com returns all the results without limiting it to the limit value
SearchRegistry queries a registry for images that contain image in their name The limit is the max number of results desired Note : The limit value doesn t work with all registries for example registry . access . redhat . com returns all the results without limiting it to the limit value