github.com/portworx/docker@v1.12.1/daemon/create_unix.go (about)

     1  // +build !windows
     2  
     3  package daemon
     4  
     5  import (
     6  	"fmt"
     7  	"os"
     8  	"path/filepath"
     9  
    10  	"github.com/Sirupsen/logrus"
    11  	"github.com/docker/docker/container"
    12  	"github.com/docker/docker/pkg/stringid"
    13  	containertypes "github.com/docker/engine-api/types/container"
    14  	"github.com/opencontainers/runc/libcontainer/label"
    15  )
    16  
    17  // createContainerPlatformSpecificSettings performs platform specific container create functionality
    18  func (daemon *Daemon) createContainerPlatformSpecificSettings(container *container.Container, config *containertypes.Config, hostConfig *containertypes.HostConfig) error {
    19  	if err := daemon.Mount(container); err != nil {
    20  		return err
    21  	}
    22  	defer daemon.Unmount(container)
    23  
    24  	rootUID, rootGID := daemon.GetRemappedUIDGID()
    25  	if err := container.SetupWorkingDirectory(rootUID, rootGID); err != nil {
    26  		return err
    27  	}
    28  
    29  	for spec := range config.Volumes {
    30  		name := stringid.GenerateNonCryptoID()
    31  		destination := filepath.Clean(spec)
    32  
    33  		// Skip volumes for which we already have something mounted on that
    34  		// destination because of a --volume-from.
    35  		if container.IsDestinationMounted(destination) {
    36  			continue
    37  		}
    38  		path, err := container.GetResourcePath(destination)
    39  		if err != nil {
    40  			return err
    41  		}
    42  
    43  		stat, err := os.Stat(path)
    44  		if err == nil && !stat.IsDir() {
    45  			return fmt.Errorf("cannot mount volume over existing file, file exists %s", path)
    46  		}
    47  
    48  		v, err := daemon.volumes.CreateWithRef(name, hostConfig.VolumeDriver, container.ID, nil, nil)
    49  		if err != nil {
    50  			return err
    51  		}
    52  
    53  		if err := label.Relabel(v.Path(), container.MountLabel, true); err != nil {
    54  			return err
    55  		}
    56  
    57  		container.AddMountPointWithVolume(destination, v, true)
    58  	}
    59  	return daemon.populateVolumes(container)
    60  }
    61  
    62  // populateVolumes copies data from the container's rootfs into the volume for non-binds.
    63  // this is only called when the container is created.
    64  func (daemon *Daemon) populateVolumes(c *container.Container) error {
    65  	for _, mnt := range c.MountPoints {
    66  		if !mnt.CopyData || mnt.Volume == nil {
    67  			continue
    68  		}
    69  
    70  		logrus.Debugf("copying image data from %s:%s, to %s", c.ID, mnt.Destination, mnt.Name)
    71  		if err := c.CopyImagePathContent(mnt.Volume, mnt.Destination); err != nil {
    72  			return err
    73  		}
    74  	}
    75  	return nil
    76  }