Explorar o código

Fixes re-creating volume on (re)start

When a container is restarted all the volume configs are parsed again.
Even if the volume was already handled in a previous start it was still
calling "FindOrCreateVolume" on the volume repo causing a new volume to
be created.

This wasn't being detected because as part of the mount initialization
it checks to see if the the _mount_ was already initialized, but this
happens after the parsing of the configs.
So a check is added during parsing to skip a volume which was already
created for that container.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Brian Goff %!s(int64=10) %!d(string=hai) anos
pai
achega
c985302c5c

+ 5 - 0
daemon/volumes.go

@@ -131,6 +131,11 @@ func (container *Container) parseVolumeMountConfig() (map[string]*Mount, error)
 			continue
 		}
 
+		// Check if this has already been created
+		if _, exists := container.Volumes[path]; exists {
+			continue
+		}
+
 		vol, err := container.daemon.volumes.FindOrCreateVolume("", true)
 		if err != nil {
 			return nil, err

+ 37 - 0
integration-cli/docker_cli_run_test.go

@@ -2339,3 +2339,40 @@ func TestVolumesNoCopyData(t *testing.T) {
 
 	logDone("run - volumes do not copy data for volumes-from and bindmounts")
 }
+
+func TestRunVolumesNotRecreatedOnStart(t *testing.T) {
+	// Clear out any remnants from other tests
+	deleteAllContainers()
+	info, err := ioutil.ReadDir(volumesConfigPath)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(info) > 0 {
+		for _, f := range info {
+			if err := os.RemoveAll(volumesConfigPath + "/" + f.Name()); err != nil {
+				t.Fatal(err)
+			}
+		}
+	}
+
+	defer deleteAllContainers()
+	cmd := exec.Command(dockerBinary, "run", "-v", "/foo", "--name", "lone_starr", "busybox")
+	if _, err := runCommand(cmd); err != nil {
+		t.Fatal(err)
+	}
+
+	cmd = exec.Command(dockerBinary, "start", "lone_starr")
+	if _, err := runCommand(cmd); err != nil {
+		t.Fatal(err)
+	}
+
+	info, err = ioutil.ReadDir(volumesConfigPath)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(info) != 1 {
+		t.Fatalf("Expected only 1 volume have %v", len(info))
+	}
+
+	logDone("run - volumes not recreated on start")
+}

+ 11 - 8
integration-cli/docker_test_vars.go

@@ -6,18 +6,21 @@ import (
 	"os/exec"
 )
 
-// the docker binary to use
-var dockerBinary = "docker"
+var (
+	// the docker binary to use
+	dockerBinary = "docker"
 
-// the private registry image to use for tests involving the registry
-var registryImageName = "registry"
+	// the private registry image to use for tests involving the registry
+	registryImageName = "registry"
 
-// the private registry to use for tests
-var privateRegistryURL = "127.0.0.1:5000"
+	// the private registry to use for tests
+	privateRegistryURL = "127.0.0.1:5000"
 
-var execDriverPath = "/var/lib/docker/execdriver/native"
+	execDriverPath    = "/var/lib/docker/execdriver/native"
+	volumesConfigPath = "/var/lib/docker/volumes"
 
-var workingDirectory string
+	workingDirectory string
+)
 
 func init() {
 	if dockerBin := os.Getenv("DOCKER_BINARY"); dockerBin != "" {

+ 1 - 1
integration-cli/docker_utils.go

@@ -267,7 +267,7 @@ func deleteContainer(container string) error {
 	killSplitArgs := strings.Split(killArgs, " ")
 	killCmd := exec.Command(dockerBinary, killSplitArgs...)
 	runCommand(killCmd)
-	rmArgs := fmt.Sprintf("rm %v", container)
+	rmArgs := fmt.Sprintf("rm -v %v", container)
 	rmSplitArgs := strings.Split(rmArgs, " ")
 	rmCmd := exec.Command(dockerBinary, rmSplitArgs...)
 	exitCode, err := runCommand(rmCmd)