docker_cli_start_volume_driver_unix_test.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. // +build !windows
  2. package main
  3. import (
  4. "encoding/json"
  5. "fmt"
  6. "io/ioutil"
  7. "net/http"
  8. "net/http/httptest"
  9. "os"
  10. "path/filepath"
  11. "strings"
  12. "github.com/go-check/check"
  13. )
  14. func init() {
  15. check.Suite(&DockerExternalVolumeSuite{
  16. ds: &DockerSuite{},
  17. })
  18. }
  19. type eventCounter struct {
  20. activations int
  21. creations int
  22. removals int
  23. mounts int
  24. unmounts int
  25. paths int
  26. }
  27. type DockerExternalVolumeSuite struct {
  28. server *httptest.Server
  29. ds *DockerSuite
  30. d *Daemon
  31. ec *eventCounter
  32. }
  33. func (s *DockerExternalVolumeSuite) SetUpTest(c *check.C) {
  34. s.d = NewDaemon(c)
  35. s.ec = &eventCounter{}
  36. }
  37. func (s *DockerExternalVolumeSuite) TearDownTest(c *check.C) {
  38. s.d.Stop()
  39. s.ds.TearDownTest(c)
  40. }
  41. func (s *DockerExternalVolumeSuite) SetUpSuite(c *check.C) {
  42. mux := http.NewServeMux()
  43. s.server = httptest.NewServer(mux)
  44. type pluginRequest struct {
  45. name string
  46. }
  47. mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) {
  48. s.ec.activations++
  49. w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
  50. fmt.Fprintln(w, `{"Implements": ["VolumeDriver"]}`)
  51. })
  52. mux.HandleFunc("/VolumeDriver.Create", func(w http.ResponseWriter, r *http.Request) {
  53. s.ec.creations++
  54. w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
  55. fmt.Fprintln(w, `{}`)
  56. })
  57. mux.HandleFunc("/VolumeDriver.Remove", func(w http.ResponseWriter, r *http.Request) {
  58. s.ec.removals++
  59. w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
  60. fmt.Fprintln(w, `{}`)
  61. })
  62. mux.HandleFunc("/VolumeDriver.Path", func(w http.ResponseWriter, r *http.Request) {
  63. s.ec.paths++
  64. var pr pluginRequest
  65. if err := json.NewDecoder(r.Body).Decode(&pr); err != nil {
  66. http.Error(w, err.Error(), 500)
  67. }
  68. p := hostVolumePath(pr.name)
  69. w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
  70. fmt.Fprintln(w, fmt.Sprintf("{\"Mountpoint\": \"%s\"}", p))
  71. })
  72. mux.HandleFunc("/VolumeDriver.Mount", func(w http.ResponseWriter, r *http.Request) {
  73. s.ec.mounts++
  74. var pr pluginRequest
  75. if err := json.NewDecoder(r.Body).Decode(&pr); err != nil {
  76. http.Error(w, err.Error(), 500)
  77. }
  78. p := hostVolumePath(pr.name)
  79. if err := os.MkdirAll(p, 0755); err != nil {
  80. http.Error(w, err.Error(), 500)
  81. }
  82. if err := ioutil.WriteFile(filepath.Join(p, "test"), []byte(s.server.URL), 0644); err != nil {
  83. http.Error(w, err.Error(), 500)
  84. }
  85. w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
  86. fmt.Fprintln(w, fmt.Sprintf("{\"Mountpoint\": \"%s\"}", p))
  87. })
  88. mux.HandleFunc("/VolumeDriver.Unmount", func(w http.ResponseWriter, r *http.Request) {
  89. s.ec.unmounts++
  90. var pr pluginRequest
  91. if err := json.NewDecoder(r.Body).Decode(&pr); err != nil {
  92. http.Error(w, err.Error(), 500)
  93. }
  94. p := hostVolumePath(pr.name)
  95. if err := os.RemoveAll(p); err != nil {
  96. http.Error(w, err.Error(), 500)
  97. }
  98. w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
  99. fmt.Fprintln(w, `{}`)
  100. })
  101. if err := os.MkdirAll("/etc/docker/plugins", 0755); err != nil {
  102. c.Fatal(err)
  103. }
  104. if err := ioutil.WriteFile("/etc/docker/plugins/test-external-volume-driver.spec", []byte(s.server.URL), 0644); err != nil {
  105. c.Fatal(err)
  106. }
  107. }
  108. func (s *DockerExternalVolumeSuite) TearDownSuite(c *check.C) {
  109. s.server.Close()
  110. if err := os.RemoveAll("/etc/docker/plugins"); err != nil {
  111. c.Fatal(err)
  112. }
  113. }
  114. func (s *DockerExternalVolumeSuite) TestStartExternalNamedVolumeDriver(c *check.C) {
  115. if err := s.d.StartWithBusybox(); err != nil {
  116. c.Fatal(err)
  117. }
  118. out, err := s.d.Cmd("run", "--rm", "--name", "test-data", "-v", "external-volume-test:/tmp/external-volume-test", "--volume-driver", "test-external-volume-driver", "busybox:latest", "cat", "/tmp/external-volume-test/test")
  119. if err != nil {
  120. c.Fatal(err)
  121. }
  122. if !strings.Contains(out, s.server.URL) {
  123. c.Fatalf("External volume mount failed. Output: %s\n", out)
  124. }
  125. p := hostVolumePath("external-volume-test")
  126. _, err = os.Lstat(p)
  127. if err == nil {
  128. c.Fatalf("Expected error checking volume path in host: %s\n", p)
  129. }
  130. if !os.IsNotExist(err) {
  131. c.Fatalf("Expected volume path in host to not exist: %s, %v\n", p, err)
  132. }
  133. c.Assert(s.ec.activations, check.Equals, 1)
  134. c.Assert(s.ec.creations, check.Equals, 1)
  135. c.Assert(s.ec.removals, check.Equals, 1)
  136. c.Assert(s.ec.mounts, check.Equals, 1)
  137. c.Assert(s.ec.unmounts, check.Equals, 1)
  138. }
  139. func (s *DockerExternalVolumeSuite) TestStartExternalVolumeUnnamedDriver(c *check.C) {
  140. if err := s.d.StartWithBusybox(); err != nil {
  141. c.Fatal(err)
  142. }
  143. out, err := s.d.Cmd("run", "--rm", "--name", "test-data", "-v", "/tmp/external-volume-test", "--volume-driver", "test-external-volume-driver", "busybox:latest", "cat", "/tmp/external-volume-test/test")
  144. if err != nil {
  145. c.Fatal(err)
  146. }
  147. if !strings.Contains(out, s.server.URL) {
  148. c.Fatalf("External volume mount failed. Output: %s\n", out)
  149. }
  150. c.Assert(s.ec.activations, check.Equals, 1)
  151. c.Assert(s.ec.creations, check.Equals, 1)
  152. c.Assert(s.ec.removals, check.Equals, 1)
  153. c.Assert(s.ec.mounts, check.Equals, 1)
  154. c.Assert(s.ec.unmounts, check.Equals, 1)
  155. }
  156. func (s DockerExternalVolumeSuite) TestStartExternalVolumeDriverVolumesFrom(c *check.C) {
  157. if err := s.d.StartWithBusybox(); err != nil {
  158. c.Fatal(err)
  159. }
  160. if _, err := s.d.Cmd("run", "-d", "--name", "vol-test1", "-v", "/foo", "--volume-driver", "test-external-volume-driver", "busybox:latest"); err != nil {
  161. c.Fatal(err)
  162. }
  163. if _, err := s.d.Cmd("run", "--rm", "--volumes-from", "vol-test1", "--name", "vol-test2", "busybox", "ls", "/tmp"); err != nil {
  164. c.Fatal(err)
  165. }
  166. if _, err := s.d.Cmd("rm", "-f", "vol-test1"); err != nil {
  167. c.Fatal(err)
  168. }
  169. c.Assert(s.ec.activations, check.Equals, 1)
  170. c.Assert(s.ec.creations, check.Equals, 2)
  171. c.Assert(s.ec.removals, check.Equals, 1)
  172. c.Assert(s.ec.mounts, check.Equals, 2)
  173. c.Assert(s.ec.unmounts, check.Equals, 2)
  174. }
  175. func (s DockerExternalVolumeSuite) TestStartExternalVolumeDriverDeleteContainer(c *check.C) {
  176. if err := s.d.StartWithBusybox(); err != nil {
  177. c.Fatal(err)
  178. }
  179. if _, err := s.d.Cmd("run", "-d", "--name", "vol-test1", "-v", "/foo", "--volume-driver", "test-external-volume-driver", "busybox:latest"); err != nil {
  180. c.Fatal(err)
  181. }
  182. if _, err := s.d.Cmd("rm", "-fv", "vol-test1"); err != nil {
  183. c.Fatal(err)
  184. }
  185. c.Assert(s.ec.activations, check.Equals, 1)
  186. c.Assert(s.ec.creations, check.Equals, 1)
  187. c.Assert(s.ec.removals, check.Equals, 1)
  188. c.Assert(s.ec.mounts, check.Equals, 1)
  189. c.Assert(s.ec.unmounts, check.Equals, 1)
  190. }
  191. func hostVolumePath(name string) string {
  192. return fmt.Sprintf("/var/lib/docker/volumes/%s", name)
  193. }