...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package layout
16
17 import (
18 "fmt"
19 "io"
20 "os"
21 "sync"
22
23 v1 "github.com/google/go-containerregistry/pkg/v1"
24 "github.com/google/go-containerregistry/pkg/v1/partial"
25 "github.com/google/go-containerregistry/pkg/v1/types"
26 )
27
28 type layoutImage struct {
29 path Path
30 desc v1.Descriptor
31 manifestLock sync.Mutex
32 rawManifest []byte
33 }
34
35 var _ partial.CompressedImageCore = (*layoutImage)(nil)
36
37
38 func (l Path) Image(h v1.Hash) (v1.Image, error) {
39 ii, err := l.ImageIndex()
40 if err != nil {
41 return nil, err
42 }
43
44 return ii.Image(h)
45 }
46
47 func (li *layoutImage) MediaType() (types.MediaType, error) {
48 return li.desc.MediaType, nil
49 }
50
51
52 func (li *layoutImage) Manifest() (*v1.Manifest, error) {
53 return partial.Manifest(li)
54 }
55
56 func (li *layoutImage) RawManifest() ([]byte, error) {
57 li.manifestLock.Lock()
58 defer li.manifestLock.Unlock()
59 if li.rawManifest != nil {
60 return li.rawManifest, nil
61 }
62
63 b, err := li.path.Bytes(li.desc.Digest)
64 if err != nil {
65 return nil, err
66 }
67
68 li.rawManifest = b
69 return li.rawManifest, nil
70 }
71
72 func (li *layoutImage) RawConfigFile() ([]byte, error) {
73 manifest, err := li.Manifest()
74 if err != nil {
75 return nil, err
76 }
77
78 return li.path.Bytes(manifest.Config.Digest)
79 }
80
81 func (li *layoutImage) LayerByDigest(h v1.Hash) (partial.CompressedLayer, error) {
82 manifest, err := li.Manifest()
83 if err != nil {
84 return nil, err
85 }
86
87 if h == manifest.Config.Digest {
88 return &compressedBlob{
89 path: li.path,
90 desc: manifest.Config,
91 }, nil
92 }
93
94 for _, desc := range manifest.Layers {
95 if h == desc.Digest {
96 return &compressedBlob{
97 path: li.path,
98 desc: desc,
99 }, nil
100 }
101 }
102
103 return nil, fmt.Errorf("could not find layer in image: %s", h)
104 }
105
106 type compressedBlob struct {
107 path Path
108 desc v1.Descriptor
109 }
110
111 func (b *compressedBlob) Digest() (v1.Hash, error) {
112 return b.desc.Digest, nil
113 }
114
115 func (b *compressedBlob) Compressed() (io.ReadCloser, error) {
116 return b.path.Blob(b.desc.Digest)
117 }
118
119 func (b *compressedBlob) Size() (int64, error) {
120 return b.desc.Size, nil
121 }
122
123 func (b *compressedBlob) MediaType() (types.MediaType, error) {
124 return b.desc.MediaType, nil
125 }
126
127
128 func (b *compressedBlob) Descriptor() (*v1.Descriptor, error) {
129 return &b.desc, nil
130 }
131
132
133 func (b *compressedBlob) Exists() (bool, error) {
134 _, err := os.Stat(b.path.blobPath(b.desc.Digest))
135 if os.IsNotExist(err) {
136 return false, nil
137 }
138 return err == nil, err
139 }
140
View as plain text