Skip to content

Commit

Permalink
enable search using pagination
Browse files Browse the repository at this point in the history
Enable search registry uses the pagination until the search result reaches the limit, instead of returning default 100 limit from registry API.
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1827794

Signed-off-by: Qi Wang <[email protected]>
  • Loading branch information
QiWang19 committed Jun 26, 2020
1 parent 8c2dee2 commit d2e8517
Showing 1 changed file with 41 additions and 18 deletions.
59 changes: 41 additions & 18 deletions docker/docker_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,6 @@ func SearchRegistry(ctx context.Context, sys *types.SystemContext, registry, ima
// 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
Expand Down Expand Up @@ -388,31 +387,55 @@ func SearchRegistry(ctx context.Context, sys *types.SystemContext, registry, ima
}

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 {
searchRes := []SearchResult{}
path := "/v2/_catalog"
for len(searchRes) < limit {
resp, err := client.makeRequest(ctx, "GET", path, nil, nil, v2Auth, nil)
if err != nil {
logrus.Debugf("error getting search results from v2 endpoint %q: %v", registry, err)
return nil, errors.Wrapf(err, "couldn't search registry %q", registry)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
logrus.Errorf("error getting search results from v2 endpoint %q: %v", registry, httpResponseToError(resp, ""))
} else {
if err := json.NewDecoder(resp.Body).Decode(v2Res); err != nil {
return nil, err
return nil, errors.Wrapf(err, "couldn't search registry %q", registry)
}
v2Res := &V2Results{}
if err := json.NewDecoder(resp.Body).Decode(v2Res); err != nil {
return nil, err
}

for _, repo := range v2Res.Repositories {
if len(searchRes) == limit {
break
}
searchRes := []SearchResult{}
for _, repo := range v2Res.Repositories {
if strings.Contains(repo, image) {
res := SearchResult{
Name: repo,
}
searchRes = append(searchRes, res)
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)
link := resp.Header.Get("Link")
if link == "" {
break
}
linkURLStr := strings.Trim(strings.Split(link, ";")[0], "<>")
linkURL, err := url.Parse(linkURLStr)
if err != nil {
return searchRes, err
}

// can be relative or absolute, but we only want the path (and I
// guess we're in trouble if it forwards to a new place...)
path = linkURL.Path
if linkURL.RawQuery != "" {
path += "?"
path += linkURL.RawQuery
}
}
return searchRes, nil
}

// makeRequest creates and executes a http.Request with the specified parameters, adding authentication and TLS options for the Docker client.
Expand Down

0 comments on commit d2e8517

Please sign in to comment.