Skip to content

Commit

Permalink
registry: implement pagination (#1430)
Browse files Browse the repository at this point in the history
  • Loading branch information
imjasonh authored Oct 19, 2022
1 parent d3ed408 commit 3413eb6
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 12 deletions.
36 changes: 24 additions & 12 deletions pkg/registry/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,12 +237,6 @@ func (m *manifests) handleTags(resp http.ResponseWriter, req *http.Request) *reg
elem := strings.Split(req.URL.Path, "/")
elem = elem[1:]
repo := strings.Join(elem[1:len(elem)-2], "/")
query := req.URL.Query()
nStr := query.Get("n")
n := 1000
if nStr != "" {
n, _ = strconv.Atoi(nStr)
}

if req.Method == "GET" {
m.lock.Lock()
Expand All @@ -258,19 +252,37 @@ func (m *manifests) handleTags(resp http.ResponseWriter, req *http.Request) *reg
}

var tags []string
countTags := 0
// TODO: implement pagination https://github.com/opencontainers/distribution-spec/blob/b505e9cc53ec499edbd9c1be32298388921bb705/detail.md#tags-paginated
for tag := range c {
if countTags >= n {
break
}
countTags++
if !strings.Contains(tag, "sha256:") {
tags = append(tags, tag)
}
}
sort.Strings(tags)

// https://github.com/opencontainers/distribution-spec/blob/b505e9cc53ec499edbd9c1be32298388921bb705/detail.md#tags-paginated
// Offset using last query parameter.
if last := req.URL.Query().Get("last"); last != "" {
for i, t := range tags {
if t > last {
tags = tags[i:]
break
}
}
}

// Limit using n query parameter.
if ns := req.URL.Query().Get("n"); ns != "" {
if n, err := strconv.Atoi(ns); err != nil {
return &regError{
Status: http.StatusBadRequest,
Code: "BAD_REQUEST",
Message: fmt.Sprintf("parsing n: %v", err),
}
} else if n < len(tags) {
tags = tags[:n]
}
}

tagsToList := listTags{
Name: repo,
Tags: tags,
Expand Down
17 changes: 17 additions & 0 deletions pkg/registry/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,23 @@ func TestCalls(t *testing.T) {
Method: "GET",
URL: "/v2/foo/tags/list?n=1000",
Code: http.StatusOK,
Want: `{"name":"foo","tags":["latest","tag1"]}`,
},
{
Description: "limit tags",
Manifests: map[string]string{"foo/manifests/latest": "foo", "foo/manifests/tag1": "foo"},
Method: "GET",
URL: "/v2/foo/tags/list?n=1",
Code: http.StatusOK,
Want: `{"name":"foo","tags":["latest"]}`,
},
{
Description: "offset tags",
Manifests: map[string]string{"foo/manifests/latest": "foo", "foo/manifests/tag1": "foo"},
Method: "GET",
URL: "/v2/foo/tags/list?last=latest",
Code: http.StatusOK,
Want: `{"name":"foo","tags":["tag1"]}`,
},
{
Description: "list non existing tags",
Expand Down

0 comments on commit 3413eb6

Please sign in to comment.