Skip to content

Commit aeda835

Browse files
committed
feat: support pagination for tags
Refs: thanks genuinetools#220
1 parent 6fdffcc commit aeda835

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-3
lines changed

registry/tags.go

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import (
66
"github.com/distribution/distribution/v3/manifest/schema2"
77
"github.com/opencontainers/go-digest"
88
ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
9+
"github.com/peterhellberg/link"
910
"github.com/sirupsen/logrus"
11+
"net/url"
1012
"time"
1113
)
1214

@@ -16,14 +18,38 @@ type tagsResponse struct {
1618

1719
// Tags returns the tags for a specific repository.
1820
func (r *Registry) Tags(ctx context.Context, repository string) ([]string, error) {
19-
url := r.url("/v2/%s/tags/list", repository)
20-
r.Logf("registry.tags url=%s repository=%s", url, repository)
21+
return r.tagsWithPagination(ctx, repository, "")
22+
}
23+
24+
func (r *Registry) tagsWithPagination(ctx context.Context, repository string, u string) ([]string, error) {
25+
var uri string
26+
if u == "" {
27+
r.Logf("registry.tags url=%s repository=%s", u, repository)
28+
uri = r.url("/v2/%s/tags/list", repository)
29+
} else {
30+
uri = r.url(u)
31+
}
32+
33+
r.Logf("registry.tags url=%s repository=%s", uri, repository)
2134

2235
var response tagsResponse
23-
if _, err := r.getJSON(ctx, url, &response); err != nil {
36+
h, err := r.getJSON(ctx, uri, &response)
37+
if err != nil {
2438
return nil, err
2539
}
2640

41+
for _, l := range link.ParseHeader(h) {
42+
if l.Rel == "next" {
43+
logrus.Infof("begin fetch next page, repo:%s, link: %s", repository, l.URI)
44+
unescaped, _ := url.QueryUnescape(l.URI)
45+
tags, err := r.tagsWithPagination(ctx, repository, unescaped)
46+
if err != nil {
47+
return nil, err
48+
}
49+
response.Tags = append(response.Tags, tags...)
50+
}
51+
}
52+
2753
return response.Tags, nil
2854
}
2955

0 commit comments

Comments
 (0)