volume_unix.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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. // consistency modes
  27. var consistencyModes = map[mounttypes.Consistency]bool{
  28. mounttypes.ConsistencyFull: true,
  29. mounttypes.ConsistencyCached: true,
  30. mounttypes.ConsistencyDelegated: true,
  31. }
  32. // BackwardsCompatible decides whether this mount point can be
  33. // used in old versions of Docker or not.
  34. // Only bind mounts and local volumes can be used in old versions of Docker.
  35. func (m *MountPoint) BackwardsCompatible() bool {
  36. return len(m.Source) > 0 || m.Driver == DefaultDriverName
  37. }
  38. // HasResource checks whether the given absolute path for a container is in
  39. // this mount point. If the relative path starts with `../` then the resource
  40. // is outside of this mount point, but we can't simply check for this prefix
  41. // because it misses `..` which is also outside of the mount, so check both.
  42. func (m *MountPoint) HasResource(absolutePath string) bool {
  43. relPath, err := filepath.Rel(m.Destination, absolutePath)
  44. return err == nil && relPath != ".." && !strings.HasPrefix(relPath, fmt.Sprintf("..%c", filepath.Separator))
  45. }
  46. // IsVolumeNameValid checks a volume name in a platform specific manner.
  47. func IsVolumeNameValid(name string) (bool, error) {
  48. return true, nil
  49. }
  50. // ValidMountMode will make sure the mount mode is valid.
  51. // returns if it's a valid mount mode or not.
  52. func ValidMountMode(mode string) bool {
  53. if mode == "" {
  54. return true
  55. }
  56. rwModeCount := 0
  57. labelModeCount := 0
  58. propagationModeCount := 0
  59. copyModeCount := 0
  60. consistencyModeCount := 0
  61. for _, o := range strings.Split(mode, ",") {
  62. switch {
  63. case rwModes[o]:
  64. rwModeCount++
  65. case labelModes[o]:
  66. labelModeCount++
  67. case propagationModes[mounttypes.Propagation(o)]:
  68. propagationModeCount++
  69. case copyModeExists(o):
  70. copyModeCount++
  71. case consistencyModes[mounttypes.Consistency(o)]:
  72. consistencyModeCount++
  73. default:
  74. return false
  75. }
  76. }
  77. // Only one string for each mode is allowed.
  78. if rwModeCount > 1 || labelModeCount > 1 || propagationModeCount > 1 || copyModeCount > 1 || consistencyModeCount > 1 {
  79. return false
  80. }
  81. return true
  82. }
  83. // ReadWrite tells you if a mode string is a valid read-write mode or not.
  84. // If there are no specifications w.r.t read write mode, then by default
  85. // it returns true.
  86. func ReadWrite(mode string) bool {
  87. if !ValidMountMode(mode) {
  88. return false
  89. }
  90. for _, o := range strings.Split(mode, ",") {
  91. if o == "ro" {
  92. return false
  93. }
  94. }
  95. return true
  96. }
  97. func validateNotRoot(p string) error {
  98. p = filepath.Clean(convertSlash(p))
  99. if p == "/" {
  100. return fmt.Errorf("invalid specification: destination can't be '/'")
  101. }
  102. return nil
  103. }
  104. func validateCopyMode(mode bool) error {
  105. return nil
  106. }
  107. func convertSlash(p string) string {
  108. return filepath.ToSlash(p)
  109. }
  110. func splitRawSpec(raw string) ([]string, error) {
  111. if strings.Count(raw, ":") > 2 {
  112. return nil, errInvalidSpec(raw)
  113. }
  114. arr := strings.SplitN(raw, ":", 3)
  115. if arr[0] == "" {
  116. return nil, errInvalidSpec(raw)
  117. }
  118. return arr, nil
  119. }
  120. func clean(p string) string {
  121. return filepath.Clean(p)
  122. }
  123. func validateStat(fi os.FileInfo) error {
  124. return nil
  125. }