added check for bind on create to determine local volume driver

Signed-off-by: Clinton Kitson <clintonskitson@gmail.com>
This commit is contained in:
Clinton Kitson 2015-08-11 19:27:33 -07:00
Родитель f5e2c6f14b
Коммит 6b8129d1fe
5 изменённых файлов: 88 добавлений и 6 удалений

Просмотреть файл

@ -63,6 +63,7 @@ func (daemon *Daemon) Create(config *runconfig.Config, hostConfig *runconfig.Hos
if err := daemon.mergeAndVerifyConfig(config, img); err != nil {
return nil, nil, err
}
if hostConfig == nil {
hostConfig = &runconfig.HostConfig{}
}
@ -89,7 +90,7 @@ func (daemon *Daemon) Create(config *runconfig.Config, hostConfig *runconfig.Hos
}
defer container.Unmount()
if err := createContainerPlatformSpecificSettings(container, config); err != nil {
if err := createContainerPlatformSpecificSettings(container, config, img); err != nil {
return nil, nil, err
}

Просмотреть файл

@ -8,13 +8,15 @@ import (
"path/filepath"
"strings"
"github.com/docker/docker/image"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/runconfig"
"github.com/docker/docker/volume"
"github.com/opencontainers/runc/libcontainer/label"
)
// createContainerPlatformSpecificSettings performs platform specific container create functionality
func createContainerPlatformSpecificSettings(container *Container, config *runconfig.Config) error {
func createContainerPlatformSpecificSettings(container *Container, config *runconfig.Config, img *image.Image) error {
for spec := range config.Volumes {
var (
name, destination string
@ -42,7 +44,17 @@ func createContainerPlatformSpecificSettings(container *Container, config *runco
return fmt.Errorf("cannot mount volume over existing file, file exists %s", path)
}
v, err := createVolume(name, config.VolumeDriver)
volumeDriver := config.VolumeDriver
if destination != "" && img != nil {
if _, ok := img.ContainerConfig.Volumes[destination]; ok {
// check for whether bind is not specified and then set to local
if _, ok := container.MountPoints[destination]; !ok {
volumeDriver = volume.DefaultDriverName
}
}
}
v, err := createVolume(name, volumeDriver)
if err != nil {
return err
}
@ -50,8 +62,11 @@ func createContainerPlatformSpecificSettings(container *Container, config *runco
return err
}
if err := container.copyImagePathContent(v, destination); err != nil {
return err
// never attempt to copy existing content in a container FS to a shared volume
if volumeDriver == volume.DefaultDriverName || volumeDriver == "" {
if err := container.copyImagePathContent(v, destination); err != nil {
return err
}
}
container.addMountPointWithVolume(destination, v, true)

Просмотреть файл

@ -1,10 +1,11 @@
package daemon
import (
"github.com/docker/docker/image"
"github.com/docker/docker/runconfig"
)
// createContainerPlatformSpecificSettings performs platform specific container create functionality
func createContainerPlatformSpecificSettings(container *Container, config *runconfig.Config) error {
func createContainerPlatformSpecificSettings(container *Container, config *runconfig.Config, img *image.Image) error {
return nil
}

Просмотреть файл

@ -244,3 +244,38 @@ func (s DockerExternalVolumeSuite) TestStartExternalVolumeDriverDeleteContainer(
func hostVolumePath(name string) string {
return fmt.Sprintf("/var/lib/docker/volumes/%s", name)
}
func (s *DockerExternalVolumeSuite) TestStartExternalNamedVolumeDriverCheckBindLocalVolume(c *check.C) {
if err := s.d.StartWithBusybox(); err != nil {
c.Fatal(err)
}
expected := s.server.URL
dockerfile := fmt.Sprintf(`FROM busybox:latest
RUN mkdir /nobindthenlocalvol
RUN echo %s > /nobindthenlocalvol/test
VOLUME ["/nobindthenlocalvol"]`, expected)
img := "test-checkbindlocalvolume"
args := []string{"--host", s.d.sock()}
buildOut, err := buildImageArgs(args, img, dockerfile, true)
fmt.Println(buildOut)
out, err := s.d.Cmd("run", "--rm", "--name", "test-data-nobind", "-v", "external-volume-test:/tmp/external-volume-test", "--volume-driver", "test-external-volume-driver", img, "cat", "/nobindthenlocalvol/test")
if err != nil {
fmt.Println(out)
c.Fatal(err)
}
if !strings.Contains(out, expected) {
c.Fatalf("External volume mount failed. Output: %s\n", out)
}
c.Assert(s.ec.activations, check.Equals, 1)
c.Assert(s.ec.creations, check.Equals, 1)
c.Assert(s.ec.removals, check.Equals, 1)
c.Assert(s.ec.mounts, check.Equals, 1)
c.Assert(s.ec.unmounts, check.Equals, 1)
}

Просмотреть файл

@ -1353,3 +1353,33 @@ func createTmpFile(c *check.C, content string) string {
return filename
}
func buildImageArgs(args []string, name, dockerfile string, useCache bool) (string, error) {
id, _, err := buildImageWithOutArgs(args, name, dockerfile, useCache)
return id, err
}
func buildImageWithOutArgs(args []string, name, dockerfile string, useCache bool) (string, string, error) {
buildCmd := buildImageCmdArgs(args, name, dockerfile, useCache)
out, exitCode, err := runCommandWithOutput(buildCmd)
if err != nil || exitCode != 0 {
return "", out, fmt.Errorf("failed to build the image: %s", out)
}
id, err := getIDByName(name)
if err != nil {
return "", out, err
}
return id, out, nil
}
func buildImageCmdArgs(args []string, name, dockerfile string, useCache bool) *exec.Cmd {
args = append(args, []string{"-D", "build", "-t", name}...)
if !useCache {
args = append(args, "--no-cache")
}
args = append(args, "-")
buildCmd := exec.Command(dockerBinary, args...)
buildCmd.Stdin = strings.NewReader(dockerfile)
return buildCmd
}