github.com/pritambaral/docker@v1.4.2-0.20150120174542-b2fe1b3dd952/daemon/execdriver/lxc/lxc_template_unit_test.go (about) 1 // +build linux 2 3 package lxc 4 5 import ( 6 "bufio" 7 "fmt" 8 "github.com/docker/docker/daemon/execdriver" 9 nativeTemplate "github.com/docker/docker/daemon/execdriver/native/template" 10 "github.com/docker/libcontainer/devices" 11 "github.com/docker/libcontainer/security/capabilities" 12 "github.com/syndtr/gocapability/capability" 13 "io/ioutil" 14 "math/rand" 15 "os" 16 "path" 17 "strings" 18 "testing" 19 "time" 20 ) 21 22 func TestLXCConfig(t *testing.T) { 23 root, err := ioutil.TempDir("", "TestLXCConfig") 24 if err != nil { 25 t.Fatal(err) 26 } 27 defer os.RemoveAll(root) 28 29 os.MkdirAll(path.Join(root, "containers", "1"), 0777) 30 31 // Memory is allocated randomly for testing 32 rand.Seed(time.Now().UTC().UnixNano()) 33 var ( 34 memMin = 33554432 35 memMax = 536870912 36 mem = memMin + rand.Intn(memMax-memMin) 37 cpuMin = 100 38 cpuMax = 10000 39 cpu = cpuMin + rand.Intn(cpuMax-cpuMin) 40 ) 41 42 driver, err := NewDriver(root, "", false) 43 if err != nil { 44 t.Fatal(err) 45 } 46 command := &execdriver.Command{ 47 ID: "1", 48 Resources: &execdriver.Resources{ 49 Memory: int64(mem), 50 CpuShares: int64(cpu), 51 }, 52 Network: &execdriver.Network{ 53 Mtu: 1500, 54 Interface: nil, 55 }, 56 AllowedDevices: make([]*devices.Device, 0), 57 ProcessConfig: execdriver.ProcessConfig{}, 58 } 59 p, err := driver.generateLXCConfig(command) 60 if err != nil { 61 t.Fatal(err) 62 } 63 grepFile(t, p, 64 fmt.Sprintf("lxc.cgroup.memory.limit_in_bytes = %d", mem)) 65 66 grepFile(t, p, 67 fmt.Sprintf("lxc.cgroup.memory.memsw.limit_in_bytes = %d", mem*2)) 68 } 69 70 func TestCustomLxcConfig(t *testing.T) { 71 root, err := ioutil.TempDir("", "TestCustomLxcConfig") 72 if err != nil { 73 t.Fatal(err) 74 } 75 defer os.RemoveAll(root) 76 77 os.MkdirAll(path.Join(root, "containers", "1"), 0777) 78 79 driver, err := NewDriver(root, "", false) 80 if err != nil { 81 t.Fatal(err) 82 } 83 processConfig := execdriver.ProcessConfig{ 84 Privileged: false, 85 } 86 command := &execdriver.Command{ 87 ID: "1", 88 LxcConfig: []string{ 89 "lxc.utsname = docker", 90 "lxc.cgroup.cpuset.cpus = 0,1", 91 }, 92 Network: &execdriver.Network{ 93 Mtu: 1500, 94 Interface: nil, 95 }, 96 ProcessConfig: processConfig, 97 } 98 99 p, err := driver.generateLXCConfig(command) 100 if err != nil { 101 t.Fatal(err) 102 } 103 104 grepFile(t, p, "lxc.utsname = docker") 105 grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1") 106 } 107 108 func grepFile(t *testing.T, path string, pattern string) { 109 grepFileWithReverse(t, path, pattern, false) 110 } 111 112 func grepFileWithReverse(t *testing.T, path string, pattern string, inverseGrep bool) { 113 f, err := os.Open(path) 114 if err != nil { 115 t.Fatal(err) 116 } 117 defer f.Close() 118 r := bufio.NewReader(f) 119 var ( 120 line string 121 ) 122 err = nil 123 for err == nil { 124 line, err = r.ReadString('\n') 125 if strings.Contains(line, pattern) == true { 126 if inverseGrep { 127 t.Fatalf("grepFile: pattern \"%s\" found in \"%s\"", pattern, path) 128 } 129 return 130 } 131 } 132 if inverseGrep { 133 return 134 } 135 t.Fatalf("grepFile: pattern \"%s\" not found in \"%s\"", pattern, path) 136 } 137 138 func TestEscapeFstabSpaces(t *testing.T) { 139 var testInputs = map[string]string{ 140 " ": "\\040", 141 "": "", 142 "/double space": "/double\\040\\040space", 143 "/some long test string": "/some\\040long\\040test\\040string", 144 "/var/lib/docker": "/var/lib/docker", 145 " leading": "\\040leading", 146 "trailing ": "trailing\\040", 147 } 148 for in, exp := range testInputs { 149 if out := escapeFstabSpaces(in); exp != out { 150 t.Logf("Expected %s got %s", exp, out) 151 t.Fail() 152 } 153 } 154 } 155 156 func TestIsDirectory(t *testing.T) { 157 tempDir, err := ioutil.TempDir("", "TestIsDir") 158 if err != nil { 159 t.Fatal(err) 160 } 161 defer os.RemoveAll(tempDir) 162 163 tempFile, err := ioutil.TempFile(tempDir, "TestIsDirFile") 164 if err != nil { 165 t.Fatal(err) 166 } 167 168 if isDirectory(tempDir) != "dir" { 169 t.Logf("Could not identify %s as a directory", tempDir) 170 t.Fail() 171 } 172 173 if isDirectory(tempFile.Name()) != "file" { 174 t.Logf("Could not identify %s as a file", tempFile.Name()) 175 t.Fail() 176 } 177 } 178 179 func TestCustomLxcConfigMounts(t *testing.T) { 180 root, err := ioutil.TempDir("", "TestCustomLxcConfig") 181 if err != nil { 182 t.Fatal(err) 183 } 184 defer os.RemoveAll(root) 185 tempDir, err := ioutil.TempDir("", "TestIsDir") 186 if err != nil { 187 t.Fatal(err) 188 } 189 defer os.RemoveAll(tempDir) 190 191 tempFile, err := ioutil.TempFile(tempDir, "TestIsDirFile") 192 if err != nil { 193 t.Fatal(err) 194 } 195 os.MkdirAll(path.Join(root, "containers", "1"), 0777) 196 197 driver, err := NewDriver(root, "", false) 198 if err != nil { 199 t.Fatal(err) 200 } 201 processConfig := execdriver.ProcessConfig{ 202 Privileged: false, 203 } 204 mounts := []execdriver.Mount{ 205 { 206 Source: tempDir, 207 Destination: tempDir, 208 Writable: false, 209 Private: true, 210 }, 211 { 212 Source: tempFile.Name(), 213 Destination: tempFile.Name(), 214 Writable: true, 215 Private: true, 216 }, 217 } 218 command := &execdriver.Command{ 219 ID: "1", 220 LxcConfig: []string{ 221 "lxc.utsname = docker", 222 "lxc.cgroup.cpuset.cpus = 0,1", 223 }, 224 Network: &execdriver.Network{ 225 Mtu: 1500, 226 Interface: nil, 227 }, 228 Mounts: mounts, 229 ProcessConfig: processConfig, 230 } 231 232 p, err := driver.generateLXCConfig(command) 233 if err != nil { 234 t.Fatal(err) 235 } 236 237 grepFile(t, p, "lxc.utsname = docker") 238 grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1") 239 240 grepFile(t, p, fmt.Sprintf("lxc.mount.entry = %s %s none rbind,ro,create=%s 0 0", tempDir, "/"+tempDir, "dir")) 241 grepFile(t, p, fmt.Sprintf("lxc.mount.entry = %s %s none rbind,rw,create=%s 0 0", tempFile.Name(), "/"+tempFile.Name(), "file")) 242 } 243 244 func TestCustomLxcConfigMisc(t *testing.T) { 245 root, err := ioutil.TempDir("", "TestCustomLxcConfig") 246 if err != nil { 247 t.Fatal(err) 248 } 249 defer os.RemoveAll(root) 250 os.MkdirAll(path.Join(root, "containers", "1"), 0777) 251 driver, err := NewDriver(root, "", false) 252 if err != nil { 253 t.Fatal(err) 254 } 255 processConfig := execdriver.ProcessConfig{ 256 Privileged: false, 257 } 258 259 processConfig.Env = []string{"HOSTNAME=testhost"} 260 command := &execdriver.Command{ 261 ID: "1", 262 LxcConfig: []string{ 263 "lxc.cgroup.cpuset.cpus = 0,1", 264 }, 265 Network: &execdriver.Network{ 266 Mtu: 1500, 267 Interface: &execdriver.NetworkInterface{ 268 Gateway: "10.10.10.1", 269 IPAddress: "10.10.10.10", 270 IPPrefixLen: 24, 271 Bridge: "docker0", 272 }, 273 }, 274 ProcessConfig: processConfig, 275 CapAdd: []string{"net_admin", "syslog"}, 276 CapDrop: []string{"kill", "mknod"}, 277 } 278 279 p, err := driver.generateLXCConfig(command) 280 if err != nil { 281 t.Fatal(err) 282 } 283 // network 284 grepFile(t, p, "lxc.network.type = veth") 285 grepFile(t, p, "lxc.network.link = docker0") 286 grepFile(t, p, "lxc.network.name = eth0") 287 grepFile(t, p, "lxc.network.ipv4 = 10.10.10.10/24") 288 grepFile(t, p, "lxc.network.ipv4.gateway = 10.10.10.1") 289 grepFile(t, p, "lxc.network.flags = up") 290 291 // hostname 292 grepFile(t, p, "lxc.utsname = testhost") 293 grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1") 294 container := nativeTemplate.New() 295 for _, cap := range container.Capabilities { 296 realCap := capabilities.GetCapability(cap) 297 numCap := fmt.Sprintf("%d", realCap.Value) 298 if cap != "MKNOD" && cap != "KILL" { 299 grepFile(t, p, fmt.Sprintf("lxc.cap.keep = %s", numCap)) 300 } 301 } 302 303 grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = %d", capability.CAP_KILL), true) 304 grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = %d", capability.CAP_MKNOD), true) 305 } 306 307 func TestCustomLxcConfigMiscOverride(t *testing.T) { 308 root, err := ioutil.TempDir("", "TestCustomLxcConfig") 309 if err != nil { 310 t.Fatal(err) 311 } 312 defer os.RemoveAll(root) 313 os.MkdirAll(path.Join(root, "containers", "1"), 0777) 314 driver, err := NewDriver(root, "", false) 315 if err != nil { 316 t.Fatal(err) 317 } 318 processConfig := execdriver.ProcessConfig{ 319 Privileged: false, 320 } 321 322 processConfig.Env = []string{"HOSTNAME=testhost"} 323 command := &execdriver.Command{ 324 ID: "1", 325 LxcConfig: []string{ 326 "lxc.cgroup.cpuset.cpus = 0,1", 327 "lxc.network.ipv4 = 172.0.0.1", 328 }, 329 Network: &execdriver.Network{ 330 Mtu: 1500, 331 Interface: &execdriver.NetworkInterface{ 332 Gateway: "10.10.10.1", 333 IPAddress: "10.10.10.10", 334 IPPrefixLen: 24, 335 Bridge: "docker0", 336 }, 337 }, 338 ProcessConfig: processConfig, 339 CapAdd: []string{"NET_ADMIN", "SYSLOG"}, 340 CapDrop: []string{"KILL", "MKNOD"}, 341 } 342 343 p, err := driver.generateLXCConfig(command) 344 if err != nil { 345 t.Fatal(err) 346 } 347 // network 348 grepFile(t, p, "lxc.network.type = veth") 349 grepFile(t, p, "lxc.network.link = docker0") 350 grepFile(t, p, "lxc.network.name = eth0") 351 grepFile(t, p, "lxc.network.ipv4 = 172.0.0.1") 352 grepFile(t, p, "lxc.network.ipv4.gateway = 10.10.10.1") 353 grepFile(t, p, "lxc.network.flags = up") 354 355 // hostname 356 grepFile(t, p, "lxc.utsname = testhost") 357 grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1") 358 container := nativeTemplate.New() 359 for _, cap := range container.Capabilities { 360 realCap := capabilities.GetCapability(cap) 361 numCap := fmt.Sprintf("%d", realCap.Value) 362 if cap != "MKNOD" && cap != "KILL" { 363 grepFile(t, p, fmt.Sprintf("lxc.cap.keep = %s", numCap)) 364 } 365 } 366 grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = %d", capability.CAP_KILL), true) 367 grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = %d", capability.CAP_MKNOD), true) 368 }