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