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