...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package crane
16
17 import (
18 "fmt"
19 "os"
20
21 legacy "github.com/google/go-containerregistry/pkg/legacy/tarball"
22 "github.com/google/go-containerregistry/pkg/name"
23 v1 "github.com/google/go-containerregistry/pkg/v1"
24 "github.com/google/go-containerregistry/pkg/v1/empty"
25 "github.com/google/go-containerregistry/pkg/v1/layout"
26 "github.com/google/go-containerregistry/pkg/v1/remote"
27 "github.com/google/go-containerregistry/pkg/v1/tarball"
28 )
29
30
31
32
33 const iWasADigestTag = "i-was-a-digest"
34
35
36 func Pull(src string, opt ...Option) (v1.Image, error) {
37 o := makeOptions(opt...)
38 ref, err := name.ParseReference(src, o.Name...)
39 if err != nil {
40 return nil, fmt.Errorf("parsing reference %q: %w", src, err)
41 }
42
43 return remote.Image(ref, o.Remote...)
44 }
45
46
47 func Save(img v1.Image, src, path string) error {
48 imgMap := map[string]v1.Image{src: img}
49 return MultiSave(imgMap, path)
50 }
51
52
53 func MultiSave(imgMap map[string]v1.Image, path string, opt ...Option) error {
54 o := makeOptions(opt...)
55 tagToImage := map[name.Tag]v1.Image{}
56
57 for src, img := range imgMap {
58 ref, err := name.ParseReference(src, o.Name...)
59 if err != nil {
60 return fmt.Errorf("parsing ref %q: %w", src, err)
61 }
62
63
64
65
66
67 tag, ok := ref.(name.Tag)
68 if !ok {
69 d, ok := ref.(name.Digest)
70 if !ok {
71 return fmt.Errorf("ref wasn't a tag or digest")
72 }
73 tag = d.Repository.Tag(iWasADigestTag)
74 }
75 tagToImage[tag] = img
76 }
77
78 return tarball.MultiWriteToFile(path, tagToImage)
79 }
80
81
82 func PullLayer(ref string, opt ...Option) (v1.Layer, error) {
83 o := makeOptions(opt...)
84 digest, err := name.NewDigest(ref, o.Name...)
85 if err != nil {
86 return nil, err
87 }
88
89 return remote.Layer(digest, o.Remote...)
90 }
91
92
93 func SaveLegacy(img v1.Image, src, path string) error {
94 imgMap := map[string]v1.Image{src: img}
95 return MultiSave(imgMap, path)
96 }
97
98
99 func MultiSaveLegacy(imgMap map[string]v1.Image, path string) error {
100 refToImage := map[name.Reference]v1.Image{}
101
102 for src, img := range imgMap {
103 ref, err := name.ParseReference(src)
104 if err != nil {
105 return fmt.Errorf("parsing ref %q: %w", src, err)
106 }
107 refToImage[ref] = img
108 }
109
110 w, err := os.Create(path)
111 if err != nil {
112 return err
113 }
114 defer w.Close()
115
116 return legacy.MultiWrite(refToImage, w)
117 }
118
119
120
121 func SaveOCI(img v1.Image, path string) error {
122 imgMap := map[string]v1.Image{"": img}
123 return MultiSaveOCI(imgMap, path)
124 }
125
126
127
128 func MultiSaveOCI(imgMap map[string]v1.Image, path string) error {
129 p, err := layout.FromPath(path)
130 if err != nil {
131 p, err = layout.Write(path, empty.Index)
132 if err != nil {
133 return err
134 }
135 }
136 for _, img := range imgMap {
137 if err = p.AppendImage(img); err != nil {
138 return err
139 }
140 }
141 return nil
142 }
143
View as plain text