github.com/jingleWang/moby@v1.13.1/volume/volume_unix.go (about) 1 // +build linux freebsd darwin solaris 2 3 package volume 4 5 import ( 6 "fmt" 7 "os" 8 "path/filepath" 9 "strings" 10 11 mounttypes "github.com/docker/docker/api/types/mount" 12 ) 13 14 var platformRawValidationOpts = []func(o *validateOpts){ 15 // need to make sure to not error out if the bind source does not exist on unix 16 // this is supported for historical reasons, the path will be automatically 17 // created later. 18 func(o *validateOpts) { o.skipBindSourceCheck = true }, 19 } 20 21 // read-write modes 22 var rwModes = map[string]bool{ 23 "rw": true, 24 "ro": true, 25 } 26 27 // label modes 28 var labelModes = map[string]bool{ 29 "Z": true, 30 "z": true, 31 } 32 33 // BackwardsCompatible decides whether this mount point can be 34 // used in old versions of Docker or not. 35 // Only bind mounts and local volumes can be used in old versions of Docker. 36 func (m *MountPoint) BackwardsCompatible() bool { 37 return len(m.Source) > 0 || m.Driver == DefaultDriverName 38 } 39 40 // HasResource checks whether the given absolute path for a container is in 41 // this mount point. If the relative path starts with `../` then the resource 42 // is outside of this mount point, but we can't simply check for this prefix 43 // because it misses `..` which is also outside of the mount, so check both. 44 func (m *MountPoint) HasResource(absolutePath string) bool { 45 relPath, err := filepath.Rel(m.Destination, absolutePath) 46 return err == nil && relPath != ".." && !strings.HasPrefix(relPath, fmt.Sprintf("..%c", filepath.Separator)) 47 } 48 49 // IsVolumeNameValid checks a volume name in a platform specific manner. 50 func IsVolumeNameValid(name string) (bool, error) { 51 return true, nil 52 } 53 54 // ValidMountMode will make sure the mount mode is valid. 55 // returns if it's a valid mount mode or not. 56 func ValidMountMode(mode string) bool { 57 if mode == "" { 58 return true 59 } 60 61 rwModeCount := 0 62 labelModeCount := 0 63 propagationModeCount := 0 64 copyModeCount := 0 65 66 for _, o := range strings.Split(mode, ",") { 67 switch { 68 case rwModes[o]: 69 rwModeCount++ 70 case labelModes[o]: 71 labelModeCount++ 72 case propagationModes[mounttypes.Propagation(o)]: 73 propagationModeCount++ 74 case copyModeExists(o): 75 copyModeCount++ 76 default: 77 return false 78 } 79 } 80 81 // Only one string for each mode is allowed. 82 if rwModeCount > 1 || labelModeCount > 1 || propagationModeCount > 1 || copyModeCount > 1 { 83 return false 84 } 85 return true 86 } 87 88 // ReadWrite tells you if a mode string is a valid read-write mode or not. 89 // If there are no specifications w.r.t read write mode, then by default 90 // it returns true. 91 func ReadWrite(mode string) bool { 92 if !ValidMountMode(mode) { 93 return false 94 } 95 96 for _, o := range strings.Split(mode, ",") { 97 if o == "ro" { 98 return false 99 } 100 } 101 return true 102 } 103 104 func validateNotRoot(p string) error { 105 p = filepath.Clean(convertSlash(p)) 106 if p == "/" { 107 return fmt.Errorf("invalid specification: destination can't be '/'") 108 } 109 return nil 110 } 111 112 func validateCopyMode(mode bool) error { 113 return nil 114 } 115 116 func convertSlash(p string) string { 117 return filepath.ToSlash(p) 118 } 119 120 func splitRawSpec(raw string) ([]string, error) { 121 if strings.Count(raw, ":") > 2 { 122 return nil, errInvalidSpec(raw) 123 } 124 125 arr := strings.SplitN(raw, ":", 3) 126 if arr[0] == "" { 127 return nil, errInvalidSpec(raw) 128 } 129 return arr, nil 130 } 131 132 func clean(p string) string { 133 return filepath.Clean(p) 134 } 135 136 func validateStat(fi os.FileInfo) error { 137 return nil 138 }