docker_cli_volume_driver_compat_unix_test.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. // +build !windows
  2. package main
  3. import (
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "io/ioutil"
  8. "net/http"
  9. "net/http/httptest"
  10. "os"
  11. "path/filepath"
  12. "strings"
  13. "github.com/docker/docker/pkg/integration/checker"
  14. "github.com/go-check/check"
  15. )
  16. func init() {
  17. check.Suite(&DockerExternalVolumeSuiteCompatV1_1{
  18. ds: &DockerSuite{},
  19. })
  20. }
  21. type DockerExternalVolumeSuiteCompatV1_1 struct {
  22. server *httptest.Server
  23. ds *DockerSuite
  24. d *Daemon
  25. ec *eventCounter
  26. }
  27. func (s *DockerExternalVolumeSuiteCompatV1_1) SetUpTest(c *check.C) {
  28. s.d = NewDaemon(c)
  29. s.ec = &eventCounter{}
  30. }
  31. func (s *DockerExternalVolumeSuiteCompatV1_1) TearDownTest(c *check.C) {
  32. s.d.Stop()
  33. s.ds.TearDownTest(c)
  34. }
  35. func (s *DockerExternalVolumeSuiteCompatV1_1) SetUpSuite(c *check.C) {
  36. mux := http.NewServeMux()
  37. s.server = httptest.NewServer(mux)
  38. type pluginRequest struct {
  39. Name string
  40. }
  41. type pluginResp struct {
  42. Mountpoint string `json:",omitempty"`
  43. Err string `json:",omitempty"`
  44. }
  45. type vol struct {
  46. Name string
  47. Mountpoint string
  48. }
  49. var volList []vol
  50. read := func(b io.ReadCloser) (pluginRequest, error) {
  51. defer b.Close()
  52. var pr pluginRequest
  53. if err := json.NewDecoder(b).Decode(&pr); err != nil {
  54. return pr, err
  55. }
  56. return pr, nil
  57. }
  58. send := func(w http.ResponseWriter, data interface{}) {
  59. switch t := data.(type) {
  60. case error:
  61. http.Error(w, t.Error(), 500)
  62. case string:
  63. w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
  64. fmt.Fprintln(w, t)
  65. default:
  66. w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
  67. json.NewEncoder(w).Encode(&data)
  68. }
  69. }
  70. mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) {
  71. s.ec.activations++
  72. send(w, `{"Implements": ["VolumeDriver"]}`)
  73. })
  74. mux.HandleFunc("/VolumeDriver.Create", func(w http.ResponseWriter, r *http.Request) {
  75. s.ec.creations++
  76. pr, err := read(r.Body)
  77. if err != nil {
  78. send(w, err)
  79. return
  80. }
  81. volList = append(volList, vol{Name: pr.Name})
  82. send(w, nil)
  83. })
  84. mux.HandleFunc("/VolumeDriver.Remove", func(w http.ResponseWriter, r *http.Request) {
  85. s.ec.removals++
  86. pr, err := read(r.Body)
  87. if err != nil {
  88. send(w, err)
  89. return
  90. }
  91. if err := os.RemoveAll(hostVolumePath(pr.Name)); err != nil {
  92. send(w, &pluginResp{Err: err.Error()})
  93. return
  94. }
  95. for i, v := range volList {
  96. if v.Name == pr.Name {
  97. if err := os.RemoveAll(hostVolumePath(v.Name)); err != nil {
  98. send(w, fmt.Sprintf(`{"Err": "%v"}`, err))
  99. return
  100. }
  101. volList = append(volList[:i], volList[i+1:]...)
  102. break
  103. }
  104. }
  105. send(w, nil)
  106. })
  107. mux.HandleFunc("/VolumeDriver.Path", func(w http.ResponseWriter, r *http.Request) {
  108. s.ec.paths++
  109. pr, err := read(r.Body)
  110. if err != nil {
  111. send(w, err)
  112. return
  113. }
  114. p := hostVolumePath(pr.Name)
  115. send(w, &pluginResp{Mountpoint: p})
  116. })
  117. mux.HandleFunc("/VolumeDriver.Mount", func(w http.ResponseWriter, r *http.Request) {
  118. s.ec.mounts++
  119. pr, err := read(r.Body)
  120. if err != nil {
  121. send(w, err)
  122. return
  123. }
  124. p := hostVolumePath(pr.Name)
  125. if err := os.MkdirAll(p, 0755); err != nil {
  126. send(w, &pluginResp{Err: err.Error()})
  127. return
  128. }
  129. if err := ioutil.WriteFile(filepath.Join(p, "test"), []byte(s.server.URL), 0644); err != nil {
  130. send(w, err)
  131. return
  132. }
  133. send(w, &pluginResp{Mountpoint: p})
  134. })
  135. mux.HandleFunc("/VolumeDriver.Unmount", func(w http.ResponseWriter, r *http.Request) {
  136. s.ec.unmounts++
  137. _, err := read(r.Body)
  138. if err != nil {
  139. send(w, err)
  140. return
  141. }
  142. send(w, nil)
  143. })
  144. err := os.MkdirAll("/etc/docker/plugins", 0755)
  145. c.Assert(err, checker.IsNil)
  146. err = ioutil.WriteFile("/etc/docker/plugins/test-external-volume-driver.spec", []byte(s.server.URL), 0644)
  147. c.Assert(err, checker.IsNil)
  148. }
  149. func (s *DockerExternalVolumeSuiteCompatV1_1) TearDownSuite(c *check.C) {
  150. s.server.Close()
  151. err := os.RemoveAll("/etc/docker/plugins")
  152. c.Assert(err, checker.IsNil)
  153. }
  154. func (s *DockerExternalVolumeSuiteCompatV1_1) TestExternalVolumeDriverCompatV1_1(c *check.C) {
  155. err := s.d.StartWithBusybox()
  156. c.Assert(err, checker.IsNil)
  157. out, err := s.d.Cmd("run", "--name=test", "-v", "foo:/bar", "--volume-driver", "test-external-volume-driver", "busybox", "sh", "-c", "echo hello > /bar/hello")
  158. c.Assert(err, checker.IsNil, check.Commentf(out))
  159. out, err = s.d.Cmd("rm", "test")
  160. c.Assert(err, checker.IsNil, check.Commentf(out))
  161. out, err = s.d.Cmd("run", "--name=test2", "-v", "foo:/bar", "busybox", "cat", "/bar/hello")
  162. c.Assert(err, checker.IsNil, check.Commentf(out))
  163. c.Assert(strings.TrimSpace(out), checker.Equals, "hello")
  164. err = s.d.Restart()
  165. c.Assert(err, checker.IsNil)
  166. out, err = s.d.Cmd("start", "-a", "test2")
  167. c.Assert(strings.TrimSpace(out), checker.Equals, "hello")
  168. out, err = s.d.Cmd("rm", "test2")
  169. c.Assert(err, checker.IsNil, check.Commentf(out))
  170. out, err = s.d.Cmd("volume", "inspect", "foo")
  171. c.Assert(err, checker.IsNil, check.Commentf(out))
  172. out, err = s.d.Cmd("volume", "rm", "foo")
  173. c.Assert(err, checker.IsNil, check.Commentf(out))
  174. }