Don't allow duplicate `-v` specifications for the same target
| ... | ... |
@@ -158,6 +158,10 @@ func (container *Container) parseVolumeMountConfig() (map[string]*Mount, error) |
| 158 | 158 |
if err != nil {
|
| 159 | 159 |
return nil, err |
| 160 | 160 |
} |
| 161 |
+ // Check if a bind mount has already been specified for the same container path |
|
| 162 |
+ if m, exists := mounts[mountToPath]; exists {
|
|
| 163 |
+ return nil, fmt.Errorf("Duplicate volume %q: %q already in use, mounted from %q", path, mountToPath, m.volume.Path)
|
|
| 164 |
+ } |
|
| 161 | 165 |
// Check if a volume already exists for this and use it |
| 162 | 166 |
vol, err := container.daemon.volumes.FindOrCreateVolume(path, writable) |
| 163 | 167 |
if err != nil {
|
| ... | ... |
@@ -493,6 +493,21 @@ func TestVolumesFromGetsProperMode(t *testing.T) {
|
| 493 | 493 |
logDone("run - volumes from ignores `rw` if inherrited volume is `ro`")
|
| 494 | 494 |
} |
| 495 | 495 |
|
| 496 |
+// Test for GH#10618 |
|
| 497 |
+func TestRunNoDupVolumes(t *testing.T) {
|
|
| 498 |
+ cmd := exec.Command(dockerBinary, "run", "-v", "/etc:/someplace", "-v", "/usr/lib:/someplace", "busybox", "echo", "hi") |
|
| 499 |
+ if out, _, err := runCommandWithOutput(cmd); err == nil {
|
|
| 500 |
+ t.Fatal("Expected error about duplicate volume definitions")
|
|
| 501 |
+ } else {
|
|
| 502 |
+ if !strings.Contains(out, "Duplicate volume") {
|
|
| 503 |
+ t.Fatalf("Expected 'duplicate volume' error, got %v", err)
|
|
| 504 |
+ } |
|
| 505 |
+ } |
|
| 506 |
+ deleteAllContainers() |
|
| 507 |
+ |
|
| 508 |
+ logDone("run - don't allow multiple (bind) volumes on the same container target")
|
|
| 509 |
+} |
|
| 510 |
+ |
|
| 496 | 511 |
// Test for #1351 |
| 497 | 512 |
func TestRunApplyVolumesFromBeforeVolumes(t *testing.T) {
|
| 498 | 513 |
cmd := exec.Command(dockerBinary, "run", "--name", "parent", "-v", "/test", "busybox", "touch", "/test/foo") |