volume/mounts: move some code to correct location, and minor linting/formatting

- Remove the windowsparser.HasResource() override, as it was the same on both
  Windows and Linux
- Move the rxLCOWDestination to the lcowParser code
- Move the rwModes variable to a generic (non-platform-specific) file, as it's
  used both for the windowsParser and the linuxParser
- Some minor formatting and linting changes

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2021-07-02 13:25:27 +02:00
parent 2a562b1583
commit f3d08d59aa
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
7 changed files with 26 additions and 31 deletions

View File

@ -7,6 +7,14 @@ import (
"github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/mount"
) )
// rxLCOWDestination is the regex expression for the mount destination for LCOW
//
// Destination (aka container path):
// - Variation on hostdir but can be a drive followed by colon as well
// - If a path, must be absolute. Can include spaces
// - Drive cannot be c: (explicitly checked in code, not RegEx)
const rxLCOWDestination = `(?P<destination>/(?:[^\\/:*?"<>\r\n]+[/]?)*)`
var lcowSpecificValidators mountValidator = func(m *mount.Mount) error { var lcowSpecificValidators mountValidator = func(m *mount.Mount) error {
if path.Clean(m.Target) == "/" { if path.Clean(m.Target) == "/" {
return ErrVolumeTargetIsRoot return ErrVolumeTargetIsRoot

View File

@ -12,8 +12,7 @@ import (
"github.com/docker/docker/volume" "github.com/docker/docker/volume"
) )
type linuxParser struct { type linuxParser struct{}
}
func linuxSplitRawSpec(raw string) ([]string, error) { func linuxSplitRawSpec(raw string) ([]string, error) {
if strings.Count(raw, ":") > 2 { if strings.Count(raw, ":") > 2 {
@ -115,12 +114,6 @@ func (p *linuxParser) validateMountConfigImpl(mnt *mount.Mount, validateBindSour
return nil return nil
} }
// read-write modes
var rwModes = map[string]bool{
"rw": true,
"ro": true,
}
// label modes // label modes
var linuxLabelModes = map[string]bool{ var linuxLabelModes = map[string]bool{
"Z": true, "Z": true,

View File

@ -18,6 +18,12 @@ const (
// It's used by both LCOW and Linux parsers. // It's used by both LCOW and Linux parsers.
var ErrVolumeTargetIsRoot = errors.New("invalid specification: destination can't be '/'") var ErrVolumeTargetIsRoot = errors.New("invalid specification: destination can't be '/'")
// read-write modes
var rwModes = map[string]bool{
"rw": true,
"ro": true,
}
// Parser represents a platform specific parser for mount expressions // Parser represents a platform specific parser for mount expressions
type Parser interface { type Parser interface {
ParseMountRaw(raw, volumeDriver string) (*MountPoint, error) ParseMountRaw(raw, volumeDriver string) (*MountPoint, error)

View File

@ -10,7 +10,6 @@ import (
"github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/mount"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
"gotest.tools/v3/assert/cmp"
) )
type parseMountRawTestSet struct { type parseMountRawTestSet struct {
@ -300,9 +299,7 @@ func TestParseMountRaw(t *testing.T) {
winParser := &windowsParser{} winParser := &windowsParser{}
lcowParser := &lcowParser{} lcowParser := &lcowParser{}
tester := func(parser Parser, set parseMountRawTestSet) { tester := func(parser Parser, set parseMountRawTestSet) {
for _, path := range set.valid { for _, path := range set.valid {
if _, err := parser.ParseMountRaw(path, "local"); err != nil { if _, err := parser.ParseMountRaw(path, "local"); err != nil {
t.Errorf("ParseMountRaw(`%q`) should succeed: error %q", path, err) t.Errorf("ParseMountRaw(`%q`) should succeed: error %q", path, err)
} }
@ -318,10 +315,10 @@ func TestParseMountRaw(t *testing.T) {
} }
} }
} }
tester(linParser, linuxSet) tester(linParser, linuxSet)
tester(winParser, windowsSet) tester(winParser, windowsSet)
tester(lcowParser, lcowSet) tester(lcowParser, lcowSet)
} }
// testParseMountRaw is a structure used by TestParseMountRawSplit for // testParseMountRaw is a structure used by TestParseMountRawSplit for
@ -397,7 +394,7 @@ func TestParseMountRawSplit(t *testing.T) {
} }
if m == nil || err != nil { if m == nil || err != nil {
t.Errorf("ParseMountRaw failed for spec '%s', driver '%s', error '%v'", c.bind, c.driver, err.Error()) t.Errorf("ParseMountRaw failed for spec '%s', driver '%s', error '%v'", c.bind, c.driver, err)
continue continue
} }
@ -525,6 +522,5 @@ func TestParseMountSpecBindWithFileinfoError(t *testing.T) {
parser := NewParser(runtime.GOOS) parser := NewParser(runtime.GOOS)
_, err := parser.ParseMountSpec(m) _, err := parser.ParseMountSpec(m)
assert.Assert(t, err != nil) assert.ErrorContains(t, err, "some crazy error")
assert.Assert(t, cmp.Contains(err.Error(), "some crazy error"))
} }

View File

@ -12,7 +12,3 @@ func (p *linuxParser) HasResource(m *MountPoint, absolutePath string) bool {
relPath, err := filepath.Rel(m.Destination, absolutePath) relPath, err := filepath.Rel(m.Destination, absolutePath)
return err == nil && relPath != ".." && !strings.HasPrefix(relPath, fmt.Sprintf("..%c", filepath.Separator)) return err == nil && relPath != ".." && !strings.HasPrefix(relPath, fmt.Sprintf("..%c", filepath.Separator))
} }
func (p *windowsParser) HasResource(m *MountPoint, absolutePath string) bool {
return false
}

View File

@ -1,8 +1,5 @@
package mounts // import "github.com/docker/docker/volume/mounts" package mounts // import "github.com/docker/docker/volume/mounts"
func (p *windowsParser) HasResource(m *MountPoint, absolutePath string) bool {
return false
}
func (p *linuxParser) HasResource(m *MountPoint, absolutePath string) bool { func (p *linuxParser) HasResource(m *MountPoint, absolutePath string) bool {
return false return false
} }

View File

@ -12,8 +12,7 @@ import (
"github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/stringid"
) )
type windowsParser struct { type windowsParser struct{}
}
const ( const (
// Spec should be in the format [source:]destination[:mode] // Spec should be in the format [source:]destination[:mode]
@ -63,12 +62,6 @@ const (
// rxDestination is the regex expression for the mount destination // rxDestination is the regex expression for the mount destination
rxDestination = `(?P<destination>((?:\\\\\?\\)?([a-z]):((?:[\\/][^\\/:*?"<>\r\n]+)*[\\/]?))|(` + rxPipe + `))` rxDestination = `(?P<destination>((?:\\\\\?\\)?([a-z]):((?:[\\/][^\\/:*?"<>\r\n]+)*[\\/]?))|(` + rxPipe + `))`
rxLCOWDestination = `(?P<destination>/(?:[^\\/:*?"<>\r\n]+[/]?)*)`
// Destination (aka container path):
// - Variation on hostdir but can be a drive followed by colon as well
// - If a path, must be absolute. Can include spaces
// - Drive cannot be c: (explicitly checked in code, not RegEx)
// rxMode is the regex expression for the mode of the mount // rxMode is the regex expression for the mode of the mount
// Mode (optional): // Mode (optional):
// - Hopefully self explanatory in comparison to above regex's. // - Hopefully self explanatory in comparison to above regex's.
@ -136,8 +129,10 @@ func windowsValidMountMode(mode string) bool {
if mode == "" { if mode == "" {
return true return true
} }
// TODO should windows mounts produce an error if any mode was provided (they're a no-op on windows)
return rwModes[strings.ToLower(mode)] return rwModes[strings.ToLower(mode)]
} }
func windowsValidateNotRoot(p string) error { func windowsValidateNotRoot(p string) error {
p = strings.ToLower(strings.Replace(p, `/`, `\`, -1)) p = strings.ToLower(strings.Replace(p, `/`, `\`, -1))
if p == "c:" || p == `c:\` { if p == "c:" || p == `c:\` {
@ -177,7 +172,7 @@ func (p *windowsParser) ReadWrite(mode string) bool {
return strings.ToLower(mode) != "ro" return strings.ToLower(mode) != "ro"
} }
// IsVolumeNameValid checks a volume name in a platform specific manner. // ValidateVolumeName checks a volume name in a platform specific manner.
func (p *windowsParser) ValidateVolumeName(name string) error { func (p *windowsParser) ValidateVolumeName(name string) error {
nameExp := regexp.MustCompile(`^` + rxName + `$`) nameExp := regexp.MustCompile(`^` + rxName + `$`)
if !nameExp.MatchString(name) { if !nameExp.MatchString(name) {
@ -454,3 +449,7 @@ func (p *windowsParser) IsBackwardCompatible(m *MountPoint) bool {
func (p *windowsParser) ValidateTmpfsMountDestination(dest string) error { func (p *windowsParser) ValidateTmpfsMountDestination(dest string) error {
return errors.New("Platform does not support tmpfs") return errors.New("Platform does not support tmpfs")
} }
func (p *windowsParser) HasResource(m *MountPoint, absolutePath string) bool {
return false
}