github.com/jiasir/docker@v1.3.3-0.20170609024000-252e610103e7/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/selinux/go-selinux/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 rootIDs := daemon.idMappings.RootPair() 26 if err := container.SetupWorkingDirectory(rootIDs); 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 }