7a7357dae1
This enables docker cp and ADD/COPY docker build support for LCOW. Originally, the graphdriver.Get() interface returned a local path to the container root filesystem. This does not work for LCOW, so the Get() method now returns an interface that LCOW implements to support copying to and from the container. Signed-off-by: Akash Gupta <akagup@microsoft.com>
100 lines
2.2 KiB
Go
100 lines
2.2 KiB
Go
package layer
|
|
|
|
import (
|
|
"io"
|
|
|
|
"github.com/docker/docker/pkg/archive"
|
|
"github.com/docker/docker/pkg/containerfs"
|
|
)
|
|
|
|
type mountedLayer struct {
|
|
name string
|
|
mountID string
|
|
initID string
|
|
parent *roLayer
|
|
path string
|
|
layerStore *layerStore
|
|
|
|
references map[RWLayer]*referencedRWLayer
|
|
}
|
|
|
|
func (ml *mountedLayer) cacheParent() string {
|
|
if ml.initID != "" {
|
|
return ml.initID
|
|
}
|
|
if ml.parent != nil {
|
|
return ml.parent.cacheID
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (ml *mountedLayer) TarStream() (io.ReadCloser, error) {
|
|
return ml.layerStore.driver.Diff(ml.mountID, ml.cacheParent())
|
|
}
|
|
|
|
func (ml *mountedLayer) Name() string {
|
|
return ml.name
|
|
}
|
|
|
|
func (ml *mountedLayer) Parent() Layer {
|
|
if ml.parent != nil {
|
|
return ml.parent
|
|
}
|
|
|
|
// Return a nil interface instead of an interface wrapping a nil
|
|
// pointer.
|
|
return nil
|
|
}
|
|
|
|
func (ml *mountedLayer) Size() (int64, error) {
|
|
return ml.layerStore.driver.DiffSize(ml.mountID, ml.cacheParent())
|
|
}
|
|
|
|
func (ml *mountedLayer) Changes() ([]archive.Change, error) {
|
|
return ml.layerStore.driver.Changes(ml.mountID, ml.cacheParent())
|
|
}
|
|
|
|
func (ml *mountedLayer) Metadata() (map[string]string, error) {
|
|
return ml.layerStore.driver.GetMetadata(ml.mountID)
|
|
}
|
|
|
|
func (ml *mountedLayer) getReference() RWLayer {
|
|
ref := &referencedRWLayer{
|
|
mountedLayer: ml,
|
|
}
|
|
ml.references[ref] = ref
|
|
|
|
return ref
|
|
}
|
|
|
|
func (ml *mountedLayer) hasReferences() bool {
|
|
return len(ml.references) > 0
|
|
}
|
|
|
|
func (ml *mountedLayer) deleteReference(ref RWLayer) error {
|
|
if _, ok := ml.references[ref]; !ok {
|
|
return ErrLayerNotRetained
|
|
}
|
|
delete(ml.references, ref)
|
|
return nil
|
|
}
|
|
|
|
func (ml *mountedLayer) retakeReference(r RWLayer) {
|
|
if ref, ok := r.(*referencedRWLayer); ok {
|
|
ml.references[ref] = ref
|
|
}
|
|
}
|
|
|
|
type referencedRWLayer struct {
|
|
*mountedLayer
|
|
}
|
|
|
|
func (rl *referencedRWLayer) Mount(mountLabel string) (containerfs.ContainerFS, error) {
|
|
return rl.layerStore.driver.Get(rl.mountedLayer.mountID, mountLabel)
|
|
}
|
|
|
|
// Unmount decrements the activity count and unmounts the underlying layer
|
|
// Callers should only call `Unmount` once per call to `Mount`, even on error.
|
|
func (rl *referencedRWLayer) Unmount() error {
|
|
return rl.layerStore.driver.Put(rl.mountedLayer.mountID)
|
|
}
|