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  }