This allows a user to specify explicitly to enable automatic copying of data from the container path to the volume path. This does not change the default behavior of automatically copying, but does allow a user to disable it at runtime. Signed-off-by: Brian Goff <cpuguy83@gmail.com> Upstream-commit: b0ac69b67ef79c6c937f84bee3df20a1924ad334 Component: engine
77 lines
2.2 KiB
Go
77 lines
2.2 KiB
Go
// +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)
|
|
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
|
|
}
|