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