@@ -18,8 +18,11 @@ import (
18
18
"fmt"
19
19
20
20
"github.com/google/go-containerregistry/pkg/crane"
21
+ "github.com/google/go-containerregistry/pkg/name"
21
22
v1 "github.com/google/go-containerregistry/pkg/v1"
22
23
"github.com/google/go-containerregistry/pkg/v1/cache"
24
+ "github.com/google/go-containerregistry/pkg/v1/layout"
25
+ "github.com/google/go-containerregistry/pkg/v1/remote"
23
26
"github.com/spf13/cobra"
24
27
)
25
28
@@ -33,16 +36,38 @@ func NewCmdPull(options *[]crane.Option) *cobra.Command {
33
36
Args : cobra .MinimumNArgs (2 ),
34
37
RunE : func (_ * cobra.Command , args []string ) error {
35
38
imageMap := map [string ]v1.Image {}
39
+ indexMap := map [string ]v1.ImageIndex {}
36
40
srcList , path := args [:len (args )- 1 ], args [len (args )- 1 ]
37
41
for _ , src := range srcList {
38
- img , err := crane .Pull (src , * options ... )
42
+ o := crane .GetOptions (* options ... )
43
+ ref , err := name .ParseReference (src , o .Name ... )
39
44
if err != nil {
40
- return fmt .Errorf ("pulling %s: %w" , src , err )
45
+ return fmt .Errorf ("parsing reference %q: %w" , src , err )
46
+ }
47
+
48
+ rmt , err := remote .Get (ref , o .Remote ... )
49
+ if err != nil {
50
+ return err
51
+ }
52
+
53
+ // If we're writing an index to a layout and --platform hasn't been set,
54
+ // pull the entire index, not just a child image.
55
+ if format == "oci" && rmt .MediaType .IsIndex () && o .Platform == nil {
56
+ idx , err := rmt .ImageIndex ()
57
+ if err != nil {
58
+ return err
59
+ }
60
+ indexMap [src ] = idx
61
+ continue
62
+ }
63
+
64
+ img , err := rmt .Image ()
65
+ if err != nil {
66
+ return err
41
67
}
42
68
if cachePath != "" {
43
69
img = cache .Image (img , cache .NewFilesystemCache (cachePath ))
44
70
}
45
-
46
71
imageMap [src ] = img
47
72
}
48
73
@@ -59,6 +84,20 @@ func NewCmdPull(options *[]crane.Option) *cobra.Command {
59
84
if err := crane .MultiSaveOCI (imageMap , path ); err != nil {
60
85
return fmt .Errorf ("saving oci image layout %s: %w" , path , err )
61
86
}
87
+
88
+ // crane.MultiSaveOCI doesn't support index, so just append these at the end.
89
+ p , err := layout .FromPath (path )
90
+ if err != nil {
91
+ return err
92
+ }
93
+ for ref , idx := range indexMap {
94
+ anns := map [string ]string {
95
+ "dev.ggcr.image.name" : ref ,
96
+ }
97
+ if err := p .AppendIndex (idx , layout .WithAnnotations (anns )); err != nil {
98
+ return err
99
+ }
100
+ }
62
101
default :
63
102
return fmt .Errorf ("unexpected --format: %q (valid values are: tarball, legacy, and oci)" , format )
64
103
}
0 commit comments