Browse code

Probe all drivers if volume driver not specified

This fixes an issue where `docker run -v foo:/bar --volume-driver
<remote driver>` -> daemon restart -> `docker run -v foo:/bar` would
make a `local` volume after the restart instead of using the existing
volume from the remote driver.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>

Brian Goff authored on 2016/02/11 02:02:52
Showing 5 changed files
... ...
@@ -117,7 +117,7 @@ func (daemon *Daemon) registerMountPoints(container *container.Container, hostCo
117 117
 			return derr.ErrorCodeMountDup.WithArgs(bind.Destination)
118 118
 		}
119 119
 
120
-		if len(bind.Name) > 0 && len(bind.Driver) > 0 {
120
+		if len(bind.Name) > 0 {
121 121
 			// create the volume
122 122
 			v, err := daemon.volumes.CreateWithRef(bind.Name, bind.Driver, container.ID, nil)
123 123
 			if err != nil {
... ...
@@ -16,6 +16,7 @@ import (
16 16
 	"time"
17 17
 
18 18
 	"github.com/docker/docker/pkg/integration/checker"
19
+	"github.com/docker/engine-api/types"
19 20
 	"github.com/go-check/check"
20 21
 )
21 22
 
... ...
@@ -410,3 +411,15 @@ func (s *DockerExternalVolumeSuite) TestExternalVolumeDriverGet(c *check.C) {
410 410
 	c.Assert(s.ec.gets, check.Equals, 1)
411 411
 	c.Assert(out, checker.Contains, "No such volume")
412 412
 }
413
+
414
+func (s *DockerExternalVolumeSuite) TestExternalVolumeDriverWithDaemnRestart(c *check.C) {
415
+	dockerCmd(c, "volume", "create", "-d", "test-external-volume-driver", "--name", "abc")
416
+	err := s.d.Restart()
417
+	c.Assert(err, checker.IsNil)
418
+
419
+	dockerCmd(c, "run", "--name=test", "-v", "abc:/foo", "busybox", "true")
420
+	var mounts []types.MountPoint
421
+	inspectFieldAndMarshall(c, "test", "Mounts", &mounts)
422
+	c.Assert(mounts, checker.HasLen, 1)
423
+	c.Assert(mounts[0].Driver, checker.Equals, "test-external-volume-driver")
424
+}
... ...
@@ -186,12 +186,23 @@ func (s *VolumeStore) create(name, driverName string, opts map[string]string) (v
186 186
 		return v, nil
187 187
 	}
188 188
 
189
-	logrus.Debugf("Registering new volume reference: driver %s, name %s", driverName, name)
189
+	// Since there isn't a specified driver name, let's see if any of the existing drivers have this volume name
190
+	if driverName == "" {
191
+		v, _ := s.getVolume(name)
192
+		if v != nil {
193
+			return v, nil
194
+		}
195
+	}
196
+
197
+	logrus.Debugf("Registering new volume reference: driver %q, name %q", driverName, name)
190 198
 	vd, err := volumedrivers.GetDriver(driverName)
191 199
 	if err != nil {
192 200
 		return nil, &OpErr{Op: "create", Name: name, Err: err}
193 201
 	}
194 202
 
203
+	if v, _ := vd.Get(name); v != nil {
204
+		return v, nil
205
+	}
195 206
 	return vd.Create(name, opts)
196 207
 }
197 208
 
... ...
@@ -167,10 +167,10 @@ func TestParseMountSpecSplit(t *testing.T) {
167 167
 			{"/tmp:/tmp2:ro", "", "/tmp2", "/tmp", "", "", false, false},
168 168
 			{"/tmp:/tmp3:rw", "", "/tmp3", "/tmp", "", "", true, false},
169 169
 			{"/tmp:/tmp4:foo", "", "", "", "", "", false, true},
170
-			{"name:/named1", "", "/named1", "", "name", "local", true, false},
170
+			{"name:/named1", "", "/named1", "", "name", "", true, false},
171 171
 			{"name:/named2", "external", "/named2", "", "name", "external", true, false},
172 172
 			{"name:/named3:ro", "local", "/named3", "", "name", "local", false, false},
173
-			{"local/name:/tmp:rw", "", "/tmp", "", "local/name", "local", true, false},
173
+			{"local/name:/tmp:rw", "", "/tmp", "", "local/name", "", true, false},
174 174
 			{"/tmp:tmp", "", "", "", "", "", true, true},
175 175
 		}
176 176
 	}
... ...
@@ -97,9 +97,6 @@ func ParseMountSpec(spec, volumeDriver string) (*MountPoint, error) {
97 97
 	if len(source) == 0 {
98 98
 		mp.Source = "" // Clear it out as we previously assumed it was not a name
99 99
 		mp.Driver = volumeDriver
100
-		if len(mp.Driver) == 0 {
101
-			mp.Driver = DefaultDriverName
102
-		}
103 100
 		// Named volumes can't have propagation properties specified.
104 101
 		// Their defaults will be decided by docker. This is just a
105 102
 		// safeguard. Don't want to get into situations where named