1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package remote
16
17 import (
18 "context"
19 "errors"
20 "fmt"
21
22 "github.com/google/go-containerregistry/pkg/logs"
23 "github.com/google/go-containerregistry/pkg/name"
24 v1 "github.com/google/go-containerregistry/pkg/v1"
25 "github.com/google/go-containerregistry/pkg/v1/partial"
26 "github.com/google/go-containerregistry/pkg/v1/types"
27 )
28
29 var allManifestMediaTypes = append(append([]types.MediaType{
30 types.DockerManifestSchema1,
31 types.DockerManifestSchema1Signed,
32 }, acceptableImageMediaTypes...), acceptableIndexMediaTypes...)
33
34
35
36
37 var ErrSchema1 = errors.New("see https://github.com/google/go-containerregistry/issues/377")
38
39
40 func newErrSchema1(schema types.MediaType) error {
41 return fmt.Errorf("unsupported MediaType: %q, %w", schema, ErrSchema1)
42 }
43
44
45
46 type Descriptor struct {
47 fetcher fetcher
48 v1.Descriptor
49
50 ref name.Reference
51 Manifest []byte
52 ctx context.Context
53
54
55 platform v1.Platform
56 }
57
58 func (d *Descriptor) toDesc() v1.Descriptor {
59 return d.Descriptor
60 }
61
62
63 func (d *Descriptor) RawManifest() ([]byte, error) {
64 return d.Manifest, nil
65 }
66
67
68
69
70
71
72 func Get(ref name.Reference, options ...Option) (*Descriptor, error) {
73 return get(ref, allManifestMediaTypes, options...)
74 }
75
76
77
78
79
80
81 func Head(ref name.Reference, options ...Option) (*v1.Descriptor, error) {
82 o, err := makeOptions(options...)
83 if err != nil {
84 return nil, err
85 }
86
87 return newPuller(o).Head(o.context, ref)
88 }
89
90
91
92 func get(ref name.Reference, acceptable []types.MediaType, options ...Option) (*Descriptor, error) {
93 o, err := makeOptions(options...)
94 if err != nil {
95 return nil, err
96 }
97 return newPuller(o).get(o.context, ref, acceptable, o.platform)
98 }
99
100
101
102
103
104
105
106
107
108 func (d *Descriptor) Image() (v1.Image, error) {
109 switch d.MediaType {
110 case types.DockerManifestSchema1, types.DockerManifestSchema1Signed:
111
112
113 return nil, newErrSchema1(d.MediaType)
114 case types.OCIImageIndex, types.DockerManifestList:
115
116 return d.remoteIndex().imageByPlatform(d.platform)
117 case types.OCIManifestSchema1, types.DockerManifestSchema2:
118
119 default:
120
121
122 logs.Warn.Printf("Unexpected media type for Image(): %s", d.MediaType)
123 }
124
125
126
127 imgCore, err := partial.CompressedToImage(d.remoteImage())
128 if err != nil {
129 return nil, err
130 }
131 return &mountableImage{
132 Image: imgCore,
133 Reference: d.ref,
134 }, nil
135 }
136
137
138
139
140
141
142 func (d *Descriptor) Schema1() (v1.Image, error) {
143 i := &schema1{
144 ref: d.ref,
145 fetcher: d.fetcher,
146 ctx: d.ctx,
147 manifest: d.Manifest,
148 mediaType: d.MediaType,
149 descriptor: &d.Descriptor,
150 }
151
152 return &mountableImage{
153 Image: i,
154 Reference: d.ref,
155 }, nil
156 }
157
158
159 func (d *Descriptor) ImageIndex() (v1.ImageIndex, error) {
160 switch d.MediaType {
161 case types.DockerManifestSchema1, types.DockerManifestSchema1Signed:
162
163
164 return nil, newErrSchema1(d.MediaType)
165 case types.OCIManifestSchema1, types.DockerManifestSchema2:
166
167 return nil, fmt.Errorf("unexpected media type for ImageIndex(): %s; call Image() instead", d.MediaType)
168 case types.OCIImageIndex, types.DockerManifestList:
169
170 default:
171
172
173 logs.Warn.Printf("Unexpected media type for ImageIndex(): %s", d.MediaType)
174 }
175 return d.remoteIndex(), nil
176 }
177
178 func (d *Descriptor) remoteImage() *remoteImage {
179 return &remoteImage{
180 ref: d.ref,
181 ctx: d.ctx,
182 fetcher: d.fetcher,
183 manifest: d.Manifest,
184 mediaType: d.MediaType,
185 descriptor: &d.Descriptor,
186 }
187 }
188
189 func (d *Descriptor) remoteIndex() *remoteIndex {
190 return &remoteIndex{
191 ref: d.ref,
192 ctx: d.ctx,
193 fetcher: d.fetcher,
194 manifest: d.Manifest,
195 mediaType: d.MediaType,
196 descriptor: &d.Descriptor,
197 }
198 }
199
View as plain text