package daemon // import "github.com/docker/docker/daemon" import ( "os" "testing" containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/container" "github.com/docker/docker/daemon/config" "github.com/docker/docker/oci" "github.com/docker/docker/pkg/idtools" "gotest.tools/assert" is "gotest.tools/assert/cmp" ) // TestTmpfsDevShmNoDupMount checks that a user-specified /dev/shm tmpfs // mount (as in "docker run --tmpfs /dev/shm:rw,size=NNN") does not result // in "Duplicate mount point" error from the engine. // https://github.com/moby/moby/issues/35455 func TestTmpfsDevShmNoDupMount(t *testing.T) { d := Daemon{ // some empty structs to avoid getting a panic // caused by a null pointer dereference idMapping: &idtools.IdentityMapping{}, configStore: &config.Config{}, } c := &container.Container{ ShmPath: "foobar", // non-empty, for c.IpcMounts() to work HostConfig: &containertypes.HostConfig{ IpcMode: containertypes.IpcMode("shareable"), // default mode // --tmpfs /dev/shm:rw,exec,size=NNN Tmpfs: map[string]string{ "/dev/shm": "rw,exec,size=1g", }, }, } // Mimick the code flow of daemon.createSpec(), enough to reproduce the issue ms, err := d.setupMounts(c) assert.Check(t, err) ms = append(ms, c.IpcMounts()...) tmpfsMounts, err := c.TmpfsMounts() assert.Check(t, err) ms = append(ms, tmpfsMounts...) s := oci.DefaultSpec() err = setMounts(&d, &s, c, ms) assert.Check(t, err) } // TestIpcPrivateVsReadonly checks that in case of IpcMode: private // and ReadonlyRootfs: true (as in "docker run --ipc private --read-only") // the resulting /dev/shm mount is NOT made read-only. // https://github.com/moby/moby/issues/36503 func TestIpcPrivateVsReadonly(t *testing.T) { d := Daemon{ // some empty structs to avoid getting a panic // caused by a null pointer dereference idMapping: &idtools.IdentityMapping{}, configStore: &config.Config{}, } c := &container.Container{ HostConfig: &containertypes.HostConfig{ IpcMode: containertypes.IpcMode("private"), ReadonlyRootfs: true, }, } // We can't call createSpec() so mimick the minimal part // of its code flow, just enough to reproduce the issue. ms, err := d.setupMounts(c) assert.Check(t, err) s := oci.DefaultSpec() s.Root.Readonly = c.HostConfig.ReadonlyRootfs err = setMounts(&d, &s, c, ms) assert.Check(t, err) // Find the /dev/shm mount in ms, check it does not have ro for _, m := range s.Mounts { if m.Destination != "/dev/shm" { continue } assert.Check(t, is.Equal(false, inSlice(m.Options, "ro"))) } } func TestGetSourceMount(t *testing.T) { // must be able to find source mount for / mnt, _, err := getSourceMount("/") assert.NilError(t, err) assert.Equal(t, mnt, "/") // must be able to find source mount for current directory cwd, err := os.Getwd() assert.NilError(t, err) _, _, err = getSourceMount(cwd) assert.NilError(t, err) }