github.com/vieux/docker@v0.6.3-0.20161004191708-e097c2a938c7/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  func (rl *roLayer) TarStream() (io.ReadCloser, error) {
    25  	r, err := rl.layerStore.store.TarSplitReader(rl.chainID)
    26  	if err != nil {
    27  		return nil, err
    28  	}
    29  
    30  	pr, pw := io.Pipe()
    31  	go func() {
    32  		err := rl.layerStore.assembleTarTo(rl.cacheID, r, nil, pw)
    33  		if err != nil {
    34  			pw.CloseWithError(err)
    35  		} else {
    36  			pw.Close()
    37  		}
    38  	}()
    39  	rc, err := newVerifiedReadCloser(pr, digest.Digest(rl.diffID))
    40  	if err != nil {
    41  		return nil, err
    42  	}
    43  	return rc, nil
    44  }
    45  
    46  func (rl *roLayer) ChainID() ChainID {
    47  	return rl.chainID
    48  }
    49  
    50  func (rl *roLayer) DiffID() DiffID {
    51  	return rl.diffID
    52  }
    53  
    54  func (rl *roLayer) Parent() Layer {
    55  	if rl.parent == nil {
    56  		return nil
    57  	}
    58  	return rl.parent
    59  }
    60  
    61  func (rl *roLayer) Size() (size int64, err error) {
    62  	if rl.parent != nil {
    63  		size, err = rl.parent.Size()
    64  		if err != nil {
    65  			return
    66  		}
    67  	}
    68  
    69  	return size + rl.size, nil
    70  }
    71  
    72  func (rl *roLayer) DiffSize() (size int64, err error) {
    73  	return rl.size, nil
    74  }
    75  
    76  func (rl *roLayer) Metadata() (map[string]string, error) {
    77  	return rl.layerStore.driver.GetMetadata(rl.cacheID)
    78  }
    79  
    80  type referencedCacheLayer struct {
    81  	*roLayer
    82  }
    83  
    84  func (rl *roLayer) getReference() Layer {
    85  	ref := &referencedCacheLayer{
    86  		roLayer: rl,
    87  	}
    88  	rl.references[ref] = struct{}{}
    89  
    90  	return ref
    91  }
    92  
    93  func (rl *roLayer) hasReference(ref Layer) bool {
    94  	_, ok := rl.references[ref]
    95  	return ok
    96  }
    97  
    98  func (rl *roLayer) hasReferences() bool {
    99  	return len(rl.references) > 0
   100  }
   101  
   102  func (rl *roLayer) deleteReference(ref Layer) {
   103  	delete(rl.references, ref)
   104  }
   105  
   106  func (rl *roLayer) depth() int {
   107  	if rl.parent == nil {
   108  		return 1
   109  	}
   110  	return rl.parent.depth() + 1
   111  }
   112  
   113  func storeLayer(tx MetadataTransaction, layer *roLayer) error {
   114  	if err := tx.SetDiffID(layer.diffID); err != nil {
   115  		return err
   116  	}
   117  	if err := tx.SetSize(layer.size); err != nil {
   118  		return err
   119  	}
   120  	if err := tx.SetCacheID(layer.cacheID); err != nil {
   121  		return err
   122  	}
   123  	// Do not store empty descriptors
   124  	if layer.descriptor.Digest != "" {
   125  		if err := tx.SetDescriptor(layer.descriptor); err != nil {
   126  			return err
   127  		}
   128  	}
   129  	if layer.parent != nil {
   130  		if err := tx.SetParent(layer.parent.chainID); err != nil {
   131  			return err
   132  		}
   133  	}
   134  
   135  	return nil
   136  }
   137  
   138  func newVerifiedReadCloser(rc io.ReadCloser, dgst digest.Digest) (io.ReadCloser, error) {
   139  	verifier, err := digest.NewDigestVerifier(dgst)
   140  	if err != nil {
   141  		return nil, err
   142  	}
   143  	return &verifiedReadCloser{
   144  		rc:       rc,
   145  		dgst:     dgst,
   146  		verifier: verifier,
   147  	}, nil
   148  }
   149  
   150  type verifiedReadCloser struct {
   151  	rc       io.ReadCloser
   152  	dgst     digest.Digest
   153  	verifier digest.Verifier
   154  }
   155  
   156  func (vrc *verifiedReadCloser) Read(p []byte) (n int, err error) {
   157  	n, err = vrc.rc.Read(p)
   158  	if n > 0 {
   159  		if n, err := vrc.verifier.Write(p[:n]); err != nil {
   160  			return n, err
   161  		}
   162  	}
   163  	if err == io.EOF {
   164  		if !vrc.verifier.Verified() {
   165  			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)
   166  		}
   167  	}
   168  	return
   169  }
   170  func (vrc *verifiedReadCloser) Close() error {
   171  	return vrc.rc.Close()
   172  }