daemon_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. package daemon
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "os"
  6. "path"
  7. "path/filepath"
  8. "testing"
  9. "github.com/docker/docker/pkg/graphdb"
  10. "github.com/docker/docker/pkg/stringid"
  11. "github.com/docker/docker/pkg/truncindex"
  12. "github.com/docker/docker/volume"
  13. )
  14. //
  15. // https://github.com/docker/docker/issues/8069
  16. //
  17. func TestGet(t *testing.T) {
  18. c1 := &Container{
  19. CommonContainer: CommonContainer{
  20. ID: "5a4ff6a163ad4533d22d69a2b8960bf7fafdcba06e72d2febdba229008b0bf57",
  21. Name: "tender_bardeen",
  22. },
  23. }
  24. c2 := &Container{
  25. CommonContainer: CommonContainer{
  26. ID: "3cdbd1aa394fd68559fd1441d6eff2ab7c1e6363582c82febfaa8045df3bd8de",
  27. Name: "drunk_hawking",
  28. },
  29. }
  30. c3 := &Container{
  31. CommonContainer: CommonContainer{
  32. ID: "3cdbd1aa394fd68559fd1441d6eff2abfafdcba06e72d2febdba229008b0bf57",
  33. Name: "3cdbd1aa",
  34. },
  35. }
  36. c4 := &Container{
  37. CommonContainer: CommonContainer{
  38. ID: "75fb0b800922abdbef2d27e60abcdfaf7fb0698b2a96d22d3354da361a6ff4a5",
  39. Name: "5a4ff6a163ad4533d22d69a2b8960bf7fafdcba06e72d2febdba229008b0bf57",
  40. },
  41. }
  42. c5 := &Container{
  43. CommonContainer: CommonContainer{
  44. ID: "d22d69a2b8960bf7fafdcba06e72d2febdba960bf7fafdcba06e72d2f9008b060b",
  45. Name: "d22d69a2b896",
  46. },
  47. }
  48. store := &contStore{
  49. s: map[string]*Container{
  50. c1.ID: c1,
  51. c2.ID: c2,
  52. c3.ID: c3,
  53. c4.ID: c4,
  54. c5.ID: c5,
  55. },
  56. }
  57. index := truncindex.NewTruncIndex([]string{})
  58. index.Add(c1.ID)
  59. index.Add(c2.ID)
  60. index.Add(c3.ID)
  61. index.Add(c4.ID)
  62. index.Add(c5.ID)
  63. daemonTestDbPath := path.Join(os.TempDir(), "daemon_test.db")
  64. graph, err := graphdb.NewSqliteConn(daemonTestDbPath)
  65. if err != nil {
  66. t.Fatalf("Failed to create daemon test sqlite database at %s", daemonTestDbPath)
  67. }
  68. graph.Set(c1.Name, c1.ID)
  69. graph.Set(c2.Name, c2.ID)
  70. graph.Set(c3.Name, c3.ID)
  71. graph.Set(c4.Name, c4.ID)
  72. graph.Set(c5.Name, c5.ID)
  73. daemon := &Daemon{
  74. containers: store,
  75. idIndex: index,
  76. containerGraph: graph,
  77. }
  78. if container, _ := daemon.Get("3cdbd1aa394fd68559fd1441d6eff2ab7c1e6363582c82febfaa8045df3bd8de"); container != c2 {
  79. t.Fatal("Should explicitly match full container IDs")
  80. }
  81. if container, _ := daemon.Get("75fb0b8009"); container != c4 {
  82. t.Fatal("Should match a partial ID")
  83. }
  84. if container, _ := daemon.Get("drunk_hawking"); container != c2 {
  85. t.Fatal("Should match a full name")
  86. }
  87. // c3.Name is a partial match for both c3.ID and c2.ID
  88. if c, _ := daemon.Get("3cdbd1aa"); c != c3 {
  89. t.Fatal("Should match a full name even though it collides with another container's ID")
  90. }
  91. if container, _ := daemon.Get("d22d69a2b896"); container != c5 {
  92. t.Fatal("Should match a container where the provided prefix is an exact match to the it's name, and is also a prefix for it's ID")
  93. }
  94. if _, err := daemon.Get("3cdbd1"); err == nil {
  95. t.Fatal("Should return an error when provided a prefix that partially matches multiple container ID's")
  96. }
  97. if _, err := daemon.Get("nothing"); err == nil {
  98. t.Fatal("Should return an error when provided a prefix that is neither a name or a partial match to an ID")
  99. }
  100. os.Remove(daemonTestDbPath)
  101. }
  102. func TestLoadWithVolume(t *testing.T) {
  103. tmp, err := ioutil.TempDir("", "docker-daemon-test-")
  104. if err != nil {
  105. t.Fatal(err)
  106. }
  107. defer os.RemoveAll(tmp)
  108. containerId := "d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e"
  109. containerPath := filepath.Join(tmp, containerId)
  110. if err = os.MkdirAll(containerPath, 0755); err != nil {
  111. t.Fatal(err)
  112. }
  113. hostVolumeId := stringid.GenerateRandomID()
  114. volumePath := filepath.Join(tmp, "vfs", "dir", hostVolumeId)
  115. config := `{"State":{"Running":true,"Paused":false,"Restarting":false,"OOMKilled":false,"Dead":false,"Pid":2464,"ExitCode":0,
  116. "Error":"","StartedAt":"2015-05-26T16:48:53.869308965Z","FinishedAt":"0001-01-01T00:00:00Z"},
  117. "ID":"d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e","Created":"2015-05-26T16:48:53.7987917Z","Path":"top",
  118. "Args":[],"Config":{"Hostname":"d59df5276e7b","Domainname":"","User":"","Memory":0,"MemorySwap":0,"CpuShares":0,"Cpuset":"",
  119. "AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"PortSpecs":null,"ExposedPorts":null,"Tty":true,"OpenStdin":true,
  120. "StdinOnce":false,"Env":null,"Cmd":["top"],"Image":"ubuntu:latest","Volumes":null,"WorkingDir":"","Entrypoint":null,
  121. "NetworkDisabled":false,"MacAddress":"","OnBuild":null,"Labels":{}},"Image":"07f8e8c5e66084bef8f848877857537ffe1c47edd01a93af27e7161672ad0e95",
  122. "NetworkSettings":{"IPAddress":"172.17.0.1","IPPrefixLen":16,"MacAddress":"02:42:ac:11:00:01","LinkLocalIPv6Address":"fe80::42:acff:fe11:1",
  123. "LinkLocalIPv6PrefixLen":64,"GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"Gateway":"172.17.42.1","IPv6Gateway":"","Bridge":"docker0","PortMapping":null,"Ports":{}},
  124. "ResolvConfPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/resolv.conf",
  125. "HostnamePath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/hostname",
  126. "HostsPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/hosts",
  127. "LogPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e-json.log",
  128. "Name":"/ubuntu","Driver":"aufs","ExecDriver":"native-0.2","MountLabel":"","ProcessLabel":"","AppArmorProfile":"","RestartCount":0,
  129. "UpdateDns":false,"Volumes":{"/vol1":"%s"},"VolumesRW":{"/vol1":true},"AppliedVolumesFrom":null}`
  130. cfg := fmt.Sprintf(config, volumePath)
  131. if err = ioutil.WriteFile(filepath.Join(containerPath, "config.json"), []byte(cfg), 0644); err != nil {
  132. t.Fatal(err)
  133. }
  134. hostConfig := `{"Binds":[],"ContainerIDFile":"","LxcConf":[],"Memory":0,"MemorySwap":0,"CpuShares":0,"CpusetCpus":"",
  135. "Privileged":false,"PortBindings":{},"Links":null,"PublishAllPorts":false,"Dns":null,"DnsSearch":null,"ExtraHosts":null,"VolumesFrom":null,
  136. "Devices":[],"NetworkMode":"bridge","IpcMode":"","PidMode":"","CapAdd":null,"CapDrop":null,"RestartPolicy":{"Name":"no","MaximumRetryCount":0},
  137. "SecurityOpt":null,"ReadonlyRootfs":false,"Ulimits":null,"LogConfig":{"Type":"","Config":null},"CgroupParent":""}`
  138. if err = ioutil.WriteFile(filepath.Join(containerPath, "hostconfig.json"), []byte(hostConfig), 0644); err != nil {
  139. t.Fatal(err)
  140. }
  141. daemon := &Daemon{
  142. repository: tmp,
  143. root: tmp,
  144. }
  145. c, err := daemon.load(containerId)
  146. if err != nil {
  147. t.Fatal(err)
  148. }
  149. err = daemon.verifyVolumesInfo(c)
  150. if err != nil {
  151. t.Fatal(err)
  152. }
  153. if len(c.MountPoints) != 1 {
  154. t.Fatalf("Expected 1 volume mounted, was 0\n")
  155. }
  156. m := c.MountPoints["/vol1"]
  157. if m.Name != hostVolumeId {
  158. t.Fatalf("Expected mount name to be %s, was %s\n", hostVolumeId, m.Name)
  159. }
  160. if m.Destination != "/vol1" {
  161. t.Fatalf("Expected mount destination /vol1, was %s\n", m.Destination)
  162. }
  163. if !m.RW {
  164. t.Fatalf("Expected mount point to be RW but it was not\n")
  165. }
  166. if m.Driver != volume.DefaultDriverName {
  167. t.Fatalf("Expected mount driver local, was %s\n", m.Driver)
  168. }
  169. }
  170. func TestLoadWithBindMount(t *testing.T) {
  171. tmp, err := ioutil.TempDir("", "docker-daemon-test-")
  172. if err != nil {
  173. t.Fatal(err)
  174. }
  175. defer os.RemoveAll(tmp)
  176. containerId := "d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e"
  177. containerPath := filepath.Join(tmp, containerId)
  178. if err = os.MkdirAll(containerPath, 0755); err != nil {
  179. t.Fatal(err)
  180. }
  181. config := `{"State":{"Running":true,"Paused":false,"Restarting":false,"OOMKilled":false,"Dead":false,"Pid":2464,"ExitCode":0,
  182. "Error":"","StartedAt":"2015-05-26T16:48:53.869308965Z","FinishedAt":"0001-01-01T00:00:00Z"},
  183. "ID":"d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e","Created":"2015-05-26T16:48:53.7987917Z","Path":"top",
  184. "Args":[],"Config":{"Hostname":"d59df5276e7b","Domainname":"","User":"","Memory":0,"MemorySwap":0,"CpuShares":0,"Cpuset":"",
  185. "AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"PortSpecs":null,"ExposedPorts":null,"Tty":true,"OpenStdin":true,
  186. "StdinOnce":false,"Env":null,"Cmd":["top"],"Image":"ubuntu:latest","Volumes":null,"WorkingDir":"","Entrypoint":null,
  187. "NetworkDisabled":false,"MacAddress":"","OnBuild":null,"Labels":{}},"Image":"07f8e8c5e66084bef8f848877857537ffe1c47edd01a93af27e7161672ad0e95",
  188. "NetworkSettings":{"IPAddress":"172.17.0.1","IPPrefixLen":16,"MacAddress":"02:42:ac:11:00:01","LinkLocalIPv6Address":"fe80::42:acff:fe11:1",
  189. "LinkLocalIPv6PrefixLen":64,"GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"Gateway":"172.17.42.1","IPv6Gateway":"","Bridge":"docker0","PortMapping":null,"Ports":{}},
  190. "ResolvConfPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/resolv.conf",
  191. "HostnamePath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/hostname",
  192. "HostsPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/hosts",
  193. "LogPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e-json.log",
  194. "Name":"/ubuntu","Driver":"aufs","ExecDriver":"native-0.2","MountLabel":"","ProcessLabel":"","AppArmorProfile":"","RestartCount":0,
  195. "UpdateDns":false,"Volumes":{"/vol1": "/vol1"},"VolumesRW":{"/vol1":true},"AppliedVolumesFrom":null}`
  196. if err = ioutil.WriteFile(filepath.Join(containerPath, "config.json"), []byte(config), 0644); err != nil {
  197. t.Fatal(err)
  198. }
  199. hostConfig := `{"Binds":["/vol1:/vol1"],"ContainerIDFile":"","LxcConf":[],"Memory":0,"MemorySwap":0,"CpuShares":0,"CpusetCpus":"",
  200. "Privileged":false,"PortBindings":{},"Links":null,"PublishAllPorts":false,"Dns":null,"DnsSearch":null,"ExtraHosts":null,"VolumesFrom":null,
  201. "Devices":[],"NetworkMode":"bridge","IpcMode":"","PidMode":"","CapAdd":null,"CapDrop":null,"RestartPolicy":{"Name":"no","MaximumRetryCount":0},
  202. "SecurityOpt":null,"ReadonlyRootfs":false,"Ulimits":null,"LogConfig":{"Type":"","Config":null},"CgroupParent":""}`
  203. if err = ioutil.WriteFile(filepath.Join(containerPath, "hostconfig.json"), []byte(hostConfig), 0644); err != nil {
  204. t.Fatal(err)
  205. }
  206. daemon := &Daemon{
  207. repository: tmp,
  208. root: tmp,
  209. }
  210. c, err := daemon.load(containerId)
  211. if err != nil {
  212. t.Fatal(err)
  213. }
  214. err = daemon.verifyVolumesInfo(c)
  215. if err != nil {
  216. t.Fatal(err)
  217. }
  218. if len(c.MountPoints) != 1 {
  219. t.Fatalf("Expected 1 volume mounted, was 0\n")
  220. }
  221. m := c.MountPoints["/vol1"]
  222. if m.Name != "" {
  223. t.Fatalf("Expected empty mount name, was %s\n", m.Name)
  224. }
  225. if m.Source != "/vol1" {
  226. t.Fatalf("Expected mount source /vol1, was %s\n", m.Source)
  227. }
  228. if m.Destination != "/vol1" {
  229. t.Fatalf("Expected mount destination /vol1, was %s\n", m.Destination)
  230. }
  231. if !m.RW {
  232. t.Fatalf("Expected mount point to be RW but it was not\n")
  233. }
  234. }