Docker-DCO-1.1-Signed-off-by: Tibor Vass <teabee89@gmail.com> (github: tiborvass)
| ... | ... |
@@ -217,15 +217,26 @@ func createVolumes(container *Container) error {
|
| 217 | 217 |
srcPath = p |
| 218 | 218 |
} |
| 219 | 219 |
|
| 220 |
- container.Volumes[volPath] = srcPath |
|
| 221 |
- container.VolumesRW[volPath] = srcRW |
|
| 222 |
- |
|
| 223 | 220 |
// Create the mountpoint |
| 224 |
- volPath = filepath.Join(container.basefs, volPath) |
|
| 225 |
- rootVolPath, err := utils.FollowSymlinkInScope(volPath, container.basefs) |
|
| 221 |
+ rootVolPath, err := utils.FollowSymlinkInScope(filepath.Join(container.basefs, volPath), container.basefs) |
|
| 222 |
+ if err != nil {
|
|
| 223 |
+ return err |
|
| 224 |
+ } |
|
| 225 |
+ |
|
| 226 |
+ newVolPath, err := filepath.Rel(container.basefs, rootVolPath) |
|
| 226 | 227 |
if err != nil {
|
| 227 | 228 |
return err |
| 228 | 229 |
} |
| 230 |
+ newVolPath = "/" + newVolPath |
|
| 231 |
+ |
|
| 232 |
+ if volPath != newVolPath {
|
|
| 233 |
+ delete(container.Volumes, volPath) |
|
| 234 |
+ delete(container.VolumesRW, volPath) |
|
| 235 |
+ } |
|
| 236 |
+ |
|
| 237 |
+ container.Volumes[newVolPath] = srcPath |
|
| 238 |
+ container.VolumesRW[newVolPath] = srcRW |
|
| 239 |
+ |
|
| 229 | 240 |
if err := createIfNotExists(rootVolPath, volIsDir); err != nil {
|
| 230 | 241 |
return err |
| 231 | 242 |
} |
| ... | ... |
@@ -4,6 +4,7 @@ import ( |
| 4 | 4 |
"fmt" |
| 5 | 5 |
"os" |
| 6 | 6 |
"os/exec" |
| 7 |
+ "path/filepath" |
|
| 7 | 8 |
"regexp" |
| 8 | 9 |
"sort" |
| 9 | 10 |
"strings" |
| ... | ... |
@@ -424,6 +425,48 @@ func TestCreateVolume(t *testing.T) {
|
| 424 | 424 |
logDone("run - create docker mangaed volume")
|
| 425 | 425 |
} |
| 426 | 426 |
|
| 427 |
+// Test that creating a volume with a symlink in its path works correctly. Test for #5152. |
|
| 428 |
+// Note that this bug happens only with symlinks with a target that starts with '/'. |
|
| 429 |
+func TestVolumeWithSymlink(t *testing.T) {
|
|
| 430 |
+ buildDirectory := filepath.Join(workingDirectory, "run_tests", "TestVolumeWithSymlink") |
|
| 431 |
+ buildCmd := exec.Command(dockerBinary, "build", "-t", "docker-test-volumewithsymlink", ".") |
|
| 432 |
+ buildCmd.Dir = buildDirectory |
|
| 433 |
+ err := buildCmd.Run() |
|
| 434 |
+ if err != nil {
|
|
| 435 |
+ t.Fatal("could not build 'docker-test-volumewithsymlink': %v", err)
|
|
| 436 |
+ } |
|
| 437 |
+ |
|
| 438 |
+ cmd := exec.Command(dockerBinary, "run", "-v", "/bar/foo", "--name", "test-volumewithsymlink", "docker-test-volumewithsymlink", "sh", "-c", "mount | grep -q /foo/foo") |
|
| 439 |
+ exitCode, err := runCommand(cmd) |
|
| 440 |
+ if err != nil || exitCode != 0 {
|
|
| 441 |
+ t.Fatal("[run] err: %v, exitcode: %d", err, exitCode)
|
|
| 442 |
+ } |
|
| 443 |
+ |
|
| 444 |
+ var volPath string |
|
| 445 |
+ cmd = exec.Command(dockerBinary, "inspect", "-f", "{{range .Volumes}}{{.}}{{end}}", "test-volumewithsymlink")
|
|
| 446 |
+ volPath, exitCode, err = runCommandWithOutput(cmd) |
|
| 447 |
+ if err != nil || exitCode != 0 {
|
|
| 448 |
+ t.Fatal("[inspect] err: %v, exitcode: %d", err, exitCode)
|
|
| 449 |
+ } |
|
| 450 |
+ |
|
| 451 |
+ cmd = exec.Command(dockerBinary, "rm", "-v", "test-volumewithsymlink") |
|
| 452 |
+ exitCode, err = runCommand(cmd) |
|
| 453 |
+ if err != nil || exitCode != 0 {
|
|
| 454 |
+ t.Fatal("[rm] err: %v, exitcode: %d", err, exitCode)
|
|
| 455 |
+ } |
|
| 456 |
+ |
|
| 457 |
+ f, err := os.Open(volPath) |
|
| 458 |
+ defer f.Close() |
|
| 459 |
+ if !os.IsNotExist(err) {
|
|
| 460 |
+ t.Fatal("[open] (expecting 'file does not exist' error) err: %v, volPath: %s", err, volPath)
|
|
| 461 |
+ } |
|
| 462 |
+ |
|
| 463 |
+ deleteImages("docker-test-volumewithsymlink")
|
|
| 464 |
+ deleteAllContainers() |
|
| 465 |
+ |
|
| 466 |
+ logDone("run - volume with symlink")
|
|
| 467 |
+} |
|
| 468 |
+ |
|
| 427 | 469 |
func TestExitCode(t *testing.T) {
|
| 428 | 470 |
cmd := exec.Command(dockerBinary, "run", "busybox", "/bin/sh", "-c", "exit 72") |
| 429 | 471 |
|