Fix #7792 - Order mounts
Docker-DCO-1.1-Signed-off-by: Brian Goff <cpuguy83@gmail.com> (github: cpuguy83)
This commit is contained in:
parent
51b26853ef
commit
0a3211f131
2 changed files with 59 additions and 5 deletions
|
@ -5,6 +5,7 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
|
@ -73,19 +74,30 @@ func setupMountsForContainer(container *Container) error {
|
|||
// Note, these are not private because you may want propagation of (un)mounts from host
|
||||
// volumes. For instance if you use -v /usr:/usr and the host later mounts /usr/share you
|
||||
// want this new mount in the container
|
||||
for r, v := range container.Volumes {
|
||||
// These mounts must be ordered based on the length of the path that it is being mounted to (lexicographic)
|
||||
for _, path := range container.sortedVolumeMounts() {
|
||||
mounts = append(mounts, execdriver.Mount{
|
||||
Source: v,
|
||||
Destination: r,
|
||||
Writable: container.VolumesRW[r],
|
||||
Source: container.Volumes[path],
|
||||
Destination: path,
|
||||
Writable: container.VolumesRW[path],
|
||||
})
|
||||
}
|
||||
|
||||
container.command.Mounts = mounts
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// sortedVolumeMounts returns the list of container volume mount points sorted in lexicographic order
|
||||
func (container *Container) sortedVolumeMounts() []string {
|
||||
var mountPaths []string
|
||||
for path := range container.Volumes {
|
||||
mountPaths = append(mountPaths, path)
|
||||
}
|
||||
|
||||
sort.Strings(mountPaths)
|
||||
return mountPaths
|
||||
}
|
||||
|
||||
func parseVolumesFromSpec(container *Container, spec string) (map[string]*Volume, error) {
|
||||
specParts := strings.SplitN(spec, ":", 2)
|
||||
if len(specParts) == 0 {
|
||||
|
|
|
@ -2069,3 +2069,45 @@ func TestDockerExecInteractive(t *testing.T) {
|
|||
|
||||
logDone("exec - Interactive test")
|
||||
}
|
||||
|
||||
// Regression test for #7792
|
||||
func TestMountOrdering(t *testing.T) {
|
||||
tmpDir, err := ioutil.TempDir("", "docker_nested_mount_test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
tmpDir2, err := ioutil.TempDir("", "docker_nested_mount_test2")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir2)
|
||||
|
||||
// Create a temporary tmpfs mount.
|
||||
fooDir := filepath.Join(tmpDir, "foo")
|
||||
if err := os.MkdirAll(filepath.Join(tmpDir, "foo"), 0755); err != nil {
|
||||
t.Fatalf("failed to mkdir at %s - %s", fooDir, err)
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(fmt.Sprintf("%s/touch-me", fooDir), []byte{}, 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(fmt.Sprintf("%s/touch-me", tmpDir), []byte{}, 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(fmt.Sprintf("%s/touch-me", tmpDir2), []byte{}, 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cmd := exec.Command(dockerBinary, "run", "-v", fmt.Sprintf("%s:/tmp", tmpDir), "-v", fmt.Sprintf("%s:/tmp/foo", fooDir), "-v", fmt.Sprintf("%s:/tmp/tmp2", tmpDir2), "-v", fmt.Sprintf("%s:/tmp/tmp2/foo", fooDir), "busybox:latest", "sh", "-c", "ls /tmp/touch-me && ls /tmp/foo/touch-me && ls /tmp/tmp2/touch-me && ls /tmp/tmp2/foo/touch-me")
|
||||
out, _, err := runCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
t.Fatal(out, err)
|
||||
}
|
||||
|
||||
deleteAllContainers()
|
||||
logDone("run - volumes are mounted in the correct order")
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue