Fix volume Create to check against canonical driver name

Previously, it was comparing against the driver name passed in by the
caller. This could lead to subtle issues when using plugins, like
"plugin" vs. "plugin:latest".

Also, remove "conflict:" prefix to improve the error message.

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Upstream-commit: 53d447c5d5c85d5595d5170411189c88a135a789
Component: engine
This commit is contained in:
Aaron Lehmann
2016-12-13 17:20:52 -08:00
parent ce25e5f9c1
commit 6f94fb07b2
4 changed files with 28 additions and 18 deletions

View File

@ -284,6 +284,22 @@ func (s *DockerExternalVolumeSuite) TearDownSuite(c *check.C) {
c.Assert(err, checker.IsNil)
}
func (s *DockerExternalVolumeSuite) TestVolumeCLICreateOptionConflict(c *check.C) {
dockerCmd(c, "volume", "create", "test")
out, _, err := dockerCmdWithError("volume", "create", "test", "--driver", volumePluginName)
c.Assert(err, check.NotNil, check.Commentf("volume create exception name already in use with another driver"))
c.Assert(out, checker.Contains, "A volume named test already exists")
out, _ = dockerCmd(c, "volume", "inspect", "--format={{ .Driver }}", "test")
_, _, err = dockerCmdWithError("volume", "create", "test", "--driver", strings.TrimSpace(out))
c.Assert(err, check.IsNil)
// make sure hidden --name option conflicts with positional arg name
out, _, err = dockerCmdWithError("volume", "create", "--name", "test2", "test2")
c.Assert(err, check.NotNil, check.Commentf("Conflicting options: either specify --name or provide positional arg, not both"))
}
func (s *DockerExternalVolumeSuite) TestExternalVolumeDriverNamed(c *check.C) {
s.d.StartWithBusybox(c)

View File

@ -29,21 +29,6 @@ func (s *DockerSuite) TestVolumeCLICreate(c *check.C) {
c.Assert(name, check.Equals, "test2")
}
func (s *DockerSuite) TestVolumeCLICreateOptionConflict(c *check.C) {
dockerCmd(c, "volume", "create", "test")
out, _, err := dockerCmdWithError("volume", "create", "test", "--driver", "nosuchdriver")
c.Assert(err, check.NotNil, check.Commentf("volume create exception name already in use with another driver"))
c.Assert(out, checker.Contains, "A volume named test already exists")
out, _ = dockerCmd(c, "volume", "inspect", "--format={{ .Driver }}", "test")
_, _, err = dockerCmdWithError("volume", "create", "test", "--driver", strings.TrimSpace(out))
c.Assert(err, check.IsNil)
// make sure hidden --name option conflicts with positional arg name
out, _, err = dockerCmdWithError("volume", "create", "--name", "test2", "test2")
c.Assert(err, check.NotNil, check.Commentf("Conflicting options: either specify --name or provide positional arg, not both"))
}
func (s *DockerSuite) TestVolumeCLIInspect(c *check.C) {
c.Assert(
exec.Command(dockerBinary, "volume", "inspect", "doesntexist").Run(),

View File

@ -14,7 +14,7 @@ var (
// errInvalidName is a typed error returned when creating a volume with a name that is not valid on the platform
errInvalidName = errors.New("volume name is not valid on this platform")
// errNameConflict is a typed error returned on create when a volume exists with the given name, but for a different driver
errNameConflict = errors.New("conflict: volume name must be unique")
errNameConflict = errors.New("volume name must be unique")
)
// OpErr is the error type returned by functions in the store package. It describes

View File

@ -309,8 +309,17 @@ func (s *VolumeStore) checkConflict(name, driverName string) (volume.Volume, err
vDriverName := v.DriverName()
var conflict bool
if driverName != "" && vDriverName != driverName {
conflict = true
if driverName != "" {
// Retrieve canonical driver name to avoid inconsistencies (for example
// "plugin" vs. "plugin:latest")
vd, err := volumedrivers.GetDriver(driverName)
if err != nil {
return nil, err
}
if vDriverName != vd.Name() {
conflict = true
}
}
// let's check if the found volume ref