mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
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:
parent
2cb26cfe9c
commit
d5b271c155
4 changed files with 72 additions and 10 deletions
|
@ -1835,14 +1835,62 @@ func (s *DockerSuite) TestContainersAPICreateMountsValidation(c *check.C) {
|
||||||
Image: "busybox",
|
Image: "busybox",
|
||||||
},
|
},
|
||||||
hostConfig: containertypes.HostConfig{
|
hostConfig: containertypes.HostConfig{
|
||||||
Mounts: []mounttypes.Mount{{
|
Mounts: []mounttypes.Mount{
|
||||||
|
{
|
||||||
Type: "volume",
|
Type: "volume",
|
||||||
Source: "hello3",
|
Source: "missing-device-opt",
|
||||||
Target: destPath,
|
Target: destPath,
|
||||||
VolumeOptions: &mounttypes.VolumeOptions{
|
VolumeOptions: &mounttypes.VolumeOptions{
|
||||||
DriverConfig: &mounttypes.Driver{
|
DriverConfig: &mounttypes.Driver{
|
||||||
Name: "local",
|
Name: "local",
|
||||||
Options: map[string]string{"o": "size=1"}}}}}},
|
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: "",
|
msg: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1869,7 +1917,6 @@ func (s *DockerSuite) TestContainersAPICreateMountsValidation(c *check.C) {
|
||||||
}}}},
|
}}}},
|
||||||
msg: "",
|
msg: "",
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
config: containertypes.Config{
|
config: containertypes.Config{
|
||||||
Image: "busybox",
|
Image: "busybox",
|
||||||
|
|
|
@ -353,11 +353,19 @@ func (v *localVolume) unmount() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateOpts(opts map[string]string) error {
|
func validateOpts(opts map[string]string) error {
|
||||||
|
if len(opts) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
for opt := range opts {
|
for opt := range opts {
|
||||||
if !validOpts[opt] {
|
if !validOpts[opt] {
|
||||||
return validationError(fmt.Sprintf("invalid option key: %q", 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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,10 @@ var (
|
||||||
"o": true, // generic mount options
|
"o": true, // generic mount options
|
||||||
"device": true, // device to mount from
|
"device": true, // device to mount from
|
||||||
}
|
}
|
||||||
|
mandatoryOpts = map[string]struct{}{
|
||||||
|
"device": {},
|
||||||
|
"type": {},
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
type optsConfig struct {
|
type optsConfig struct {
|
||||||
|
|
|
@ -14,7 +14,10 @@ import (
|
||||||
|
|
||||||
type optsConfig struct{}
|
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
|
// scopedPath verifies that the path where the volume is located
|
||||||
// is under Docker's root and the valid local paths.
|
// is under Docker's root and the valid local paths.
|
||||||
|
|
Loading…
Reference in a new issue