7 "github.com/docker/distribution"
8 "github.com/docker/docker/pkg/ioutils"
9 "github.com/opencontainers/go-digest"
18 layerStore *layerStore
19 descriptor distribution.Descriptor
23 references map[Layer]struct{}
26 // TarStream for roLayer guarantees that the data that is produced is the exact
27 // data that the layer was registered with.
28 func (rl *roLayer) TarStream() (io.ReadCloser, error) {
29 rc, err := rl.layerStore.getTarStream(rl)
34 vrc, err := newVerifiedReadCloser(rc, digest.Digest(rl.diffID))
41 // TarSeekStream for roLayer guarantees that the data that is produced is the exact
42 // data that the layer was registered with.
43 func (rl *roLayer) TarSeekStream() (ioutils.ReadSeekCloser, error) {
44 return rl.layerStore.getTarSeekStream(rl)
47 // TarStreamFrom does not make any guarantees to the correctness of the produced
48 // data. As such it should not be used when the layer content must be verified
49 // to be an exact match to the registered layer.
50 func (rl *roLayer) TarStreamFrom(parent ChainID) (io.ReadCloser, error) {
51 var parentCacheID string
52 for pl := rl.parent; pl != nil; pl = pl.parent {
53 if pl.chainID == parent {
54 parentCacheID = pl.cacheID
59 if parent != ChainID("") && parentCacheID == "" {
60 return nil, fmt.Errorf("layer ID '%s' is not a parent of the specified layer: cannot provide diff to non-parent", parent)
62 return rl.layerStore.driver.Diff(rl.cacheID, parentCacheID)
65 func (rl *roLayer) ChainID() ChainID {
69 func (rl *roLayer) DiffID() DiffID {
73 func (rl *roLayer) Parent() Layer {
80 func (rl *roLayer) Size() (size int64, err error) {
82 size, err = rl.parent.Size()
88 return size + rl.size, nil
91 func (rl *roLayer) DiffSize() (size int64, err error) {
95 func (rl *roLayer) Metadata() (map[string]string, error) {
96 return rl.layerStore.driver.GetMetadata(rl.cacheID)
99 type referencedCacheLayer struct {
103 func (rl *roLayer) getReference() Layer {
104 ref := &referencedCacheLayer{
107 rl.references[ref] = struct{}{}
112 func (rl *roLayer) hasReference(ref Layer) bool {
113 _, ok := rl.references[ref]
117 func (rl *roLayer) hasReferences() bool {
118 return len(rl.references) > 0
121 func (rl *roLayer) deleteReference(ref Layer) {
122 delete(rl.references, ref)
125 func (rl *roLayer) depth() int {
126 if rl.parent == nil {
129 return rl.parent.depth() + 1
132 func storeLayer(tx MetadataTransaction, layer *roLayer) error {
133 if err := tx.SetDiffID(layer.diffID); err != nil {
136 if err := tx.SetSize(layer.size); err != nil {
139 if err := tx.SetCacheID(layer.cacheID); err != nil {
142 // Do not store empty descriptors
143 if layer.descriptor.Digest != "" {
144 if err := tx.SetDescriptor(layer.descriptor); err != nil {
148 if layer.parent != nil {
149 if err := tx.SetParent(layer.parent.chainID); err != nil {
153 if err := tx.SetPlatform(layer.platform); err != nil {
160 func newVerifiedReadCloser(rc io.ReadCloser, dgst digest.Digest) (io.ReadCloser, error) {
161 return &verifiedReadCloser{
164 verifier: dgst.Verifier(),
168 type verifiedReadCloser struct {
171 verifier digest.Verifier
174 func (vrc *verifiedReadCloser) Read(p []byte) (n int, err error) {
175 n, err = vrc.rc.Read(p)
177 if n, err := vrc.verifier.Write(p[:n]); err != nil {
182 if !vrc.verifier.Verified() {
183 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)
188 func (vrc *verifiedReadCloser) Close() error {
189 return vrc.rc.Close()