github.com/portworx/docker@v1.12.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 func (rl *roLayer) TarStream() (io.ReadCloser, error) { 25 r, err := rl.layerStore.store.TarSplitReader(rl.chainID) 26 if err != nil { 27 return nil, err 28 } 29 30 pr, pw := io.Pipe() 31 go func() { 32 err := rl.layerStore.assembleTarTo(rl.cacheID, r, nil, pw) 33 if err != nil { 34 pw.CloseWithError(err) 35 } else { 36 pw.Close() 37 } 38 }() 39 rc, err := newVerifiedReadCloser(pr, digest.Digest(rl.diffID)) 40 if err != nil { 41 return nil, err 42 } 43 return rc, nil 44 } 45 46 func (rl *roLayer) ChainID() ChainID { 47 return rl.chainID 48 } 49 50 func (rl *roLayer) DiffID() DiffID { 51 return rl.diffID 52 } 53 54 func (rl *roLayer) Parent() Layer { 55 if rl.parent == nil { 56 return nil 57 } 58 return rl.parent 59 } 60 61 func (rl *roLayer) Size() (size int64, err error) { 62 if rl.parent != nil { 63 size, err = rl.parent.Size() 64 if err != nil { 65 return 66 } 67 } 68 69 return size + rl.size, nil 70 } 71 72 func (rl *roLayer) DiffSize() (size int64, err error) { 73 return rl.size, nil 74 } 75 76 func (rl *roLayer) Metadata() (map[string]string, error) { 77 return rl.layerStore.driver.GetMetadata(rl.cacheID) 78 } 79 80 type referencedCacheLayer struct { 81 *roLayer 82 } 83 84 func (rl *roLayer) getReference() Layer { 85 ref := &referencedCacheLayer{ 86 roLayer: rl, 87 } 88 rl.references[ref] = struct{}{} 89 90 return ref 91 } 92 93 func (rl *roLayer) hasReference(ref Layer) bool { 94 _, ok := rl.references[ref] 95 return ok 96 } 97 98 func (rl *roLayer) hasReferences() bool { 99 return len(rl.references) > 0 100 } 101 102 func (rl *roLayer) deleteReference(ref Layer) { 103 delete(rl.references, ref) 104 } 105 106 func (rl *roLayer) depth() int { 107 if rl.parent == nil { 108 return 1 109 } 110 return rl.parent.depth() + 1 111 } 112 113 func storeLayer(tx MetadataTransaction, layer *roLayer) error { 114 if err := tx.SetDiffID(layer.diffID); err != nil { 115 return err 116 } 117 if err := tx.SetSize(layer.size); err != nil { 118 return err 119 } 120 if err := tx.SetCacheID(layer.cacheID); err != nil { 121 return err 122 } 123 // Do not store empty descriptors 124 if layer.descriptor.Digest != "" { 125 if err := tx.SetDescriptor(layer.descriptor); err != nil { 126 return err 127 } 128 } 129 if layer.parent != nil { 130 if err := tx.SetParent(layer.parent.chainID); err != nil { 131 return err 132 } 133 } 134 135 return nil 136 } 137 138 func newVerifiedReadCloser(rc io.ReadCloser, dgst digest.Digest) (io.ReadCloser, error) { 139 verifier, err := digest.NewDigestVerifier(dgst) 140 if err != nil { 141 return nil, err 142 } 143 return &verifiedReadCloser{ 144 rc: rc, 145 dgst: dgst, 146 verifier: verifier, 147 }, nil 148 } 149 150 type verifiedReadCloser struct { 151 rc io.ReadCloser 152 dgst digest.Digest 153 verifier digest.Verifier 154 } 155 156 func (vrc *verifiedReadCloser) Read(p []byte) (n int, err error) { 157 n, err = vrc.rc.Read(p) 158 if n > 0 { 159 if n, err := vrc.verifier.Write(p[:n]); err != nil { 160 return n, err 161 } 162 } 163 if err == io.EOF { 164 if !vrc.verifier.Verified() { 165 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) 166 } 167 } 168 return 169 } 170 func (vrc *verifiedReadCloser) Close() error { 171 return vrc.rc.Close() 172 }