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