docker_cli_daemon_test.go 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932
  1. // +build daemon
  2. package main
  3. import (
  4. "encoding/json"
  5. "fmt"
  6. "io/ioutil"
  7. "net"
  8. "os"
  9. "os/exec"
  10. "path/filepath"
  11. "strings"
  12. "time"
  13. "github.com/docker/libtrust"
  14. "github.com/go-check/check"
  15. )
  16. func (s *DockerDaemonSuite) TestDaemonRestartWithRunningContainersPorts(c *check.C) {
  17. if err := s.d.StartWithBusybox(); err != nil {
  18. c.Fatalf("Could not start daemon with busybox: %v", err)
  19. }
  20. if out, err := s.d.Cmd("run", "-d", "--name", "top1", "-p", "1234:80", "--restart", "always", "busybox:latest", "top"); err != nil {
  21. c.Fatalf("Could not run top1: err=%v\n%s", err, out)
  22. }
  23. // --restart=no by default
  24. if out, err := s.d.Cmd("run", "-d", "--name", "top2", "-p", "80", "busybox:latest", "top"); err != nil {
  25. c.Fatalf("Could not run top2: err=%v\n%s", err, out)
  26. }
  27. testRun := func(m map[string]bool, prefix string) {
  28. var format string
  29. for cont, shouldRun := range m {
  30. out, err := s.d.Cmd("ps")
  31. if err != nil {
  32. c.Fatalf("Could not run ps: err=%v\n%q", err, out)
  33. }
  34. if shouldRun {
  35. format = "%scontainer %q is not running"
  36. } else {
  37. format = "%scontainer %q is running"
  38. }
  39. if shouldRun != strings.Contains(out, cont) {
  40. c.Fatalf(format, prefix, cont)
  41. }
  42. }
  43. }
  44. testRun(map[string]bool{"top1": true, "top2": true}, "")
  45. if err := s.d.Restart(); err != nil {
  46. c.Fatalf("Could not restart daemon: %v", err)
  47. }
  48. testRun(map[string]bool{"top1": true, "top2": false}, "After daemon restart: ")
  49. }
  50. func (s *DockerDaemonSuite) TestDaemonRestartWithVolumesRefs(c *check.C) {
  51. if err := s.d.StartWithBusybox(); err != nil {
  52. c.Fatal(err)
  53. }
  54. if out, err := s.d.Cmd("run", "-d", "--name", "volrestarttest1", "-v", "/foo", "busybox"); err != nil {
  55. c.Fatal(err, out)
  56. }
  57. if err := s.d.Restart(); err != nil {
  58. c.Fatal(err)
  59. }
  60. if _, err := s.d.Cmd("run", "-d", "--volumes-from", "volrestarttest1", "--name", "volrestarttest2", "busybox", "top"); err != nil {
  61. c.Fatal(err)
  62. }
  63. if out, err := s.d.Cmd("rm", "-fv", "volrestarttest2"); err != nil {
  64. c.Fatal(err, out)
  65. }
  66. v, err := s.d.Cmd("inspect", "--format", "{{ json .Volumes }}", "volrestarttest1")
  67. if err != nil {
  68. c.Fatal(err)
  69. }
  70. volumes := make(map[string]string)
  71. json.Unmarshal([]byte(v), &volumes)
  72. if _, err := os.Stat(volumes["/foo"]); err != nil {
  73. c.Fatalf("Expected volume to exist: %s - %s", volumes["/foo"], err)
  74. }
  75. }
  76. func (s *DockerDaemonSuite) TestDaemonStartIptablesFalse(c *check.C) {
  77. if err := s.d.Start("--iptables=false"); err != nil {
  78. c.Fatalf("we should have been able to start the daemon with passing iptables=false: %v", err)
  79. }
  80. }
  81. // Issue #8444: If docker0 bridge is modified (intentionally or unintentionally) and
  82. // no longer has an IP associated, we should gracefully handle that case and associate
  83. // an IP with it rather than fail daemon start
  84. func (s *DockerDaemonSuite) TestDaemonStartBridgeWithoutIPAssociation(c *check.C) {
  85. // rather than depending on brctl commands to verify docker0 is created and up
  86. // let's start the daemon and stop it, and then make a modification to run the
  87. // actual test
  88. if err := s.d.Start(); err != nil {
  89. c.Fatalf("Could not start daemon: %v", err)
  90. }
  91. if err := s.d.Stop(); err != nil {
  92. c.Fatalf("Could not stop daemon: %v", err)
  93. }
  94. // now we will remove the ip from docker0 and then try starting the daemon
  95. ipCmd := exec.Command("ip", "addr", "flush", "dev", "docker0")
  96. stdout, stderr, _, err := runCommandWithStdoutStderr(ipCmd)
  97. if err != nil {
  98. c.Fatalf("failed to remove docker0 IP association: %v, stdout: %q, stderr: %q", err, stdout, stderr)
  99. }
  100. if err := s.d.Start(); err != nil {
  101. warning := "**WARNING: Docker bridge network in bad state--delete docker0 bridge interface to fix"
  102. c.Fatalf("Could not start daemon when docker0 has no IP address: %v\n%s", err, warning)
  103. }
  104. }
  105. func (s *DockerDaemonSuite) TestDaemonIptablesClean(c *check.C) {
  106. if err := s.d.StartWithBusybox(); err != nil {
  107. c.Fatalf("Could not start daemon with busybox: %v", err)
  108. }
  109. if out, err := s.d.Cmd("run", "-d", "--name", "top", "-p", "80", "busybox:latest", "top"); err != nil {
  110. c.Fatalf("Could not run top: %s, %v", out, err)
  111. }
  112. // get output from iptables with container running
  113. ipTablesSearchString := "tcp dpt:80"
  114. ipTablesCmd := exec.Command("iptables", "-nvL")
  115. out, _, err := runCommandWithOutput(ipTablesCmd)
  116. if err != nil {
  117. c.Fatalf("Could not run iptables -nvL: %s, %v", out, err)
  118. }
  119. if !strings.Contains(out, ipTablesSearchString) {
  120. c.Fatalf("iptables output should have contained %q, but was %q", ipTablesSearchString, out)
  121. }
  122. if err := s.d.Stop(); err != nil {
  123. c.Fatalf("Could not stop daemon: %v", err)
  124. }
  125. // get output from iptables after restart
  126. ipTablesCmd = exec.Command("iptables", "-nvL")
  127. out, _, err = runCommandWithOutput(ipTablesCmd)
  128. if err != nil {
  129. c.Fatalf("Could not run iptables -nvL: %s, %v", out, err)
  130. }
  131. if strings.Contains(out, ipTablesSearchString) {
  132. c.Fatalf("iptables output should not have contained %q, but was %q", ipTablesSearchString, out)
  133. }
  134. }
  135. func (s *DockerDaemonSuite) TestDaemonIptablesCreate(c *check.C) {
  136. if err := s.d.StartWithBusybox(); err != nil {
  137. c.Fatalf("Could not start daemon with busybox: %v", err)
  138. }
  139. if out, err := s.d.Cmd("run", "-d", "--name", "top", "--restart=always", "-p", "80", "busybox:latest", "top"); err != nil {
  140. c.Fatalf("Could not run top: %s, %v", out, err)
  141. }
  142. // get output from iptables with container running
  143. ipTablesSearchString := "tcp dpt:80"
  144. ipTablesCmd := exec.Command("iptables", "-nvL")
  145. out, _, err := runCommandWithOutput(ipTablesCmd)
  146. if err != nil {
  147. c.Fatalf("Could not run iptables -nvL: %s, %v", out, err)
  148. }
  149. if !strings.Contains(out, ipTablesSearchString) {
  150. c.Fatalf("iptables output should have contained %q, but was %q", ipTablesSearchString, out)
  151. }
  152. if err := s.d.Restart(); err != nil {
  153. c.Fatalf("Could not restart daemon: %v", err)
  154. }
  155. // make sure the container is not running
  156. runningOut, err := s.d.Cmd("inspect", "--format='{{.State.Running}}'", "top")
  157. if err != nil {
  158. c.Fatalf("Could not inspect on container: %s, %v", out, err)
  159. }
  160. if strings.TrimSpace(runningOut) != "true" {
  161. c.Fatalf("Container should have been restarted after daemon restart. Status running should have been true but was: %q", strings.TrimSpace(runningOut))
  162. }
  163. // get output from iptables after restart
  164. ipTablesCmd = exec.Command("iptables", "-nvL")
  165. out, _, err = runCommandWithOutput(ipTablesCmd)
  166. if err != nil {
  167. c.Fatalf("Could not run iptables -nvL: %s, %v", out, err)
  168. }
  169. if !strings.Contains(out, ipTablesSearchString) {
  170. c.Fatalf("iptables output after restart should have contained %q, but was %q", ipTablesSearchString, out)
  171. }
  172. }
  173. func (s *DockerDaemonSuite) TestDaemonLogLevelWrong(c *check.C) {
  174. c.Assert(s.d.Start("--log-level=bogus"), check.NotNil, check.Commentf("Daemon shouldn't start with wrong log level"))
  175. }
  176. func (s *DockerDaemonSuite) TestDaemonLogLevelDebug(c *check.C) {
  177. if err := s.d.Start("--log-level=debug"); err != nil {
  178. c.Fatal(err)
  179. }
  180. content, _ := ioutil.ReadFile(s.d.logFile.Name())
  181. if !strings.Contains(string(content), `level=debug`) {
  182. c.Fatalf(`Missing level="debug" in log file:\n%s`, string(content))
  183. }
  184. }
  185. func (s *DockerDaemonSuite) TestDaemonLogLevelFatal(c *check.C) {
  186. // we creating new daemons to create new logFile
  187. if err := s.d.Start("--log-level=fatal"); err != nil {
  188. c.Fatal(err)
  189. }
  190. content, _ := ioutil.ReadFile(s.d.logFile.Name())
  191. if strings.Contains(string(content), `level=debug`) {
  192. c.Fatalf(`Should not have level="debug" in log file:\n%s`, string(content))
  193. }
  194. }
  195. func (s *DockerDaemonSuite) TestDaemonFlagD(c *check.C) {
  196. if err := s.d.Start("-D"); err != nil {
  197. c.Fatal(err)
  198. }
  199. content, _ := ioutil.ReadFile(s.d.logFile.Name())
  200. if !strings.Contains(string(content), `level=debug`) {
  201. c.Fatalf(`Missing level="debug" in log file using -D:\n%s`, string(content))
  202. }
  203. }
  204. func (s *DockerDaemonSuite) TestDaemonFlagDebug(c *check.C) {
  205. if err := s.d.Start("--debug"); err != nil {
  206. c.Fatal(err)
  207. }
  208. content, _ := ioutil.ReadFile(s.d.logFile.Name())
  209. if !strings.Contains(string(content), `level=debug`) {
  210. c.Fatalf(`Missing level="debug" in log file using --debug:\n%s`, string(content))
  211. }
  212. }
  213. func (s *DockerDaemonSuite) TestDaemonFlagDebugLogLevelFatal(c *check.C) {
  214. if err := s.d.Start("--debug", "--log-level=fatal"); err != nil {
  215. c.Fatal(err)
  216. }
  217. content, _ := ioutil.ReadFile(s.d.logFile.Name())
  218. if !strings.Contains(string(content), `level=debug`) {
  219. c.Fatalf(`Missing level="debug" in log file when using both --debug and --log-level=fatal:\n%s`, string(content))
  220. }
  221. }
  222. func (s *DockerDaemonSuite) TestDaemonAllocatesListeningPort(c *check.C) {
  223. listeningPorts := [][]string{
  224. {"0.0.0.0", "0.0.0.0", "5678"},
  225. {"127.0.0.1", "127.0.0.1", "1234"},
  226. {"localhost", "127.0.0.1", "1235"},
  227. }
  228. cmdArgs := []string{}
  229. for _, hostDirective := range listeningPorts {
  230. cmdArgs = append(cmdArgs, "--host", fmt.Sprintf("tcp://%s:%s", hostDirective[0], hostDirective[2]))
  231. }
  232. if err := s.d.StartWithBusybox(cmdArgs...); err != nil {
  233. c.Fatalf("Could not start daemon with busybox: %v", err)
  234. }
  235. for _, hostDirective := range listeningPorts {
  236. output, err := s.d.Cmd("run", "-p", fmt.Sprintf("%s:%s:80", hostDirective[1], hostDirective[2]), "busybox", "true")
  237. if err == nil {
  238. c.Fatalf("Container should not start, expected port already allocated error: %q", output)
  239. } else if !strings.Contains(output, "port is already allocated") {
  240. c.Fatalf("Expected port is already allocated error: %q", output)
  241. }
  242. }
  243. }
  244. // #9629
  245. func (s *DockerDaemonSuite) TestDaemonVolumesBindsRefs(c *check.C) {
  246. if err := s.d.StartWithBusybox(); err != nil {
  247. c.Fatal(err)
  248. }
  249. tmp, err := ioutil.TempDir(os.TempDir(), "")
  250. if err != nil {
  251. c.Fatal(err)
  252. }
  253. defer os.RemoveAll(tmp)
  254. if err := ioutil.WriteFile(tmp+"/test", []byte("testing"), 0655); err != nil {
  255. c.Fatal(err)
  256. }
  257. if out, err := s.d.Cmd("create", "-v", tmp+":/foo", "--name=voltest", "busybox"); err != nil {
  258. c.Fatal(err, out)
  259. }
  260. if err := s.d.Restart(); err != nil {
  261. c.Fatal(err)
  262. }
  263. if out, err := s.d.Cmd("run", "--volumes-from=voltest", "--name=consumer", "busybox", "/bin/sh", "-c", "[ -f /foo/test ]"); err != nil {
  264. c.Fatal(err, out)
  265. }
  266. }
  267. func (s *DockerDaemonSuite) TestDaemonKeyGeneration(c *check.C) {
  268. // TODO: skip or update for Windows daemon
  269. os.Remove("/etc/docker/key.json")
  270. if err := s.d.Start(); err != nil {
  271. c.Fatalf("Could not start daemon: %v", err)
  272. }
  273. s.d.Stop()
  274. k, err := libtrust.LoadKeyFile("/etc/docker/key.json")
  275. if err != nil {
  276. c.Fatalf("Error opening key file")
  277. }
  278. kid := k.KeyID()
  279. // Test Key ID is a valid fingerprint (e.g. QQXN:JY5W:TBXI:MK3X:GX6P:PD5D:F56N:NHCS:LVRZ:JA46:R24J:XEFF)
  280. if len(kid) != 59 {
  281. c.Fatalf("Bad key ID: %s", kid)
  282. }
  283. }
  284. func (s *DockerDaemonSuite) TestDaemonKeyMigration(c *check.C) {
  285. // TODO: skip or update for Windows daemon
  286. os.Remove("/etc/docker/key.json")
  287. k1, err := libtrust.GenerateECP256PrivateKey()
  288. if err != nil {
  289. c.Fatalf("Error generating private key: %s", err)
  290. }
  291. if err := os.MkdirAll(filepath.Join(os.Getenv("HOME"), ".docker"), 0755); err != nil {
  292. c.Fatalf("Error creating .docker directory: %s", err)
  293. }
  294. if err := libtrust.SaveKey(filepath.Join(os.Getenv("HOME"), ".docker", "key.json"), k1); err != nil {
  295. c.Fatalf("Error saving private key: %s", err)
  296. }
  297. if err := s.d.Start(); err != nil {
  298. c.Fatalf("Could not start daemon: %v", err)
  299. }
  300. s.d.Stop()
  301. k2, err := libtrust.LoadKeyFile("/etc/docker/key.json")
  302. if err != nil {
  303. c.Fatalf("Error opening key file")
  304. }
  305. if k1.KeyID() != k2.KeyID() {
  306. c.Fatalf("Key not migrated")
  307. }
  308. }
  309. // Simulate an older daemon (pre 1.3) coming up with volumes specified in containers
  310. // without corresponding volume json
  311. func (s *DockerDaemonSuite) TestDaemonUpgradeWithVolumes(c *check.C) {
  312. graphDir := filepath.Join(os.TempDir(), "docker-test")
  313. defer os.RemoveAll(graphDir)
  314. if err := s.d.StartWithBusybox("-g", graphDir); err != nil {
  315. c.Fatal(err)
  316. }
  317. tmpDir := filepath.Join(os.TempDir(), "test")
  318. defer os.RemoveAll(tmpDir)
  319. if out, err := s.d.Cmd("create", "-v", tmpDir+":/foo", "--name=test", "busybox"); err != nil {
  320. c.Fatal(err, out)
  321. }
  322. if err := s.d.Stop(); err != nil {
  323. c.Fatal(err)
  324. }
  325. // Remove this since we're expecting the daemon to re-create it too
  326. if err := os.RemoveAll(tmpDir); err != nil {
  327. c.Fatal(err)
  328. }
  329. configDir := filepath.Join(graphDir, "volumes")
  330. if err := os.RemoveAll(configDir); err != nil {
  331. c.Fatal(err)
  332. }
  333. if err := s.d.Start("-g", graphDir); err != nil {
  334. c.Fatal(err)
  335. }
  336. if _, err := os.Stat(tmpDir); os.IsNotExist(err) {
  337. c.Fatalf("expected volume path %s to exist but it does not", tmpDir)
  338. }
  339. dir, err := ioutil.ReadDir(configDir)
  340. if err != nil {
  341. c.Fatal(err)
  342. }
  343. if len(dir) == 0 {
  344. c.Fatalf("expected volumes config dir to contain data for new volume")
  345. }
  346. // Now with just removing the volume config and not the volume data
  347. if err := s.d.Stop(); err != nil {
  348. c.Fatal(err)
  349. }
  350. if err := os.RemoveAll(configDir); err != nil {
  351. c.Fatal(err)
  352. }
  353. if err := s.d.Start("-g", graphDir); err != nil {
  354. c.Fatal(err)
  355. }
  356. dir, err = ioutil.ReadDir(configDir)
  357. if err != nil {
  358. c.Fatal(err)
  359. }
  360. if len(dir) == 0 {
  361. c.Fatalf("expected volumes config dir to contain data for new volume")
  362. }
  363. }
  364. // GH#11320 - verify that the daemon exits on failure properly
  365. // Note that this explicitly tests the conflict of {-b,--bridge} and {--bip} options as the means
  366. // to get a daemon init failure; no other tests for -b/--bip conflict are therefore required
  367. func (s *DockerDaemonSuite) TestDaemonExitOnFailure(c *check.C) {
  368. //attempt to start daemon with incorrect flags (we know -b and --bip conflict)
  369. if err := s.d.Start("--bridge", "nosuchbridge", "--bip", "1.1.1.1"); err != nil {
  370. //verify we got the right error
  371. if !strings.Contains(err.Error(), "Daemon exited and never started") {
  372. c.Fatalf("Expected daemon not to start, got %v", err)
  373. }
  374. // look in the log and make sure we got the message that daemon is shutting down
  375. runCmd := exec.Command("grep", "Error starting daemon", s.d.LogfileName())
  376. if out, _, err := runCommandWithOutput(runCmd); err != nil {
  377. c.Fatalf("Expected 'Error starting daemon' message; but doesn't exist in log: %q, err: %v", out, err)
  378. }
  379. } else {
  380. //if we didn't get an error and the daemon is running, this is a failure
  381. c.Fatal("Conflicting options should cause the daemon to error out with a failure")
  382. }
  383. }
  384. func (s *DockerDaemonSuite) TestDaemonBridgeExternal(c *check.C) {
  385. d := s.d
  386. err := d.Start("--bridge", "nosuchbridge")
  387. c.Assert(err, check.Not(check.IsNil), check.Commentf("--bridge option with an invalid bridge should cause the daemon to fail"))
  388. bridgeName := "external-bridge"
  389. bridgeIp := "192.169.1.1/24"
  390. _, bridgeIPNet, _ := net.ParseCIDR(bridgeIp)
  391. args := []string{"link", "add", "name", bridgeName, "type", "bridge"}
  392. ipLinkCmd := exec.Command("ip", args...)
  393. _, _, _, err = runCommandWithStdoutStderr(ipLinkCmd)
  394. c.Assert(err, check.IsNil)
  395. ifCfgCmd := exec.Command("ifconfig", bridgeName, bridgeIp, "up")
  396. _, _, _, err = runCommandWithStdoutStderr(ifCfgCmd)
  397. c.Assert(err, check.IsNil)
  398. err = d.StartWithBusybox("--bridge", bridgeName)
  399. c.Assert(err, check.IsNil)
  400. ipTablesSearchString := bridgeIPNet.String()
  401. ipTablesCmd := exec.Command("iptables", "-t", "nat", "-nvL")
  402. out, _, err := runCommandWithOutput(ipTablesCmd)
  403. c.Assert(err, check.IsNil)
  404. c.Assert(strings.Contains(out, ipTablesSearchString), check.Equals, true,
  405. check.Commentf("iptables output should have contained %q, but was %q",
  406. ipTablesSearchString, out))
  407. _, err = d.Cmd("run", "-d", "--name", "ExtContainer", "busybox", "top")
  408. c.Assert(err, check.IsNil)
  409. containerIp := d.findContainerIP(c, "ExtContainer")
  410. ip := net.ParseIP(containerIp)
  411. c.Assert(bridgeIPNet.Contains(ip), check.Equals, true,
  412. check.Commentf("Container IP-Address must be in the same subnet range : %s",
  413. containerIp))
  414. }
  415. func (s *DockerDaemonSuite) TestDaemonUlimitDefaults(c *check.C) {
  416. testRequires(c, NativeExecDriver)
  417. if err := s.d.StartWithBusybox("--default-ulimit", "nofile=42:42", "--default-ulimit", "nproc=1024:1024"); err != nil {
  418. c.Fatal(err)
  419. }
  420. out, err := s.d.Cmd("run", "--ulimit", "nproc=2048", "--name=test", "busybox", "/bin/sh", "-c", "echo $(ulimit -n); echo $(ulimit -p)")
  421. if err != nil {
  422. c.Fatal(out, err)
  423. }
  424. outArr := strings.Split(out, "\n")
  425. if len(outArr) < 2 {
  426. c.Fatalf("got unexpected output: %s", out)
  427. }
  428. nofile := strings.TrimSpace(outArr[0])
  429. nproc := strings.TrimSpace(outArr[1])
  430. if nofile != "42" {
  431. c.Fatalf("expected `ulimit -n` to be `42`, got: %s", nofile)
  432. }
  433. if nproc != "2048" {
  434. c.Fatalf("exepcted `ulimit -p` to be 2048, got: %s", nproc)
  435. }
  436. // Now restart daemon with a new default
  437. if err := s.d.Restart("--default-ulimit", "nofile=43"); err != nil {
  438. c.Fatal(err)
  439. }
  440. out, err = s.d.Cmd("start", "-a", "test")
  441. if err != nil {
  442. c.Fatal(err)
  443. }
  444. outArr = strings.Split(out, "\n")
  445. if len(outArr) < 2 {
  446. c.Fatalf("got unexpected output: %s", out)
  447. }
  448. nofile = strings.TrimSpace(outArr[0])
  449. nproc = strings.TrimSpace(outArr[1])
  450. if nofile != "43" {
  451. c.Fatalf("expected `ulimit -n` to be `43`, got: %s", nofile)
  452. }
  453. if nproc != "2048" {
  454. c.Fatalf("exepcted `ulimit -p` to be 2048, got: %s", nproc)
  455. }
  456. }
  457. // #11315
  458. func (s *DockerDaemonSuite) TestDaemonRestartRenameContainer(c *check.C) {
  459. if err := s.d.StartWithBusybox(); err != nil {
  460. c.Fatal(err)
  461. }
  462. if out, err := s.d.Cmd("run", "--name=test", "busybox"); err != nil {
  463. c.Fatal(err, out)
  464. }
  465. if out, err := s.d.Cmd("rename", "test", "test2"); err != nil {
  466. c.Fatal(err, out)
  467. }
  468. if err := s.d.Restart(); err != nil {
  469. c.Fatal(err)
  470. }
  471. if out, err := s.d.Cmd("start", "test2"); err != nil {
  472. c.Fatal(err, out)
  473. }
  474. }
  475. func (s *DockerDaemonSuite) TestDaemonLoggingDriverDefault(c *check.C) {
  476. if err := s.d.StartWithBusybox(); err != nil {
  477. c.Fatal(err)
  478. }
  479. out, err := s.d.Cmd("run", "-d", "busybox", "echo", "testline")
  480. if err != nil {
  481. c.Fatal(out, err)
  482. }
  483. id := strings.TrimSpace(out)
  484. if out, err := s.d.Cmd("wait", id); err != nil {
  485. c.Fatal(out, err)
  486. }
  487. logPath := filepath.Join(s.d.folder, "graph", "containers", id, id+"-json.log")
  488. if _, err := os.Stat(logPath); err != nil {
  489. c.Fatal(err)
  490. }
  491. f, err := os.Open(logPath)
  492. if err != nil {
  493. c.Fatal(err)
  494. }
  495. var res struct {
  496. Log string `json:"log"`
  497. Stream string `json:"stream"`
  498. Time time.Time `json:"time"`
  499. }
  500. if err := json.NewDecoder(f).Decode(&res); err != nil {
  501. c.Fatal(err)
  502. }
  503. if res.Log != "testline\n" {
  504. c.Fatalf("Unexpected log line: %q, expected: %q", res.Log, "testline\n")
  505. }
  506. if res.Stream != "stdout" {
  507. c.Fatalf("Unexpected stream: %q, expected: %q", res.Stream, "stdout")
  508. }
  509. if !time.Now().After(res.Time) {
  510. c.Fatalf("Log time %v in future", res.Time)
  511. }
  512. }
  513. func (s *DockerDaemonSuite) TestDaemonLoggingDriverDefaultOverride(c *check.C) {
  514. if err := s.d.StartWithBusybox(); err != nil {
  515. c.Fatal(err)
  516. }
  517. out, err := s.d.Cmd("run", "-d", "--log-driver=none", "busybox", "echo", "testline")
  518. if err != nil {
  519. c.Fatal(out, err)
  520. }
  521. id := strings.TrimSpace(out)
  522. if out, err := s.d.Cmd("wait", id); err != nil {
  523. c.Fatal(out, err)
  524. }
  525. logPath := filepath.Join(s.d.folder, "graph", "containers", id, id+"-json.log")
  526. if _, err := os.Stat(logPath); err == nil || !os.IsNotExist(err) {
  527. c.Fatalf("%s shouldn't exits, error on Stat: %s", logPath, err)
  528. }
  529. }
  530. func (s *DockerDaemonSuite) TestDaemonLoggingDriverNone(c *check.C) {
  531. if err := s.d.StartWithBusybox("--log-driver=none"); err != nil {
  532. c.Fatal(err)
  533. }
  534. out, err := s.d.Cmd("run", "-d", "busybox", "echo", "testline")
  535. if err != nil {
  536. c.Fatal(out, err)
  537. }
  538. id := strings.TrimSpace(out)
  539. if out, err := s.d.Cmd("wait", id); err != nil {
  540. c.Fatal(out, err)
  541. }
  542. logPath := filepath.Join(s.d.folder, "graph", "containers", id, id+"-json.log")
  543. if _, err := os.Stat(logPath); err == nil || !os.IsNotExist(err) {
  544. c.Fatalf("%s shouldn't exits, error on Stat: %s", logPath, err)
  545. }
  546. }
  547. func (s *DockerDaemonSuite) TestDaemonLoggingDriverNoneOverride(c *check.C) {
  548. if err := s.d.StartWithBusybox("--log-driver=none"); err != nil {
  549. c.Fatal(err)
  550. }
  551. out, err := s.d.Cmd("run", "-d", "--log-driver=json-file", "busybox", "echo", "testline")
  552. if err != nil {
  553. c.Fatal(out, err)
  554. }
  555. id := strings.TrimSpace(out)
  556. if out, err := s.d.Cmd("wait", id); err != nil {
  557. c.Fatal(out, err)
  558. }
  559. logPath := filepath.Join(s.d.folder, "graph", "containers", id, id+"-json.log")
  560. if _, err := os.Stat(logPath); err != nil {
  561. c.Fatal(err)
  562. }
  563. f, err := os.Open(logPath)
  564. if err != nil {
  565. c.Fatal(err)
  566. }
  567. var res struct {
  568. Log string `json:"log"`
  569. Stream string `json:"stream"`
  570. Time time.Time `json:"time"`
  571. }
  572. if err := json.NewDecoder(f).Decode(&res); err != nil {
  573. c.Fatal(err)
  574. }
  575. if res.Log != "testline\n" {
  576. c.Fatalf("Unexpected log line: %q, expected: %q", res.Log, "testline\n")
  577. }
  578. if res.Stream != "stdout" {
  579. c.Fatalf("Unexpected stream: %q, expected: %q", res.Stream, "stdout")
  580. }
  581. if !time.Now().After(res.Time) {
  582. c.Fatalf("Log time %v in future", res.Time)
  583. }
  584. }
  585. func (s *DockerDaemonSuite) TestDaemonLoggingDriverNoneLogsError(c *check.C) {
  586. if err := s.d.StartWithBusybox("--log-driver=none"); err != nil {
  587. c.Fatal(err)
  588. }
  589. out, err := s.d.Cmd("run", "-d", "busybox", "echo", "testline")
  590. if err != nil {
  591. c.Fatal(out, err)
  592. }
  593. id := strings.TrimSpace(out)
  594. out, err = s.d.Cmd("logs", id)
  595. if err == nil {
  596. c.Fatalf("Logs should fail with \"none\" driver")
  597. }
  598. if !strings.Contains(out, `\"logs\" command is supported only for \"json-file\" logging driver`) {
  599. c.Fatalf("There should be error about non-json-file driver, got %s", out)
  600. }
  601. }
  602. func (s *DockerDaemonSuite) TestDaemonDots(c *check.C) {
  603. if err := s.d.StartWithBusybox(); err != nil {
  604. c.Fatal(err)
  605. }
  606. // Now create 4 containers
  607. if _, err := s.d.Cmd("create", "busybox"); err != nil {
  608. c.Fatalf("Error creating container: %q", err)
  609. }
  610. if _, err := s.d.Cmd("create", "busybox"); err != nil {
  611. c.Fatalf("Error creating container: %q", err)
  612. }
  613. if _, err := s.d.Cmd("create", "busybox"); err != nil {
  614. c.Fatalf("Error creating container: %q", err)
  615. }
  616. if _, err := s.d.Cmd("create", "busybox"); err != nil {
  617. c.Fatalf("Error creating container: %q", err)
  618. }
  619. s.d.Stop()
  620. s.d.Start("--log-level=debug")
  621. s.d.Stop()
  622. content, _ := ioutil.ReadFile(s.d.logFile.Name())
  623. if strings.Contains(string(content), "....") {
  624. c.Fatalf("Debug level should not have ....\n%s", string(content))
  625. }
  626. s.d.Start("--log-level=error")
  627. s.d.Stop()
  628. content, _ = ioutil.ReadFile(s.d.logFile.Name())
  629. if strings.Contains(string(content), "....") {
  630. c.Fatalf("Error level should not have ....\n%s", string(content))
  631. }
  632. s.d.Start("--log-level=info")
  633. s.d.Stop()
  634. content, _ = ioutil.ReadFile(s.d.logFile.Name())
  635. if !strings.Contains(string(content), "....") {
  636. c.Fatalf("Info level should have ....\n%s", string(content))
  637. }
  638. }
  639. func (s *DockerDaemonSuite) TestDaemonUnixSockCleanedUp(c *check.C) {
  640. dir, err := ioutil.TempDir("", "socket-cleanup-test")
  641. if err != nil {
  642. c.Fatal(err)
  643. }
  644. defer os.RemoveAll(dir)
  645. sockPath := filepath.Join(dir, "docker.sock")
  646. if err := s.d.Start("--host", "unix://"+sockPath); err != nil {
  647. c.Fatal(err)
  648. }
  649. if _, err := os.Stat(sockPath); err != nil {
  650. c.Fatal("socket does not exist")
  651. }
  652. if err := s.d.Stop(); err != nil {
  653. c.Fatal(err)
  654. }
  655. if _, err := os.Stat(sockPath); err == nil || !os.IsNotExist(err) {
  656. c.Fatal("unix socket is not cleaned up")
  657. }
  658. }
  659. func (s *DockerDaemonSuite) TestDaemonwithwrongkey(c *check.C) {
  660. type Config struct {
  661. Crv string `json:"crv"`
  662. D string `json:"d"`
  663. Kid string `json:"kid"`
  664. Kty string `json:"kty"`
  665. X string `json:"x"`
  666. Y string `json:"y"`
  667. }
  668. os.Remove("/etc/docker/key.json")
  669. if err := s.d.Start(); err != nil {
  670. c.Fatalf("Failed to start daemon: %v", err)
  671. }
  672. if err := s.d.Stop(); err != nil {
  673. c.Fatalf("Could not stop daemon: %v", err)
  674. }
  675. config := &Config{}
  676. bytes, err := ioutil.ReadFile("/etc/docker/key.json")
  677. if err != nil {
  678. c.Fatalf("Error reading key.json file: %s", err)
  679. }
  680. // byte[] to Data-Struct
  681. if err := json.Unmarshal(bytes, &config); err != nil {
  682. c.Fatalf("Error Unmarshal: %s", err)
  683. }
  684. //replace config.Kid with the fake value
  685. config.Kid = "VSAJ:FUYR:X3H2:B2VZ:KZ6U:CJD5:K7BX:ZXHY:UZXT:P4FT:MJWG:HRJ4"
  686. // NEW Data-Struct to byte[]
  687. newBytes, err := json.Marshal(&config)
  688. if err != nil {
  689. c.Fatalf("Error Marshal: %s", err)
  690. }
  691. // write back
  692. if err := ioutil.WriteFile("/etc/docker/key.json", newBytes, 0400); err != nil {
  693. c.Fatalf("Error ioutil.WriteFile: %s", err)
  694. }
  695. defer os.Remove("/etc/docker/key.json")
  696. if err := s.d.Start(); err == nil {
  697. c.Fatalf("It should not be successful to start daemon with wrong key: %v", err)
  698. }
  699. content, _ := ioutil.ReadFile(s.d.logFile.Name())
  700. if !strings.Contains(string(content), "Public Key ID does not match") {
  701. c.Fatal("Missing KeyID message from daemon logs")
  702. }
  703. }
  704. func (s *DockerDaemonSuite) TestDaemonRestartKillWait(c *check.C) {
  705. if err := s.d.StartWithBusybox(); err != nil {
  706. c.Fatalf("Could not start daemon with busybox: %v", err)
  707. }
  708. out, err := s.d.Cmd("run", "-id", "busybox", "/bin/cat")
  709. if err != nil {
  710. c.Fatalf("Could not run /bin/cat: err=%v\n%s", err, out)
  711. }
  712. containerID := strings.TrimSpace(out)
  713. if out, err := s.d.Cmd("kill", containerID); err != nil {
  714. c.Fatalf("Could not kill %s: err=%v\n%s", containerID, err, out)
  715. }
  716. if err := s.d.Restart(); err != nil {
  717. c.Fatalf("Could not restart daemon: %v", err)
  718. }
  719. errchan := make(chan error)
  720. go func() {
  721. if out, err := s.d.Cmd("wait", containerID); err != nil {
  722. errchan <- fmt.Errorf("%v:\n%s", err, out)
  723. }
  724. close(errchan)
  725. }()
  726. select {
  727. case <-time.After(5 * time.Second):
  728. c.Fatal("Waiting on a stopped (killed) container timed out")
  729. case err := <-errchan:
  730. if err != nil {
  731. c.Fatal(err)
  732. }
  733. }
  734. }
  735. // TestHttpsInfo connects via two-way authenticated HTTPS to the info endpoint
  736. func (s *DockerDaemonSuite) TestHttpsInfo(c *check.C) {
  737. const (
  738. testDaemonHttpsAddr = "localhost:4271"
  739. )
  740. if err := s.d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-cert.pem",
  741. "--tlskey", "fixtures/https/server-key.pem", "-H", testDaemonHttpsAddr); err != nil {
  742. c.Fatalf("Could not start daemon with busybox: %v", err)
  743. }
  744. //force tcp protocol
  745. host := fmt.Sprintf("tcp://%s", testDaemonHttpsAddr)
  746. daemonArgs := []string{"--host", host, "--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/client-cert.pem", "--tlskey", "fixtures/https/client-key.pem"}
  747. out, err := s.d.CmdWithArgs(daemonArgs, "info")
  748. if err != nil {
  749. c.Fatalf("Error Occurred: %s and output: %s", err, out)
  750. }
  751. }
  752. // TestHttpsInfoRogueCert connects via two-way authenticated HTTPS to the info endpoint
  753. // by using a rogue client certificate and checks that it fails with the expected error.
  754. func (s *DockerDaemonSuite) TestHttpsInfoRogueCert(c *check.C) {
  755. const (
  756. errBadCertificate = "remote error: bad certificate"
  757. testDaemonHttpsAddr = "localhost:4271"
  758. )
  759. if err := s.d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-cert.pem",
  760. "--tlskey", "fixtures/https/server-key.pem", "-H", testDaemonHttpsAddr); err != nil {
  761. c.Fatalf("Could not start daemon with busybox: %v", err)
  762. }
  763. //force tcp protocol
  764. host := fmt.Sprintf("tcp://%s", testDaemonHttpsAddr)
  765. daemonArgs := []string{"--host", host, "--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/client-rogue-cert.pem", "--tlskey", "fixtures/https/client-rogue-key.pem"}
  766. out, err := s.d.CmdWithArgs(daemonArgs, "info")
  767. if err == nil || !strings.Contains(out, errBadCertificate) {
  768. c.Fatalf("Expected err: %s, got instead: %s and output: %s", errBadCertificate, err, out)
  769. }
  770. }
  771. // TestHttpsInfoRogueServerCert connects via two-way authenticated HTTPS to the info endpoint
  772. // which provides a rogue server certificate and checks that it fails with the expected error
  773. func (s *DockerDaemonSuite) TestHttpsInfoRogueServerCert(c *check.C) {
  774. const (
  775. errCaUnknown = "x509: certificate signed by unknown authority"
  776. testDaemonRogueHttpsAddr = "localhost:4272"
  777. )
  778. if err := s.d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-rogue-cert.pem",
  779. "--tlskey", "fixtures/https/server-rogue-key.pem", "-H", testDaemonRogueHttpsAddr); err != nil {
  780. c.Fatalf("Could not start daemon with busybox: %v", err)
  781. }
  782. //force tcp protocol
  783. host := fmt.Sprintf("tcp://%s", testDaemonRogueHttpsAddr)
  784. daemonArgs := []string{"--host", host, "--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/client-rogue-cert.pem", "--tlskey", "fixtures/https/client-rogue-key.pem"}
  785. out, err := s.d.CmdWithArgs(daemonArgs, "info")
  786. if err == nil || !strings.Contains(out, errCaUnknown) {
  787. c.Fatalf("Expected err: %s, got instead: %s and output: %s", errCaUnknown, err, out)
  788. }
  789. }