volume create error on conflict option

Signed-off-by: Kun Zhang <zkazure@gmail.com>
This commit is contained in:
Kun Zhang 2015-10-04 20:09:51 +08:00
parent c45ad0b02d
commit 0ff3123eba
4 changed files with 37 additions and 0 deletions

View File

@ -11,6 +11,7 @@ import (
"github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/runconfig"
"github.com/docker/docker/volume"
"github.com/opencontainers/runc/libcontainer/label"
)
@ -148,5 +149,10 @@ func (daemon *Daemon) VolumeCreate(name, driverName string, opts map[string]stri
if err != nil {
return nil, err
}
// keep "docker run -v existing_volume:/foo --volume-driver other_driver" work
if (driverName != "" && v.DriverName() != driverName) || (driverName == "" && v.DriverName() != volume.DefaultDriverName) {
return nil, derr.ErrorVolumeNameTaken.WithArgs(name, v.DriverName())
}
return volumeToAPIType(v), nil
}

View File

@ -29,6 +29,14 @@ The mount is created inside the container's `/src` directory. Docker does not su
Multiple containers can use the same volume in the same time period. This is useful if two containers need access to shared data. For example, if one container writes and the other reads the data.
Volume names must be unique among drivers. This means you cannot use the same volume name with two different drivers. If you attempt this `docker` returns an error:
```
A volume named %s already exists with the %s driver. Choose a different volume name.
```
If you specify a volume name already in use on the current driver, Docker assumes you want to re-use the existing volume and does not return an error.
## Driver specific options
Some volume drivers may take options to customize the volume creation. Use the `-o` or `--opt` flags to pass driver options:

View File

@ -863,4 +863,13 @@ var (
Description: "While verifying the container's 'HostConfig', cpuset memory nodes provided aren't available in the container's cgroup available set",
HTTPStatusCode: http.StatusInternalServerError,
})
// ErrorVolumeNameTaken is generated when an error occurred while
// trying to create a volume that has existed using different driver.
ErrorVolumeNameTaken = errcode.Register(errGroup, errcode.ErrorDescriptor{
Value: "VOLUME_NAME_TAKEN",
Message: "A volume name %s already exists with the %s driver. Choose a different volume name.",
Description: "An attempt to create a volume using a driver but the volume already exists with a different driver",
HTTPStatusCode: http.StatusInternalServerError,
})
)

View File

@ -4,7 +4,9 @@ import (
"os/exec"
"strings"
derr "github.com/docker/docker/errors"
"github.com/docker/docker/pkg/integration/checker"
"github.com/docker/docker/volume"
"github.com/go-check/check"
)
@ -20,6 +22,18 @@ func (s *DockerSuite) TestVolumeCliCreate(c *check.C) {
c.Assert(name, check.Equals, "test")
}
func (s *DockerSuite) TestVolumeCliCreateOptionConflict(c *check.C) {
dockerCmd(c, "volume", "create", "--name=test")
out, _, err := dockerCmdWithError("volume", "create", "--name", "test", "--driver", "nosuchdriver")
c.Assert(err, check.NotNil, check.Commentf("volume create exception name already in use with another driver"))
stderr := derr.ErrorVolumeNameTaken.WithArgs("test", volume.DefaultDriverName).Error()
c.Assert(strings.Contains(out, strings.TrimPrefix(stderr, "volume name taken: ")), check.Equals, true)
out, _ = dockerCmd(c, "volume", "inspect", "--format='{{ .Driver }}'", "test")
_, _, err = dockerCmdWithError("volume", "create", "--name", "test", "--driver", strings.TrimSpace(out))
c.Assert(err, check.IsNil)
}
func (s *DockerSuite) TestVolumeCliInspect(c *check.C) {
testRequires(c, DaemonIsLinux)
c.Assert(