github.com/adityamillind98/moby@v23.0.0-rc.4+incompatible/daemon/oci_linux_test.go (about) 1 package daemon // import "github.com/docker/docker/daemon" 2 3 import ( 4 "os" 5 "path/filepath" 6 "testing" 7 8 containertypes "github.com/docker/docker/api/types/container" 9 "github.com/docker/docker/container" 10 "github.com/docker/docker/daemon/config" 11 "github.com/docker/docker/daemon/network" 12 "github.com/docker/docker/libnetwork" 13 "github.com/docker/docker/pkg/containerfs" 14 "gotest.tools/v3/assert" 15 is "gotest.tools/v3/assert/cmp" 16 "gotest.tools/v3/skip" 17 ) 18 19 func setupFakeDaemon(t *testing.T, c *container.Container) *Daemon { 20 root, err := os.MkdirTemp("", "oci_linux_test-root") 21 assert.NilError(t, err) 22 23 rootfs := filepath.Join(root, "rootfs") 24 err = os.MkdirAll(rootfs, 0755) 25 assert.NilError(t, err) 26 27 netController, err := libnetwork.New() 28 assert.NilError(t, err) 29 30 d := &Daemon{ 31 // some empty structs to avoid getting a panic 32 // caused by a null pointer dereference 33 configStore: &config.Config{}, 34 linkIndex: newLinkIndex(), 35 netController: netController, 36 } 37 38 c.Root = root 39 c.BaseFS = containerfs.NewLocalContainerFS(rootfs) 40 41 if c.Config == nil { 42 c.Config = new(containertypes.Config) 43 } 44 if c.HostConfig == nil { 45 c.HostConfig = new(containertypes.HostConfig) 46 } 47 if c.NetworkSettings == nil { 48 c.NetworkSettings = &network.Settings{Networks: make(map[string]*network.EndpointSettings)} 49 } 50 51 return d 52 } 53 54 func cleanupFakeContainer(c *container.Container) { 55 _ = os.RemoveAll(c.Root) 56 } 57 58 // TestTmpfsDevShmNoDupMount checks that a user-specified /dev/shm tmpfs 59 // mount (as in "docker run --tmpfs /dev/shm:rw,size=NNN") does not result 60 // in "Duplicate mount point" error from the engine. 61 // https://github.com/moby/moby/issues/35455 62 func TestTmpfsDevShmNoDupMount(t *testing.T) { 63 skip.If(t, os.Getuid() != 0, "skipping test that requires root") 64 c := &container.Container{ 65 ShmPath: "foobar", // non-empty, for c.IpcMounts() to work 66 HostConfig: &containertypes.HostConfig{ 67 IpcMode: containertypes.IPCModeShareable, // default mode 68 // --tmpfs /dev/shm:rw,exec,size=NNN 69 Tmpfs: map[string]string{ 70 "/dev/shm": "rw,exec,size=1g", 71 }, 72 }, 73 } 74 d := setupFakeDaemon(t, c) 75 defer cleanupFakeContainer(c) 76 77 _, err := d.createSpec(c) 78 assert.Check(t, err) 79 } 80 81 // TestIpcPrivateVsReadonly checks that in case of IpcMode: private 82 // and ReadonlyRootfs: true (as in "docker run --ipc private --read-only") 83 // the resulting /dev/shm mount is NOT made read-only. 84 // https://github.com/moby/moby/issues/36503 85 func TestIpcPrivateVsReadonly(t *testing.T) { 86 skip.If(t, os.Getuid() != 0, "skipping test that requires root") 87 c := &container.Container{ 88 HostConfig: &containertypes.HostConfig{ 89 IpcMode: containertypes.IPCModePrivate, 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 skip.If(t, os.Getuid() != 0, "skipping test that requires root") 112 c := &container.Container{ 113 Config: &containertypes.Config{ 114 Hostname: "foobar", 115 Domainname: "baz.cyphar.com", 116 }, 117 HostConfig: &containertypes.HostConfig{ 118 NetworkMode: "bridge", 119 Sysctls: map[string]string{}, 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 // Ensure the ping_group_range is not set on a daemon with user-namespaces enabled 149 d.configStore.RemappedRoot = "dummy:dummy" 150 s, err = d.createSpec(c) 151 assert.NilError(t, err) 152 _, ok := s.Linux.Sysctl["net.ipv4.ping_group_range"] 153 assert.Assert(t, !ok) 154 155 // Ensure the ping_group_range is set on a container in "host" userns mode 156 // on a daemon with user-namespaces enabled 157 c.HostConfig.UsernsMode = "host" 158 s, err = d.createSpec(c) 159 assert.NilError(t, err) 160 assert.Equal(t, s.Linux.Sysctl["net.ipv4.ping_group_range"], "0 2147483647") 161 } 162 163 // TestSysctlOverrideHost ensures that any implicit network sysctls are not set 164 // with host networking 165 func TestSysctlOverrideHost(t *testing.T) { 166 skip.If(t, os.Getuid() != 0, "skipping test that requires root") 167 c := &container.Container{ 168 Config: &containertypes.Config{}, 169 HostConfig: &containertypes.HostConfig{ 170 NetworkMode: "host", 171 Sysctls: map[string]string{}, 172 }, 173 } 174 d := setupFakeDaemon(t, c) 175 defer cleanupFakeContainer(c) 176 177 // Ensure that the implicit sysctl is not set 178 s, err := d.createSpec(c) 179 assert.NilError(t, err) 180 assert.Equal(t, s.Linux.Sysctl["net.ipv4.ip_unprivileged_port_start"], "") 181 assert.Equal(t, s.Linux.Sysctl["net.ipv4.ping_group_range"], "") 182 183 // Set an explicit sysctl. 184 c.HostConfig.Sysctls["net.ipv4.ip_unprivileged_port_start"] = "1024" 185 186 s, err = d.createSpec(c) 187 assert.NilError(t, err) 188 assert.Equal(t, s.Linux.Sysctl["net.ipv4.ip_unprivileged_port_start"], c.HostConfig.Sysctls["net.ipv4.ip_unprivileged_port_start"]) 189 } 190 191 func TestGetSourceMount(t *testing.T) { 192 // must be able to find source mount for / 193 mnt, _, err := getSourceMount("/") 194 assert.NilError(t, err) 195 assert.Equal(t, mnt, "/") 196 197 // must be able to find source mount for current directory 198 cwd, err := os.Getwd() 199 assert.NilError(t, err) 200 _, _, err = getSourceMount(cwd) 201 assert.NilError(t, err) 202 }