volume_unix.go 3.3 KB

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