Re-validate Mounts on container start

Validation of Mounts was only performed on container _creation_, not on
container _start_. As a result, if the host-path no longer existed
when the container was started, a directory was created in the given
location.

This is the wrong behavior, because when using the `Mounts` API, host paths
should never be created, and an error should be produced instead.

This patch adds a validation step on container start, and produces an
error if the host path is not found.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2017-12-19 11:44:29 +01:00
parent c492e76d13
commit 7cb96ba308
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
6 changed files with 17 additions and 13 deletions

View File

@ -19,6 +19,7 @@ import (
"github.com/docker/docker/pkg/system"
"github.com/docker/docker/pkg/truncindex"
"github.com/docker/docker/runconfig"
"github.com/docker/docker/volume"
"github.com/docker/go-connections/nat"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
@ -293,6 +294,14 @@ func (daemon *Daemon) verifyContainerSettings(platform string, hostConfig *conta
return nil, errors.Errorf("can't create 'AutoRemove' container with restart policy")
}
// Validate mounts; check if host directories still exist
parser := volume.NewParser(platform)
for _, cfg := range hostConfig.Mounts {
if err := parser.ValidateMountConfig(&cfg); err != nil {
return nil, err
}
}
for _, extraHost := range hostConfig.ExtraHosts {
if _, err := opts.ValidateExtraHost(extraHost); err != nil {
return nil, err

View File

@ -22,7 +22,7 @@ type lcowParser struct {
windowsParser
}
func (p *lcowParser) validateMountConfig(mnt *mount.Mount) error {
func (p *lcowParser) ValidateMountConfig(mnt *mount.Mount) error {
return p.validateMountConfigReg(mnt, rxLCOWDestination, lcowSpecificValidators)
}

View File

@ -40,7 +40,7 @@ func linuxValidateAbsolute(p string) error {
}
return fmt.Errorf("invalid mount path: '%s' mount path must be absolute", p)
}
func (p *linuxParser) validateMountConfig(mnt *mount.Mount) error {
func (p *linuxParser) ValidateMountConfig(mnt *mount.Mount) error {
// there was something looking like a bug in existing codebase:
// - validateMountConfig on linux was called with options skipping bind source existence when calling ParseMountRaw
// - but not when calling ParseMountSpec directly... nor when the unit test called it directly

View File

@ -26,8 +26,7 @@ type Parser interface {
IsBackwardCompatible(m *MountPoint) bool
HasResource(m *MountPoint, absPath string) bool
ValidateTmpfsMountDestination(dest string) error
validateMountConfig(mt *mount.Mount) error
ValidateMountConfig(mt *mount.Mount) error
}
// NewParser creates a parser for a given container OS, depending on the current host OS (linux on a windows host will resolve to an lcowParser)

View File

@ -31,13 +31,9 @@ func TestValidateMount(t *testing.T) {
{mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath}, nil},
{mount.Mount{Type: "invalid", Target: testDestinationPath}, errors.New("mount type unknown")},
{mount.Mount{Type: mount.TypeBind, Source: testSourcePath, Target: testDestinationPath}, errBindNotExist},
}
if runtime.GOOS == "windows" {
cases = append(cases, struct {
input mount.Mount
expected error
}{mount.Mount{Type: mount.TypeBind, Source: testSourcePath, Target: testDestinationPath}, errBindNotExist}) // bind source existance is not checked on linux
}
lcowCases := []struct {
input mount.Mount
expected error
@ -54,7 +50,7 @@ func TestValidateMount(t *testing.T) {
}
parser := NewParser(runtime.GOOS)
for i, x := range cases {
err := parser.validateMountConfig(&x.input)
err := parser.ValidateMountConfig(&x.input)
if err == nil && x.expected == nil {
continue
}
@ -65,7 +61,7 @@ func TestValidateMount(t *testing.T) {
if runtime.GOOS == "windows" {
parser = &lcowParser{}
for i, x := range lcowCases {
err := parser.validateMountConfig(&x.input)
err := parser.ValidateMountConfig(&x.input)
if err == nil && x.expected == nil {
continue
}

View File

@ -189,7 +189,7 @@ func (p *windowsParser) ValidateVolumeName(name string) error {
}
return nil
}
func (p *windowsParser) validateMountConfig(mnt *mount.Mount) error {
func (p *windowsParser) ValidateMountConfig(mnt *mount.Mount) error {
return p.validateMountConfigReg(mnt, rxDestination, windowsSpecificValidators)
}