github.com/go/docker@v1.12.0-rc2/layer/mounted_layer.go (about)

     1  package layer
     2  
     3  import (
     4  	"io"
     5  
     6  	"github.com/docker/docker/pkg/archive"
     7  )
     8  
     9  type mountedLayer struct {
    10  	name       string
    11  	mountID    string
    12  	initID     string
    13  	parent     *roLayer
    14  	path       string
    15  	layerStore *layerStore
    16  
    17  	references map[RWLayer]*referencedRWLayer
    18  }
    19  
    20  func (ml *mountedLayer) cacheParent() string {
    21  	if ml.initID != "" {
    22  		return ml.initID
    23  	}
    24  	if ml.parent != nil {
    25  		return ml.parent.cacheID
    26  	}
    27  	return ""
    28  }
    29  
    30  func (ml *mountedLayer) TarStream() (io.ReadCloser, error) {
    31  	archiver, err := ml.layerStore.driver.Diff(ml.mountID, ml.cacheParent())
    32  	if err != nil {
    33  		return nil, err
    34  	}
    35  	return archiver, nil
    36  }
    37  
    38  func (ml *mountedLayer) Name() string {
    39  	return ml.name
    40  }
    41  
    42  func (ml *mountedLayer) Parent() Layer {
    43  	if ml.parent != nil {
    44  		return ml.parent
    45  	}
    46  
    47  	// Return a nil interface instead of an interface wrapping a nil
    48  	// pointer.
    49  	return nil
    50  }
    51  
    52  func (ml *mountedLayer) Size() (int64, error) {
    53  	return ml.layerStore.driver.DiffSize(ml.mountID, ml.cacheParent())
    54  }
    55  
    56  func (ml *mountedLayer) Changes() ([]archive.Change, error) {
    57  	return ml.layerStore.driver.Changes(ml.mountID, ml.cacheParent())
    58  }
    59  
    60  func (ml *mountedLayer) Metadata() (map[string]string, error) {
    61  	return ml.layerStore.driver.GetMetadata(ml.mountID)
    62  }
    63  
    64  func (ml *mountedLayer) getReference() RWLayer {
    65  	ref := &referencedRWLayer{
    66  		mountedLayer: ml,
    67  	}
    68  	ml.references[ref] = ref
    69  
    70  	return ref
    71  }
    72  
    73  func (ml *mountedLayer) hasReferences() bool {
    74  	return len(ml.references) > 0
    75  }
    76  
    77  func (ml *mountedLayer) deleteReference(ref RWLayer) error {
    78  	if _, ok := ml.references[ref]; !ok {
    79  		return ErrLayerNotRetained
    80  	}
    81  	delete(ml.references, ref)
    82  	return nil
    83  }
    84  
    85  func (ml *mountedLayer) retakeReference(r RWLayer) {
    86  	if ref, ok := r.(*referencedRWLayer); ok {
    87  		ml.references[ref] = ref
    88  	}
    89  }
    90  
    91  type referencedRWLayer struct {
    92  	*mountedLayer
    93  }
    94  
    95  func (rl *referencedRWLayer) Mount(mountLabel string) (string, error) {
    96  	return rl.layerStore.driver.Get(rl.mountedLayer.mountID, mountLabel)
    97  }
    98  
    99  // Unmount decrements the activity count and unmounts the underlying layer
   100  // Callers should only call `Unmount` once per call to `Mount`, even on error.
   101  func (rl *referencedRWLayer) Unmount() error {
   102  	return rl.layerStore.driver.Put(rl.mountedLayer.mountID)
   103  }