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