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