6
6
"github.com/distribution/distribution/v3/manifest/schema2"
7
7
"github.com/opencontainers/go-digest"
8
8
ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
9
+ "github.com/peterhellberg/link"
9
10
"github.com/sirupsen/logrus"
11
+ "net/url"
10
12
"time"
11
13
)
12
14
@@ -16,14 +18,38 @@ type tagsResponse struct {
16
18
17
19
// Tags returns the tags for a specific repository.
18
20
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 )
21
34
22
35
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 {
24
38
return nil , err
25
39
}
26
40
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
+
27
53
return response .Tags , nil
28
54
}
29
55
0 commit comments