daemon/create_unix.go
47c56e43
 // +build !windows
 
4f0d95fa
 package daemon // import "github.com/docker/docker/daemon"
47c56e43
 
 import (
e4b6adc8
 	"context"
a793564b
 	"fmt"
47c56e43
 	"os"
 	"path/filepath"
 
91e197d6
 	containertypes "github.com/docker/docker/api/types/container"
fc7b904d
 	mounttypes "github.com/docker/docker/api/types/mount"
6bb0d181
 	"github.com/docker/docker/container"
3694c1e3
 	"github.com/docker/docker/oci"
47c56e43
 	"github.com/docker/docker/pkg/stringid"
e4b6adc8
 	volumeopts "github.com/docker/docker/volume/service/opts"
abbbf914
 	"github.com/opencontainers/selinux/go-selinux/label"
1009e6a4
 	"github.com/sirupsen/logrus"
47c56e43
 )
 
0380fbff
 // createContainerOSSpecificSettings performs host-OS specific container create functionality
 func (daemon *Daemon) createContainerOSSpecificSettings(container *container.Container, config *containertypes.Config, hostConfig *containertypes.HostConfig) error {
9112d90b
 	if err := daemon.Mount(container); err != nil {
 		return err
 	}
 	defer daemon.Unmount(container)
 
763d8392
 	rootIDs := daemon.idMapping.RootPair()
09cd96c5
 	if err := container.SetupWorkingDirectory(rootIDs); err != nil {
cde0ed67
 		return err
 	}
 
3694c1e3
 	// Set the default masked and readonly paths with regard to the host config options if they are not set.
 	if hostConfig.MaskedPaths == nil && !hostConfig.Privileged {
 		hostConfig.MaskedPaths = oci.DefaultSpec().Linux.MaskedPaths // Set it to the default if nil
 		container.HostConfig.MaskedPaths = hostConfig.MaskedPaths
 	}
 	if hostConfig.ReadonlyPaths == nil && !hostConfig.Privileged {
 		hostConfig.ReadonlyPaths = oci.DefaultSpec().Linux.ReadonlyPaths // Set it to the default if nil
 		container.HostConfig.ReadonlyPaths = hostConfig.ReadonlyPaths
 	}
 
47c56e43
 	for spec := range config.Volumes {
510e79eb
 		name := stringid.GenerateRandomID()
cec31abf
 		destination := filepath.Clean(spec)
8e5bb8fd
 
47c56e43
 		// Skip volumes for which we already have something mounted on that
 		// destination because of a --volume-from.
6bb0d181
 		if container.IsDestinationMounted(destination) {
47c56e43
 			continue
 		}
 		path, err := container.GetResourcePath(destination)
 		if err != nil {
 			return err
 		}
 
 		stat, err := os.Stat(path)
 		if err == nil && !stat.IsDir() {
a793564b
 			return fmt.Errorf("cannot mount volume over existing file, file exists %s", path)
47c56e43
 		}
 
e4b6adc8
 		v, err := daemon.volumes.Create(context.TODO(), name, hostConfig.VolumeDriver, volumeopts.WithCreateReference(container.ID))
47c56e43
 		if err != nil {
 			return err
 		}
b3b7eb27
 
e4b6adc8
 		if err := label.Relabel(v.Mountpoint, container.MountLabel, true); err != nil {
47c56e43
 			return err
 		}
 
e4b6adc8
 		container.AddMountPointWithVolume(destination, &volumeWrapper{v: v, s: daemon.volumes}, true)
b4683327
 	}
 	return daemon.populateVolumes(container)
 }
 
 // populateVolumes copies data from the container's rootfs into the volume for non-binds.
 // this is only called when the container is created.
 func (daemon *Daemon) populateVolumes(c *container.Container) error {
 	for _, mnt := range c.MountPoints {
fc7b904d
 		if mnt.Volume == nil {
 			continue
 		}
 
 		if mnt.Type != mounttypes.TypeVolume || !mnt.CopyData {
b4683327
 			continue
47c56e43
 		}
 
b4683327
 		logrus.Debugf("copying image data from %s:%s, to %s", c.ID, mnt.Destination, mnt.Name)
 		if err := c.CopyImagePathContent(mnt.Volume, mnt.Destination); err != nil {
 			return err
 		}
47c56e43
 	}
 	return nil
 }