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