1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package partial
16
17 import (
18 "io"
19
20 "github.com/google/go-containerregistry/internal/and"
21 "github.com/google/go-containerregistry/internal/compression"
22 "github.com/google/go-containerregistry/internal/gzip"
23 "github.com/google/go-containerregistry/internal/zstd"
24 comp "github.com/google/go-containerregistry/pkg/compression"
25 v1 "github.com/google/go-containerregistry/pkg/v1"
26 "github.com/google/go-containerregistry/pkg/v1/types"
27 )
28
29
30
31 type CompressedLayer interface {
32
33 Digest() (v1.Hash, error)
34
35
36 Compressed() (io.ReadCloser, error)
37
38
39 Size() (int64, error)
40
41
42 MediaType() (types.MediaType, error)
43 }
44
45
46 type compressedLayerExtender struct {
47 CompressedLayer
48 }
49
50
51 func (cle *compressedLayerExtender) Uncompressed() (io.ReadCloser, error) {
52 rc, err := cle.Compressed()
53 if err != nil {
54 return nil, err
55 }
56
57
58
59
60 cp, pr, err := compression.PeekCompression(rc)
61 if err != nil {
62 return nil, err
63 }
64
65 prc := &and.ReadCloser{
66 Reader: pr,
67 CloseFunc: rc.Close,
68 }
69
70 switch cp {
71 case comp.GZip:
72 return gzip.UnzipReadCloser(prc)
73 case comp.ZStd:
74 return zstd.UnzipReadCloser(prc)
75 default:
76 return prc, nil
77 }
78 }
79
80
81 func (cle *compressedLayerExtender) DiffID() (v1.Hash, error) {
82
83
84 if wdi, ok := cle.CompressedLayer.(WithDiffID); ok {
85 return wdi.DiffID()
86 }
87 r, err := cle.Uncompressed()
88 if err != nil {
89 return v1.Hash{}, err
90 }
91 defer r.Close()
92 h, _, err := v1.SHA256(r)
93 return h, err
94 }
95
96
97 func CompressedToLayer(ul CompressedLayer) (v1.Layer, error) {
98 return &compressedLayerExtender{ul}, nil
99 }
100
101
102
103 type CompressedImageCore interface {
104 ImageCore
105
106
107 RawManifest() ([]byte, error)
108
109
110
111 LayerByDigest(v1.Hash) (CompressedLayer, error)
112 }
113
114
115
116 type compressedImageExtender struct {
117 CompressedImageCore
118 }
119
120
121 var _ v1.Image = (*compressedImageExtender)(nil)
122
123
124 func (i *compressedImageExtender) Digest() (v1.Hash, error) {
125 return Digest(i)
126 }
127
128
129 func (i *compressedImageExtender) ConfigName() (v1.Hash, error) {
130 return ConfigName(i)
131 }
132
133
134 func (i *compressedImageExtender) Layers() ([]v1.Layer, error) {
135 hs, err := FSLayers(i)
136 if err != nil {
137 return nil, err
138 }
139 ls := make([]v1.Layer, 0, len(hs))
140 for _, h := range hs {
141 l, err := i.LayerByDigest(h)
142 if err != nil {
143 return nil, err
144 }
145 ls = append(ls, l)
146 }
147 return ls, nil
148 }
149
150
151 func (i *compressedImageExtender) LayerByDigest(h v1.Hash) (v1.Layer, error) {
152 cl, err := i.CompressedImageCore.LayerByDigest(h)
153 if err != nil {
154 return nil, err
155 }
156 return CompressedToLayer(cl)
157 }
158
159
160 func (i *compressedImageExtender) LayerByDiffID(h v1.Hash) (v1.Layer, error) {
161 h, err := DiffIDToBlob(i, h)
162 if err != nil {
163 return nil, err
164 }
165 return i.LayerByDigest(h)
166 }
167
168
169 func (i *compressedImageExtender) ConfigFile() (*v1.ConfigFile, error) {
170 return ConfigFile(i)
171 }
172
173
174 func (i *compressedImageExtender) Manifest() (*v1.Manifest, error) {
175 return Manifest(i)
176 }
177
178
179 func (i *compressedImageExtender) Size() (int64, error) {
180 return Size(i)
181 }
182
183
184 func CompressedToImage(cic CompressedImageCore) (v1.Image, error) {
185 return &compressedImageExtender{
186 CompressedImageCore: cic,
187 }, nil
188 }
189
View as plain text