lxc_template_unit_test.go 8.6 KB

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