From 44a180294ac4564604fbed248b4bce9da9a3f384 Mon Sep 17 00:00:00 2001 From: Jason Hall Date: Mon, 15 Aug 2022 09:30:29 -0400 Subject: [PATCH] registry: implement pagination --- pkg/registry/manifest.go | 36 +++++++++++++++++++++++------------ pkg/registry/registry_test.go | 17 +++++++++++++++++ 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/pkg/registry/manifest.go b/pkg/registry/manifest.go index 2a9723916..6c556604c 100644 --- a/pkg/registry/manifest.go +++ b/pkg/registry/manifest.go @@ -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() @@ -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 ®Error{ + 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, diff --git a/pkg/registry/registry_test.go b/pkg/registry/registry_test.go index 6186aafc1..8ee038860 100644 --- a/pkg/registry/registry_test.go +++ b/pkg/registry/registry_test.go @@ -400,6 +400,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",