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