github.com/jingleWang/moby@v1.13.1/layer/ro_layer.go (about) 1 package layer 2 3 import ( 4 "fmt" 5 "io" 6 7 "github.com/docker/distribution" 8 "github.com/docker/distribution/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 guarentees 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 r, err := rl.layerStore.store.TarSplitReader(rl.chainID) 28 if err != nil { 29 return nil, err 30 } 31 32 pr, pw := io.Pipe() 33 go func() { 34 err := rl.layerStore.assembleTarTo(rl.cacheID, r, nil, pw) 35 if err != nil { 36 pw.CloseWithError(err) 37 } else { 38 pw.Close() 39 } 40 }() 41 rc, err := newVerifiedReadCloser(pr, digest.Digest(rl.diffID)) 42 if err != nil { 43 return nil, err 44 } 45 return rc, nil 46 } 47 48 // TarStreamFrom does not make any guarentees to the correctness of the produced 49 // data. As such it should not be used when the layer content must be verified 50 // to be an exact match to the registered layer. 51 func (rl *roLayer) TarStreamFrom(parent ChainID) (io.ReadCloser, error) { 52 var parentCacheID string 53 for pl := rl.parent; pl != nil; pl = pl.parent { 54 if pl.chainID == parent { 55 parentCacheID = pl.cacheID 56 break 57 } 58 } 59 60 if parent != ChainID("") && parentCacheID == "" { 61 return nil, fmt.Errorf("layer ID '%s' is not a parent of the specified layer: cannot provide diff to non-parent", parent) 62 } 63 return rl.layerStore.driver.Diff(rl.cacheID, parentCacheID) 64 } 65 66 func (rl *roLayer) ChainID() ChainID { 67 return rl.chainID 68 } 69 70 func (rl *roLayer) DiffID() DiffID { 71 return rl.diffID 72 } 73 74 func (rl *roLayer) Parent() Layer { 75 if rl.parent == nil { 76 return nil 77 } 78 return rl.parent 79 } 80 81 func (rl *roLayer) Size() (size int64, err error) { 82 if rl.parent != nil { 83 size, err = rl.parent.Size() 84 if err != nil { 85 return 86 } 87 } 88 89 return size + rl.size, nil 90 } 91 92 func (rl *roLayer) DiffSize() (size int64, err error) { 93 return rl.size, nil 94 } 95 96 func (rl *roLayer) Metadata() (map[string]string, error) { 97 return rl.layerStore.driver.GetMetadata(rl.cacheID) 98 } 99 100 type referencedCacheLayer struct { 101 *roLayer 102 } 103 104 func (rl *roLayer) getReference() Layer { 105 ref := &referencedCacheLayer{ 106 roLayer: rl, 107 } 108 rl.references[ref] = struct{}{} 109 110 return ref 111 } 112 113 func (rl *roLayer) hasReference(ref Layer) bool { 114 _, ok := rl.references[ref] 115 return ok 116 } 117 118 func (rl *roLayer) hasReferences() bool { 119 return len(rl.references) > 0 120 } 121 122 func (rl *roLayer) deleteReference(ref Layer) { 123 delete(rl.references, ref) 124 } 125 126 func (rl *roLayer) depth() int { 127 if rl.parent == nil { 128 return 1 129 } 130 return rl.parent.depth() + 1 131 } 132 133 func storeLayer(tx MetadataTransaction, layer *roLayer) error { 134 if err := tx.SetDiffID(layer.diffID); err != nil { 135 return err 136 } 137 if err := tx.SetSize(layer.size); err != nil { 138 return err 139 } 140 if err := tx.SetCacheID(layer.cacheID); err != nil { 141 return err 142 } 143 // Do not store empty descriptors 144 if layer.descriptor.Digest != "" { 145 if err := tx.SetDescriptor(layer.descriptor); err != nil { 146 return err 147 } 148 } 149 if layer.parent != nil { 150 if err := tx.SetParent(layer.parent.chainID); err != nil { 151 return err 152 } 153 } 154 155 return nil 156 } 157 158 func newVerifiedReadCloser(rc io.ReadCloser, dgst digest.Digest) (io.ReadCloser, error) { 159 verifier, err := digest.NewDigestVerifier(dgst) 160 if err != nil { 161 return nil, err 162 } 163 return &verifiedReadCloser{ 164 rc: rc, 165 dgst: dgst, 166 verifier: verifier, 167 }, nil 168 } 169 170 type verifiedReadCloser struct { 171 rc io.ReadCloser 172 dgst digest.Digest 173 verifier digest.Verifier 174 } 175 176 func (vrc *verifiedReadCloser) Read(p []byte) (n int, err error) { 177 n, err = vrc.rc.Read(p) 178 if n > 0 { 179 if n, err := vrc.verifier.Write(p[:n]); err != nil { 180 return n, err 181 } 182 } 183 if err == io.EOF { 184 if !vrc.verifier.Verified() { 185 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) 186 } 187 } 188 return 189 } 190 func (vrc *verifiedReadCloser) Close() error { 191 return vrc.rc.Close() 192 }