You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

165 lines
4.5 KiB

  1. package command
  2. import (
  3. "fmt"
  4. "strings"
  5. "strconv"
  6. "time"
  7. "os"
  8. )
  9. func init() {
  10. cmdFuse.Run = runFuse // break init cycle
  11. }
  12. func runFuse(cmd *Command, args []string) bool {
  13. argsLen := len(args)
  14. options := []string{}
  15. // at least target mount path should be passed
  16. if argsLen < 1 {
  17. return false
  18. }
  19. // first option is always target mount path
  20. mountOptions.dir = &args[0]
  21. // scan parameters looking for one or more -o options
  22. // -o options receive parameters on format key=value[,key=value]...
  23. for i := 0; i < argsLen; i++ {
  24. if args[i] == "-o" && i+1 <= argsLen {
  25. options = strings.Split(args[i+1], ",")
  26. i++
  27. }
  28. }
  29. // for each option passed with -o
  30. for _, option := range options {
  31. // split just first = character
  32. parts := strings.SplitN(option, "=", 2)
  33. // if doesn't key and value skip
  34. if len(parts) != 2 {
  35. continue
  36. }
  37. key, value := parts[0], parts[1]
  38. // switch key keeping "weed mount" parameters
  39. switch key {
  40. case "filer":
  41. mountOptions.filer = &value
  42. case "filer.path":
  43. mountOptions.filerMountRootPath = &value
  44. case "dirAutoCreate":
  45. if parsed, err := strconv.ParseBool(value); err != nil {
  46. mountOptions.dirAutoCreate = &parsed
  47. } else {
  48. panic(fmt.Errorf("dirAutoCreate: %s", err))
  49. }
  50. case "collection":
  51. mountOptions.collection = &value
  52. case "replication":
  53. mountOptions.replication = &value
  54. case "disk":
  55. mountOptions.diskType = &value
  56. case "ttl":
  57. if parsed, err := strconv.ParseInt(value, 0, 32); err != nil {
  58. intValue := int(parsed)
  59. mountOptions.ttlSec = &intValue
  60. } else {
  61. panic(fmt.Errorf("ttl: %s", err))
  62. }
  63. case "chunkSizeLimitMB":
  64. if parsed, err := strconv.ParseInt(value, 0, 32); err != nil {
  65. intValue := int(parsed)
  66. mountOptions.chunkSizeLimitMB = &intValue
  67. } else {
  68. panic(fmt.Errorf("chunkSizeLimitMB: %s", err))
  69. }
  70. case "concurrentWriters":
  71. if parsed, err := strconv.ParseInt(value, 0, 32); err != nil {
  72. intValue := int(parsed)
  73. mountOptions.concurrentWriters = &intValue
  74. } else {
  75. panic(fmt.Errorf("concurrentWriters: %s", err))
  76. }
  77. case "cacheDir":
  78. mountOptions.cacheDir = &value
  79. case "cacheCapacityMB":
  80. if parsed, err := strconv.ParseInt(value, 0, 64); err != nil {
  81. mountOptions.cacheSizeMB = &parsed
  82. } else {
  83. panic(fmt.Errorf("cacheCapacityMB: %s", err))
  84. }
  85. case "dataCenter":
  86. mountOptions.dataCenter = &value
  87. case "allowOthers":
  88. if parsed, err := strconv.ParseBool(value); err != nil {
  89. mountOptions.allowOthers = &parsed
  90. } else {
  91. panic(fmt.Errorf("allowOthers: %s", err))
  92. }
  93. case "umask":
  94. mountOptions.umaskString = &value
  95. case "nonempty":
  96. if parsed, err := strconv.ParseBool(value); err != nil {
  97. mountOptions.nonempty = &parsed
  98. } else {
  99. panic(fmt.Errorf("nonempty: %s", err))
  100. }
  101. case "volumeServerAccess":
  102. mountOptions.volumeServerAccess = &value
  103. case "map.uid":
  104. mountOptions.uidMap = &value
  105. case "map.gid":
  106. mountOptions.gidMap = &value
  107. case "readOnly":
  108. if parsed, err := strconv.ParseBool(value); err != nil {
  109. mountOptions.readOnly = &parsed
  110. } else {
  111. panic(fmt.Errorf("readOnly: %s", err))
  112. }
  113. case "cpuprofile":
  114. mountCpuProfile = &value
  115. case "memprofile":
  116. mountMemProfile = &value
  117. case "readRetryTime":
  118. if parsed, err := time.ParseDuration(value); err != nil {
  119. mountReadRetryTime = &parsed
  120. } else {
  121. panic(fmt.Errorf("readRetryTime: %s", err))
  122. }
  123. }
  124. }
  125. // I don't know why PATH environment variable is lost
  126. if err := os.Setenv("PATH", "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"); err != nil {
  127. panic(fmt.Errorf("setenv: %s", err))
  128. }
  129. // just call "weed mount" command
  130. return runMount(cmdMount, []string{})
  131. }
  132. var cmdFuse = &Command{
  133. UsageLine: "fuse /mnt/mount/point -o \"filer=localhost:8888,filer.path=/\"",
  134. Short: "Allow use weed with linux's mount command",
  135. Long: `Allow use weed with linux's mount command
  136. You can use -t weed on mount command:
  137. mv weed /sbin/mount.weed
  138. mount -t weed fuse /mnt -o "filer=localhost:8888,filer.path=/"
  139. Or you can use -t fuse on mount command:
  140. mv weed /sbin/weed
  141. mount -t fuse.weed fuse /mnt -o "filer=localhost:8888,filer.path=/"
  142. mount -t fuse "weed#fuse" /mnt -o "filer=localhost:8888,filer.path=/"
  143. To use without mess with your /sbin:
  144. mount -t fuse./home/user/bin/weed fuse /mnt -o "filer=localhost:8888,filer.path=/"
  145. mount -t fuse "/home/user/bin/weed#fuse" /mnt -o "filer=localhost:8888,filer.path=/"
  146. To check valid options look "weed mount --help"
  147. `,
  148. }