github.com/rish1988/moby@v25.0.2+incompatible/layer/ro_layer.go (about) 1 package layer // import "github.com/docker/docker/layer" 2 3 import ( 4 "fmt" 5 "io" 6 7 "github.com/docker/distribution" 8 "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() int64 { 77 size := rl.size 78 if rl.parent != nil { 79 size += rl.parent.Size() 80 } 81 82 return size 83 } 84 85 func (rl *roLayer) DiffSize() int64 { 86 return rl.size 87 } 88 89 func (rl *roLayer) Metadata() (map[string]string, error) { 90 return rl.layerStore.driver.GetMetadata(rl.cacheID) 91 } 92 93 type referencedCacheLayer struct { 94 *roLayer 95 } 96 97 func (rl *roLayer) getReference() Layer { 98 ref := &referencedCacheLayer{ 99 roLayer: rl, 100 } 101 rl.references[ref] = struct{}{} 102 103 return ref 104 } 105 106 func (rl *roLayer) hasReference(ref Layer) bool { 107 _, ok := rl.references[ref] 108 return ok 109 } 110 111 func (rl *roLayer) hasReferences() bool { 112 return len(rl.references) > 0 113 } 114 115 func (rl *roLayer) deleteReference(ref Layer) { 116 delete(rl.references, ref) 117 } 118 119 func (rl *roLayer) depth() int { 120 if rl.parent == nil { 121 return 1 122 } 123 return rl.parent.depth() + 1 124 } 125 126 func storeLayer(tx *fileMetadataTransaction, layer *roLayer) error { 127 if err := tx.SetDiffID(layer.diffID); err != nil { 128 return err 129 } 130 if err := tx.SetSize(layer.size); err != nil { 131 return err 132 } 133 if err := tx.SetCacheID(layer.cacheID); err != nil { 134 return err 135 } 136 // Do not store empty descriptors 137 if layer.descriptor.Digest != "" { 138 if err := tx.SetDescriptor(layer.descriptor); err != nil { 139 return err 140 } 141 } 142 if layer.parent != nil { 143 if err := tx.SetParent(layer.parent.chainID); err != nil { 144 return err 145 } 146 } 147 return nil 148 } 149 150 func newVerifiedReadCloser(rc io.ReadCloser, dgst digest.Digest) (io.ReadCloser, error) { 151 return &verifiedReadCloser{ 152 rc: rc, 153 dgst: dgst, 154 verifier: dgst.Verifier(), 155 }, nil 156 } 157 158 type verifiedReadCloser struct { 159 rc io.ReadCloser 160 dgst digest.Digest 161 verifier digest.Verifier 162 } 163 164 func (vrc *verifiedReadCloser) Read(p []byte) (n int, err error) { 165 n, err = vrc.rc.Read(p) 166 if n > 0 { 167 if n, err := vrc.verifier.Write(p[:n]); err != nil { 168 return n, err 169 } 170 } 171 if err == io.EOF { 172 if !vrc.verifier.Verified() { 173 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) 174 } 175 } 176 return 177 } 178 179 func (vrc *verifiedReadCloser) Close() error { 180 return vrc.rc.Close() 181 }