github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/daemon/oci_linux_test.go (about) 1 package daemon // import "github.com/docker/docker/daemon" 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 "testing" 8 9 containertypes "github.com/docker/docker/api/types/container" 10 "github.com/docker/docker/container" 11 "github.com/docker/docker/daemon/config" 12 "github.com/docker/docker/daemon/network" 13 "github.com/docker/docker/pkg/containerfs" 14 "github.com/docker/docker/pkg/idtools" 15 "github.com/docker/libnetwork" 16 "gotest.tools/v3/assert" 17 is "gotest.tools/v3/assert/cmp" 18 ) 19 20 func setupFakeDaemon(t *testing.T, c *container.Container) *Daemon { 21 root, err := ioutil.TempDir("", "oci_linux_test-root") 22 assert.NilError(t, err) 23 24 rootfs := filepath.Join(root, "rootfs") 25 err = os.MkdirAll(rootfs, 0755) 26 assert.NilError(t, err) 27 28 netController, err := libnetwork.New() 29 assert.NilError(t, err) 30 31 d := &Daemon{ 32 // some empty structs to avoid getting a panic 33 // caused by a null pointer dereference 34 idMapping: &idtools.IdentityMapping{}, 35 configStore: &config.Config{}, 36 linkIndex: newLinkIndex(), 37 netController: netController, 38 } 39 40 c.Root = root 41 c.BaseFS = containerfs.NewLocalContainerFS(rootfs) 42 43 if c.Config == nil { 44 c.Config = new(containertypes.Config) 45 } 46 if c.HostConfig == nil { 47 c.HostConfig = new(containertypes.HostConfig) 48 } 49 if c.NetworkSettings == nil { 50 c.NetworkSettings = &network.Settings{Networks: make(map[string]*network.EndpointSettings)} 51 } 52 53 return d 54 } 55 56 func cleanupFakeContainer(c *container.Container) { 57 _ = os.RemoveAll(c.Root) 58 } 59 60 // TestTmpfsDevShmNoDupMount checks that a user-specified /dev/shm tmpfs 61 // mount (as in "docker run --tmpfs /dev/shm:rw,size=NNN") does not result 62 // in "Duplicate mount point" error from the engine. 63 // https://github.com/moby/moby/issues/35455 64 func TestTmpfsDevShmNoDupMount(t *testing.T) { 65 c := &container.Container{ 66 ShmPath: "foobar", // non-empty, for c.IpcMounts() to work 67 HostConfig: &containertypes.HostConfig{ 68 IpcMode: containertypes.IpcMode("shareable"), // default mode 69 // --tmpfs /dev/shm:rw,exec,size=NNN 70 Tmpfs: map[string]string{ 71 "/dev/shm": "rw,exec,size=1g", 72 }, 73 }, 74 } 75 d := setupFakeDaemon(t, c) 76 defer cleanupFakeContainer(c) 77 78 _, err := d.createSpec(c) 79 assert.Check(t, err) 80 } 81 82 // TestIpcPrivateVsReadonly checks that in case of IpcMode: private 83 // and ReadonlyRootfs: true (as in "docker run --ipc private --read-only") 84 // the resulting /dev/shm mount is NOT made read-only. 85 // https://github.com/moby/moby/issues/36503 86 func TestIpcPrivateVsReadonly(t *testing.T) { 87 c := &container.Container{ 88 HostConfig: &containertypes.HostConfig{ 89 IpcMode: containertypes.IpcMode("private"), 90 ReadonlyRootfs: true, 91 }, 92 } 93 d := setupFakeDaemon(t, c) 94 defer cleanupFakeContainer(c) 95 96 s, err := d.createSpec(c) 97 assert.Check(t, err) 98 99 // Find the /dev/shm mount in ms, check it does not have ro 100 for _, m := range s.Mounts { 101 if m.Destination != "/dev/shm" { 102 continue 103 } 104 assert.Check(t, is.Equal(false, inSlice(m.Options, "ro"))) 105 } 106 } 107 108 // TestSysctlOverride ensures that any implicit sysctls (such as 109 // Config.Domainname) are overridden by an explicit sysctl in the HostConfig. 110 func TestSysctlOverride(t *testing.T) { 111 c := &container.Container{ 112 Config: &containertypes.Config{ 113 Hostname: "foobar", 114 Domainname: "baz.cyphar.com", 115 }, 116 HostConfig: &containertypes.HostConfig{ 117 NetworkMode: "bridge", 118 Sysctls: map[string]string{}, 119 UsernsMode: "host", 120 }, 121 } 122 d := setupFakeDaemon(t, c) 123 defer cleanupFakeContainer(c) 124 125 // Ensure that the implicit sysctl is set correctly. 126 s, err := d.createSpec(c) 127 assert.NilError(t, err) 128 assert.Equal(t, s.Hostname, "foobar") 129 assert.Equal(t, s.Linux.Sysctl["kernel.domainname"], c.Config.Domainname) 130 if sysctlExists("net.ipv4.ip_unprivileged_port_start") { 131 assert.Equal(t, s.Linux.Sysctl["net.ipv4.ip_unprivileged_port_start"], "0") 132 } 133 if sysctlExists("net.ipv4.ping_group_range") { 134 assert.Equal(t, s.Linux.Sysctl["net.ipv4.ping_group_range"], "0 2147483647") 135 } 136 137 // Set an explicit sysctl. 138 c.HostConfig.Sysctls["kernel.domainname"] = "foobar.net" 139 assert.Assert(t, c.HostConfig.Sysctls["kernel.domainname"] != c.Config.Domainname) 140 c.HostConfig.Sysctls["net.ipv4.ip_unprivileged_port_start"] = "1024" 141 142 s, err = d.createSpec(c) 143 assert.NilError(t, err) 144 assert.Equal(t, s.Hostname, "foobar") 145 assert.Equal(t, s.Linux.Sysctl["kernel.domainname"], c.HostConfig.Sysctls["kernel.domainname"]) 146 assert.Equal(t, s.Linux.Sysctl["net.ipv4.ip_unprivileged_port_start"], c.HostConfig.Sysctls["net.ipv4.ip_unprivileged_port_start"]) 147 } 148 149 // TestSysctlOverrideHost ensures that any implicit network sysctls are not set 150 // with host networking 151 func TestSysctlOverrideHost(t *testing.T) { 152 c := &container.Container{ 153 Config: &containertypes.Config{}, 154 HostConfig: &containertypes.HostConfig{ 155 NetworkMode: "host", 156 Sysctls: map[string]string{}, 157 UsernsMode: "host", 158 }, 159 } 160 d := setupFakeDaemon(t, c) 161 defer cleanupFakeContainer(c) 162 163 // Ensure that the implicit sysctl is not set 164 s, err := d.createSpec(c) 165 assert.NilError(t, err) 166 assert.Equal(t, s.Linux.Sysctl["net.ipv4.ip_unprivileged_port_start"], "") 167 assert.Equal(t, s.Linux.Sysctl["net.ipv4.ping_group_range"], "") 168 169 // Set an explicit sysctl. 170 c.HostConfig.Sysctls["net.ipv4.ip_unprivileged_port_start"] = "1024" 171 172 s, err = d.createSpec(c) 173 assert.NilError(t, err) 174 assert.Equal(t, s.Linux.Sysctl["net.ipv4.ip_unprivileged_port_start"], c.HostConfig.Sysctls["net.ipv4.ip_unprivileged_port_start"]) 175 } 176 177 func TestGetSourceMount(t *testing.T) { 178 // must be able to find source mount for / 179 mnt, _, err := getSourceMount("/") 180 assert.NilError(t, err) 181 assert.Equal(t, mnt, "/") 182 183 // must be able to find source mount for current directory 184 cwd, err := os.Getwd() 185 assert.NilError(t, err) 186 _, _, err = getSourceMount(cwd) 187 assert.NilError(t, err) 188 }