Browse Source

Merge pull request #27974 from yongtang/27969-duplicate-bind-mount

Fix issue related to duplicate identical bind mounts for `docker run`
Akihiro Suda 8 years ago
parent
commit
e448a32192
2 changed files with 26 additions and 2 deletions
  1. 21 0
      integration-cli/docker_cli_run_test.go
  2. 5 2
      runconfig/opts/parse.go

+ 21 - 0
integration-cli/docker_cli_run_test.go

@@ -4567,3 +4567,24 @@ func (s *DockerSuite) TestRunServicingContainer(c *check.C) {
 	c.Assert(out2, checker.Contains, `Windows Container (Servicing)`, check.Commentf("Didn't find 'Windows Container (Servicing): %s", out2))
 	c.Assert(out2, checker.Contains, containerID+"_servicing", check.Commentf("Didn't find '%s_servicing': %s", containerID+"_servicing", out2))
 }
+
+func (s *DockerSuite) TestRunDuplicateMount(c *check.C) {
+	testRequires(c, DaemonIsLinux)
+
+	tmpFile, err := ioutil.TempFile("", "touch-me")
+	c.Assert(err, checker.IsNil)
+	defer tmpFile.Close()
+
+	data := "touch-me-foo-bar\n"
+	if _, err := tmpFile.Write([]byte(data)); err != nil {
+		c.Fatal(err)
+	}
+
+	name := "test"
+	out, _ := dockerCmd(c, "run", "--name", name, "-v", "/tmp:/tmp", "-v", "/tmp:/tmp", "busybox", "sh", "-c", "cat "+tmpFile.Name()+" && ls /")
+	c.Assert(out, checker.Not(checker.Contains), "tmp:")
+	c.Assert(out, checker.Contains, data)
+
+	out = inspectFieldJSON(c, name, "Config.Volumes")
+	c.Assert(out, checker.Contains, "null")
+}

+ 5 - 2
runconfig/opts/parse.go

@@ -348,13 +348,16 @@ func Parse(flags *pflag.FlagSet, copts *ContainerOptions) (*container.Config, *c
 	}
 
 	var binds []string
+	volumes := copts.volumes.GetMap()
 	// add any bind targets to the list of container volumes
 	for bind := range copts.volumes.GetMap() {
 		if arr := volumeSplitN(bind, 2); len(arr) > 1 {
 			// after creating the bind mount we want to delete it from the copts.volumes values because
 			// we do not want bind mounts being committed to image configs
 			binds = append(binds, bind)
-			copts.volumes.Delete(bind)
+			// We should delete from the map (`volumes`) here, as deleting from copts.volumes will not work if
+			// there are duplicates entries.
+			delete(volumes, bind)
 		}
 	}
 
@@ -556,7 +559,7 @@ func Parse(flags *pflag.FlagSet, copts *ContainerOptions) (*container.Config, *c
 		Env:             envVariables,
 		Cmd:             runCmd,
 		Image:           copts.Image,
-		Volumes:         copts.volumes.GetMap(),
+		Volumes:         volumes,
 		MacAddress:      copts.macAddress,
 		Entrypoint:      entrypoint,
 		WorkingDir:      copts.workingDir,