瀏覽代碼

Merge pull request #15507 from clintonskitson/patch_issue_15467

added check for bind on create to determine local volume driver
Jessie Frazelle 10 年之前
父節點
當前提交
19f7bfcda9

+ 2 - 1
daemon/create.go

@@ -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{}
 	}
@@ -97,7 +98,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
 	}
 

+ 19 - 4
daemon/create_unix.go

@@ -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)

+ 2 - 1
daemon/create_windows.go

@@ -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
 }

+ 35 - 0
integration-cli/docker_cli_start_volume_driver_unix_test.go

@@ -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)
+}

+ 30 - 0
integration-cli/docker_utils.go

@@ -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
+
+}