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>
| ... | ... |
@@ -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 |