| // +build !windows |
| |
| package daemon |
| |
| import ( |
| "fmt" |
| "os" |
| "path/filepath" |
| |
| "github.com/Sirupsen/logrus" |
| "github.com/docker/docker/container" |
| "github.com/docker/docker/pkg/stringid" |
| containertypes "github.com/docker/engine-api/types/container" |
| "github.com/opencontainers/runc/libcontainer/label" |
| ) |
| |
| // createContainerPlatformSpecificSettings performs platform specific container create functionality |
| func (daemon *Daemon) createContainerPlatformSpecificSettings(container *container.Container, config *containertypes.Config, hostConfig *containertypes.HostConfig) error { |
| if err := daemon.Mount(container); err != nil { |
| return err |
| } |
| defer daemon.Unmount(container) |
| |
| rootUID, rootGID := daemon.GetRemappedUIDGID() |
| if err := container.SetupWorkingDirectory(rootUID, rootGID); err != nil { |
| return err |
| } |
| |
| for spec := range config.Volumes { |
| name := stringid.GenerateNonCryptoID() |
| destination := filepath.Clean(spec) |
| |
| // Skip volumes for which we already have something mounted on that |
| // destination because of a --volume-from. |
| if container.IsDestinationMounted(destination) { |
| continue |
| } |
| path, err := container.GetResourcePath(destination) |
| if err != nil { |
| return err |
| } |
| |
| stat, err := os.Stat(path) |
| if err == nil && !stat.IsDir() { |
| return fmt.Errorf("cannot mount volume over existing file, file exists %s", path) |
| } |
| |
| v, err := daemon.volumes.CreateWithRef(name, hostConfig.VolumeDriver, container.ID, nil, nil) |
| if err != nil { |
| return err |
| } |
| |
| if err := label.Relabel(v.Path(), container.MountLabel, true); err != nil { |
| return err |
| } |
| |
| container.AddMountPointWithVolume(destination, v, true) |
| } |
| 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 { |
| if !mnt.CopyData || mnt.Volume == nil { |
| continue |
| } |
| |
| 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 |
| } |
| } |
| return nil |
| } |