add check for local volume option

Description:
When using local volume option such as size=10G, type=tmpfs, if we provide wrong options, we could create volume successfully.
But when we are ready to use it, it will fail to start container by failing to mount the local volume(invalid option).

We should check the options at when we create it.

Signed-off-by: Wentao Zhang <zhangwentao234@huawei.com>
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Vincent Demeester 2018-04-09 10:09:30 +02:00 committed by Sebastiaan van Stijn
parent 2cb26cfe9c
commit d5b271c155
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
4 changed files with 72 additions and 10 deletions

View File

@ -1835,14 +1835,62 @@ func (s *DockerSuite) TestContainersAPICreateMountsValidation(c *check.C) {
Image: "busybox",
},
hostConfig: containertypes.HostConfig{
Mounts: []mounttypes.Mount{{
Type: "volume",
Source: "hello3",
Target: destPath,
VolumeOptions: &mounttypes.VolumeOptions{
DriverConfig: &mounttypes.Driver{
Name: "local",
Options: map[string]string{"o": "size=1"}}}}}},
Mounts: []mounttypes.Mount{
{
Type: "volume",
Source: "missing-device-opt",
Target: destPath,
VolumeOptions: &mounttypes.VolumeOptions{
DriverConfig: &mounttypes.Driver{
Name: "local",
Options: map[string]string{"type": "tmpfs"},
},
},
},
},
},
msg: `missing required option: "device"`,
},
{
config: containertypes.Config{
Image: "busybox",
},
hostConfig: containertypes.HostConfig{
Mounts: []mounttypes.Mount{
{
Type: "volume",
Source: "missing-type-opt",
Target: destPath,
VolumeOptions: &mounttypes.VolumeOptions{
DriverConfig: &mounttypes.Driver{
Name: "local",
Options: map[string]string{"device": "tmpfs"},
},
},
},
},
},
msg: `missing required option: "type"`,
},
{
config: containertypes.Config{
Image: "busybox",
},
hostConfig: containertypes.HostConfig{
Mounts: []mounttypes.Mount{
{
Type: "volume",
Source: "hello4",
Target: destPath,
VolumeOptions: &mounttypes.VolumeOptions{
DriverConfig: &mounttypes.Driver{
Name: "local",
Options: map[string]string{"o": "size=1", "type": "tmpfs", "device": "tmpfs"},
},
},
},
},
},
msg: "",
},
{
@ -1869,7 +1917,6 @@ func (s *DockerSuite) TestContainersAPICreateMountsValidation(c *check.C) {
}}}},
msg: "",
},
{
config: containertypes.Config{
Image: "busybox",

View File

@ -353,11 +353,19 @@ func (v *localVolume) unmount() error {
}
func validateOpts(opts map[string]string) error {
if len(opts) == 0 {
return nil
}
for opt := range opts {
if !validOpts[opt] {
return validationError(fmt.Sprintf("invalid option key: %q", opt))
}
}
for opt := range mandatoryOpts {
if _, ok := opts[opt]; !ok {
return errdefs.InvalidParameter(errors.Errorf("missing required option: %q", opt))
}
}
return nil
}

View File

@ -27,6 +27,10 @@ var (
"o": true, // generic mount options
"device": true, // device to mount from
}
mandatoryOpts = map[string]struct{}{
"device": {},
"type": {},
}
)
type optsConfig struct {

View File

@ -14,7 +14,10 @@ import (
type optsConfig struct{}
var validOpts map[string]bool
var (
validOpts map[string]bool
mandatoryOpts map[string]struct{}
)
// scopedPath verifies that the path where the volume is located
// is under Docker's root and the valid local paths.