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>
This commit is contained in:
Brian Goff 2016-02-10 12:02:52 -05:00
parent 7e44d0ca58
commit 00ec6102d9
5 changed files with 28 additions and 7 deletions

View file

@ -117,7 +117,7 @@ func (daemon *Daemon) registerMountPoints(container *container.Container, hostCo
return derr.ErrorCodeMountDup.WithArgs(bind.Destination) return derr.ErrorCodeMountDup.WithArgs(bind.Destination)
} }
if len(bind.Name) > 0 && len(bind.Driver) > 0 { if len(bind.Name) > 0 {
// create the volume // create the volume
v, err := daemon.volumes.CreateWithRef(bind.Name, bind.Driver, container.ID, nil) v, err := daemon.volumes.CreateWithRef(bind.Name, bind.Driver, container.ID, nil)
if err != nil { if err != nil {

View file

@ -16,6 +16,7 @@ import (
"time" "time"
"github.com/docker/docker/pkg/integration/checker" "github.com/docker/docker/pkg/integration/checker"
"github.com/docker/engine-api/types"
"github.com/go-check/check" "github.com/go-check/check"
) )
@ -410,3 +411,15 @@ func (s *DockerExternalVolumeSuite) TestExternalVolumeDriverGet(c *check.C) {
c.Assert(s.ec.gets, check.Equals, 1) c.Assert(s.ec.gets, check.Equals, 1)
c.Assert(out, checker.Contains, "No such volume") c.Assert(out, checker.Contains, "No such volume")
} }
func (s *DockerExternalVolumeSuite) TestExternalVolumeDriverWithDaemnRestart(c *check.C) {
dockerCmd(c, "volume", "create", "-d", "test-external-volume-driver", "--name", "abc")
err := s.d.Restart()
c.Assert(err, checker.IsNil)
dockerCmd(c, "run", "--name=test", "-v", "abc:/foo", "busybox", "true")
var mounts []types.MountPoint
inspectFieldAndMarshall(c, "test", "Mounts", &mounts)
c.Assert(mounts, checker.HasLen, 1)
c.Assert(mounts[0].Driver, checker.Equals, "test-external-volume-driver")
}

View file

@ -186,12 +186,23 @@ func (s *VolumeStore) create(name, driverName string, opts map[string]string) (v
return v, nil return v, nil
} }
logrus.Debugf("Registering new volume reference: driver %s, name %s", driverName, name) // Since there isn't a specified driver name, let's see if any of the existing drivers have this volume name
if driverName == "" {
v, _ := s.getVolume(name)
if v != nil {
return v, nil
}
}
logrus.Debugf("Registering new volume reference: driver %q, name %q", driverName, name)
vd, err := volumedrivers.GetDriver(driverName) vd, err := volumedrivers.GetDriver(driverName)
if err != nil { if err != nil {
return nil, &OpErr{Op: "create", Name: name, Err: err} return nil, &OpErr{Op: "create", Name: name, Err: err}
} }
if v, _ := vd.Get(name); v != nil {
return v, nil
}
return vd.Create(name, opts) return vd.Create(name, opts)
} }

View file

@ -167,10 +167,10 @@ func TestParseMountSpecSplit(t *testing.T) {
{"/tmp:/tmp2:ro", "", "/tmp2", "/tmp", "", "", false, false}, {"/tmp:/tmp2:ro", "", "/tmp2", "/tmp", "", "", false, false},
{"/tmp:/tmp3:rw", "", "/tmp3", "/tmp", "", "", true, false}, {"/tmp:/tmp3:rw", "", "/tmp3", "/tmp", "", "", true, false},
{"/tmp:/tmp4:foo", "", "", "", "", "", false, true}, {"/tmp:/tmp4:foo", "", "", "", "", "", false, true},
{"name:/named1", "", "/named1", "", "name", "local", true, false}, {"name:/named1", "", "/named1", "", "name", "", true, false},
{"name:/named2", "external", "/named2", "", "name", "external", true, false}, {"name:/named2", "external", "/named2", "", "name", "external", true, false},
{"name:/named3:ro", "local", "/named3", "", "name", "local", false, false}, {"name:/named3:ro", "local", "/named3", "", "name", "local", false, false},
{"local/name:/tmp:rw", "", "/tmp", "", "local/name", "local", true, false}, {"local/name:/tmp:rw", "", "/tmp", "", "local/name", "", true, false},
{"/tmp:tmp", "", "", "", "", "", true, true}, {"/tmp:tmp", "", "", "", "", "", true, true},
} }
} }

View file

@ -97,9 +97,6 @@ func ParseMountSpec(spec, volumeDriver string) (*MountPoint, error) {
if len(source) == 0 { if len(source) == 0 {
mp.Source = "" // Clear it out as we previously assumed it was not a name mp.Source = "" // Clear it out as we previously assumed it was not a name
mp.Driver = volumeDriver mp.Driver = volumeDriver
if len(mp.Driver) == 0 {
mp.Driver = DefaultDriverName
}
// Named volumes can't have propagation properties specified. // Named volumes can't have propagation properties specified.
// Their defaults will be decided by docker. This is just a // Their defaults will be decided by docker. This is just a
// safeguard. Don't want to get into situations where named // safeguard. Don't want to get into situations where named