github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/layer/ro_layer.go (about) 1 package layer // import "github.com/demonoid81/moby/layer" 2 3 import ( 4 "fmt" 5 "io" 6 7 "github.com/docker/distribution" 8 digest "github.com/opencontainers/go-digest" 9 ) 10 11 type roLayer struct { 12 chainID ChainID 13 diffID DiffID 14 parent *roLayer 15 cacheID string 16 size int64 17 layerStore *layerStore 18 descriptor distribution.Descriptor 19 20 referenceCount int 21 references map[Layer]struct{} 22 } 23 24 // TarStream for roLayer guarantees that the data that is produced is the exact 25 // data that the layer was registered with. 26 func (rl *roLayer) TarStream() (io.ReadCloser, error) { 27 rc, err := rl.layerStore.getTarStream(rl) 28 if err != nil { 29 return nil, err 30 } 31 32 vrc, err := newVerifiedReadCloser(rc, digest.Digest(rl.diffID)) 33 if err != nil { 34 return nil, err 35 } 36 return vrc, nil 37 } 38 39 // TarStreamFrom does not make any guarantees to the correctness of the produced 40 // data. As such it should not be used when the layer content must be verified 41 // to be an exact match to the registered layer. 42 func (rl *roLayer) TarStreamFrom(parent ChainID) (io.ReadCloser, error) { 43 var parentCacheID string 44 for pl := rl.parent; pl != nil; pl = pl.parent { 45 if pl.chainID == parent { 46 parentCacheID = pl.cacheID 47 break 48 } 49 } 50 51 if parent != ChainID("") && parentCacheID == "" { 52 return nil, fmt.Errorf("layer ID '%s' is not a parent of the specified layer: cannot provide diff to non-parent", parent) 53 } 54 return rl.layerStore.driver.Diff(rl.cacheID, parentCacheID) 55 } 56 57 func (rl *roLayer) CacheID() string { 58 return rl.cacheID 59 } 60 61 func (rl *roLayer) ChainID() ChainID { 62 return rl.chainID 63 } 64 65 func (rl *roLayer) DiffID() DiffID { 66 return rl.diffID 67 } 68 69 func (rl *roLayer) Parent() Layer { 70 if rl.parent == nil { 71 return nil 72 } 73 return rl.parent 74 } 75 76 func (rl *roLayer) Size() (size int64, err error) { 77 if rl.parent != nil { 78 size, err = rl.parent.Size() 79 if err != nil { 80 return 81 } 82 } 83 84 return size + rl.size, nil 85 } 86 87 func (rl *roLayer) DiffSize() (size int64, err error) { 88 return rl.size, nil 89 } 90 91 func (rl *roLayer) Metadata() (map[string]string, error) { 92 return rl.layerStore.driver.GetMetadata(rl.cacheID) 93 } 94 95 type referencedCacheLayer struct { 96 *roLayer 97 } 98 99 func (rl *roLayer) getReference() Layer { 100 ref := &referencedCacheLayer{ 101 roLayer: rl, 102 } 103 rl.references[ref] = struct{}{} 104 105 return ref 106 } 107 108 func (rl *roLayer) hasReference(ref Layer) bool { 109 _, ok := rl.references[ref] 110 return ok 111 } 112 113 func (rl *roLayer) hasReferences() bool { 114 return len(rl.references) > 0 115 } 116 117 func (rl *roLayer) deleteReference(ref Layer) { 118 delete(rl.references, ref) 119 } 120 121 func (rl *roLayer) depth() int { 122 if rl.parent == nil { 123 return 1 124 } 125 return rl.parent.depth() + 1 126 } 127 128 func storeLayer(tx *fileMetadataTransaction, layer *roLayer) error { 129 if err := tx.SetDiffID(layer.diffID); err != nil { 130 return err 131 } 132 if err := tx.SetSize(layer.size); err != nil { 133 return err 134 } 135 if err := tx.SetCacheID(layer.cacheID); err != nil { 136 return err 137 } 138 // Do not store empty descriptors 139 if layer.descriptor.Digest != "" { 140 if err := tx.SetDescriptor(layer.descriptor); err != nil { 141 return err 142 } 143 } 144 if layer.parent != nil { 145 if err := tx.SetParent(layer.parent.chainID); err != nil { 146 return err 147 } 148 } 149 return tx.setOS(layer.layerStore.os) 150 } 151 152 func newVerifiedReadCloser(rc io.ReadCloser, dgst digest.Digest) (io.ReadCloser, error) { 153 return &verifiedReadCloser{ 154 rc: rc, 155 dgst: dgst, 156 verifier: dgst.Verifier(), 157 }, nil 158 } 159 160 type verifiedReadCloser struct { 161 rc io.ReadCloser 162 dgst digest.Digest 163 verifier digest.Verifier 164 } 165 166 func (vrc *verifiedReadCloser) Read(p []byte) (n int, err error) { 167 n, err = vrc.rc.Read(p) 168 if n > 0 { 169 if n, err := vrc.verifier.Write(p[:n]); err != nil { 170 return n, err 171 } 172 } 173 if err == io.EOF { 174 if !vrc.verifier.Verified() { 175 err = fmt.Errorf("could not verify layer data for: %s. This may be because internal files in the layer store were modified. Re-pulling or rebuilding this image may resolve the issue", vrc.dgst) 176 } 177 } 178 return 179 } 180 func (vrc *verifiedReadCloser) Close() error { 181 return vrc.rc.Close() 182 }