aboutsummaryrefslogtreecommitdiff
path: root/weed/command
diff options
context:
space:
mode:
authorhilimd <68371223+hilimd@users.noreply.github.com>2021-05-27 15:48:38 +0800
committerGitHub <noreply@github.com>2021-05-27 15:48:38 +0800
commitff26e646481a832ff6b75b5efa084935ed1a739b (patch)
treee39c62671768cd64e34549aeb6767acc0f965604 /weed/command
parent9524b08becce1e21d5da08884333de3b011f8e4a (diff)
parent45bffc92a8e1cf42fdacb20824223e0e4df710f0 (diff)
downloadseaweedfs-ff26e646481a832ff6b75b5efa084935ed1a739b.tar.xz
seaweedfs-ff26e646481a832ff6b75b5efa084935ed1a739b.zip
Merge pull request #78 from chrislusf/master
sync
Diffstat (limited to 'weed/command')
-rw-r--r--weed/command/command.go1
-rw-r--r--weed/command/fuse.go165
-rw-r--r--weed/command/mount.go2
-rw-r--r--weed/command/mount_std.go20
-rw-r--r--weed/command/scaffold.go11
5 files changed, 182 insertions, 17 deletions
diff --git a/weed/command/command.go b/weed/command/command.go
index b6efcead2..18e53ad8c 100644
--- a/weed/command/command.go
+++ b/weed/command/command.go
@@ -22,6 +22,7 @@ var Commands = []*Command{
cmdFilerReplicate,
cmdFilerSynchronize,
cmdFix,
+ cmdFuse,
cmdGateway,
cmdMaster,
cmdMount,
diff --git a/weed/command/fuse.go b/weed/command/fuse.go
new file mode 100644
index 000000000..0a55e509c
--- /dev/null
+++ b/weed/command/fuse.go
@@ -0,0 +1,165 @@
+package command
+
+import (
+ "fmt"
+ "strings"
+ "strconv"
+ "time"
+ "os"
+)
+
+func init() {
+ cmdFuse.Run = runFuse // break init cycle
+}
+
+func runFuse(cmd *Command, args []string) bool {
+ argsLen := len(args)
+ options := []string{}
+
+ // at least target mount path should be passed
+ if argsLen < 1 {
+ return false
+ }
+
+ // first option is always target mount path
+ mountOptions.dir = &args[0]
+
+ // scan parameters looking for one or more -o options
+ // -o options receive parameters on format key=value[,key=value]...
+ for i := 0; i < argsLen; i++ {
+ if args[i] == "-o" && i+1 <= argsLen {
+ options = strings.Split(args[i+1], ",")
+ i++
+ }
+ }
+
+ // for each option passed with -o
+ for _, option := range options {
+ // split just first = character
+ parts := strings.SplitN(option, "=", 2)
+
+ // if doesn't key and value skip
+ if len(parts) != 2 {
+ continue
+ }
+
+ key, value := parts[0], parts[1]
+
+ // switch key keeping "weed mount" parameters
+ switch key {
+ case "filer":
+ mountOptions.filer = &value
+ case "filer.path":
+ mountOptions.filerMountRootPath = &value
+ case "dirAutoCreate":
+ if parsed, err := strconv.ParseBool(value); err != nil {
+ mountOptions.dirAutoCreate = &parsed
+ } else {
+ panic(fmt.Errorf("dirAutoCreate: %s", err))
+ }
+ case "collection":
+ mountOptions.collection = &value
+ case "replication":
+ mountOptions.replication = &value
+ case "disk":
+ mountOptions.diskType = &value
+ case "ttl":
+ if parsed, err := strconv.ParseInt(value, 0, 32); err != nil {
+ intValue := int(parsed)
+ mountOptions.ttlSec = &intValue
+ } else {
+ panic(fmt.Errorf("ttl: %s", err))
+ }
+ case "chunkSizeLimitMB":
+ if parsed, err := strconv.ParseInt(value, 0, 32); err != nil {
+ intValue := int(parsed)
+ mountOptions.chunkSizeLimitMB = &intValue
+ } else {
+ panic(fmt.Errorf("chunkSizeLimitMB: %s", err))
+ }
+ case "concurrentWriters":
+ if parsed, err := strconv.ParseInt(value, 0, 32); err != nil {
+ intValue := int(parsed)
+ mountOptions.concurrentWriters = &intValue
+ } else {
+ panic(fmt.Errorf("concurrentWriters: %s", err))
+ }
+ case "cacheDir":
+ mountOptions.cacheDir = &value
+ case "cacheCapacityMB":
+ if parsed, err := strconv.ParseInt(value, 0, 64); err != nil {
+ mountOptions.cacheSizeMB = &parsed
+ } else {
+ panic(fmt.Errorf("cacheCapacityMB: %s", err))
+ }
+ case "dataCenter":
+ mountOptions.dataCenter = &value
+ case "allowOthers":
+ if parsed, err := strconv.ParseBool(value); err != nil {
+ mountOptions.allowOthers = &parsed
+ } else {
+ panic(fmt.Errorf("allowOthers: %s", err))
+ }
+ case "umask":
+ mountOptions.umaskString = &value
+ case "nonempty":
+ if parsed, err := strconv.ParseBool(value); err != nil {
+ mountOptions.nonempty = &parsed
+ } else {
+ panic(fmt.Errorf("nonempty: %s", err))
+ }
+ case "volumeServerAccess":
+ mountOptions.volumeServerAccess = &value
+ case "map.uid":
+ mountOptions.uidMap = &value
+ case "map.gid":
+ mountOptions.gidMap = &value
+ case "readOnly":
+ if parsed, err := strconv.ParseBool(value); err != nil {
+ mountOptions.readOnly = &parsed
+ } else {
+ panic(fmt.Errorf("readOnly: %s", err))
+ }
+ case "cpuprofile":
+ mountCpuProfile = &value
+ case "memprofile":
+ mountMemProfile = &value
+ case "readRetryTime":
+ if parsed, err := time.ParseDuration(value); err != nil {
+ mountReadRetryTime = &parsed
+ } else {
+ panic(fmt.Errorf("readRetryTime: %s", err))
+ }
+ }
+ }
+
+ // I don't know why PATH environment variable is lost
+ if err := os.Setenv("PATH", "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"); err != nil {
+ panic(fmt.Errorf("setenv: %s", err))
+ }
+
+ // just call "weed mount" command
+ return runMount(cmdMount, []string{})
+}
+
+var cmdFuse = &Command{
+ UsageLine: "fuse /mnt/mount/point -o \"filer=localhost:8888,filer.path=/\"",
+ Short: "Allow use weed with linux's mount command",
+ Long: `Allow use weed with linux's mount command
+
+ You can use -t weed on mount command:
+ mv weed /sbin/mount.weed
+ mount -t weed fuse /mnt -o "filer=localhost:8888,filer.path=/"
+
+ Or you can use -t fuse on mount command:
+ mv weed /sbin/weed
+ mount -t fuse.weed fuse /mnt -o "filer=localhost:8888,filer.path=/"
+ mount -t fuse "weed#fuse" /mnt -o "filer=localhost:8888,filer.path=/"
+
+ To use without mess with your /sbin:
+ mount -t fuse./home/user/bin/weed fuse /mnt -o "filer=localhost:8888,filer.path=/"
+ mount -t fuse "/home/user/bin/weed#fuse" /mnt -o "filer=localhost:8888,filer.path=/"
+
+ To check valid options look "weed mount --help"
+ `,
+}
diff --git a/weed/command/mount.go b/weed/command/mount.go
index 5811f0b99..aec5fcc3c 100644
--- a/weed/command/mount.go
+++ b/weed/command/mount.go
@@ -37,7 +37,7 @@ var (
func init() {
cmdMount.Run = runMount // break init cycle
- mountOptions.filer = cmdMount.Flag.String("filer", "localhost:8888", "weed filer location")
+ mountOptions.filer = cmdMount.Flag.String("filer", "localhost:8888", "comma-separated weed filer location")
mountOptions.filerMountRootPath = cmdMount.Flag.String("filer.path", "/", "mount this remote path from filer server")
mountOptions.dir = cmdMount.Flag.String("dir", ".", "mount weed filer to this directory")
mountOptions.dirAutoCreate = cmdMount.Flag.Bool("dirAutoCreate", false, "auto create the directory to mount to")
diff --git a/weed/command/mount_std.go b/weed/command/mount_std.go
index 2474cf7dd..e72a2f2cf 100644
--- a/weed/command/mount_std.go
+++ b/weed/command/mount_std.go
@@ -51,9 +51,9 @@ func runMount(cmd *Command, args []string) bool {
func RunMount(option *MountOptions, umask os.FileMode) bool {
- filer := *option.filer
+ filers := strings.Split(*option.filer, ",")
// parse filer grpc address
- filerGrpcAddress, err := pb.ParseServerToGrpcAddress(filer)
+ filerGrpcAddresses, err := pb.ParseServersToGrpcAddresses(filers)
if err != nil {
glog.V(0).Infof("ParseFilerGrpcAddress: %v", err)
return true
@@ -64,22 +64,22 @@ func RunMount(option *MountOptions, umask os.FileMode) bool {
grpcDialOption := security.LoadClientTLS(util.GetViper(), "grpc.client")
var cipher bool
for i := 0; i < 10; i++ {
- err = pb.WithGrpcFilerClient(filerGrpcAddress, grpcDialOption, func(client filer_pb.SeaweedFilerClient) error {
+ err = pb.WithOneOfGrpcFilerClients(filerGrpcAddresses, grpcDialOption, func(client filer_pb.SeaweedFilerClient) error {
resp, err := client.GetFilerConfiguration(context.Background(), &filer_pb.GetFilerConfigurationRequest{})
if err != nil {
- return fmt.Errorf("get filer grpc address %s configuration: %v", filerGrpcAddress, err)
+ return fmt.Errorf("get filer grpc address %v configuration: %v", filerGrpcAddresses, err)
}
cipher = resp.Cipher
return nil
})
if err != nil {
- glog.V(0).Infof("failed to talk to filer %s: %v", filerGrpcAddress, err)
+ glog.V(0).Infof("failed to talk to filer %v: %v", filerGrpcAddresses, err)
glog.V(0).Infof("wait for %d seconds ...", i+1)
time.Sleep(time.Duration(i+1) * time.Second)
}
}
if err != nil {
- glog.Errorf("failed to talk to filer %s: %v", filerGrpcAddress, err)
+ glog.Errorf("failed to talk to filer %v: %v", filerGrpcAddresses, err)
return true
}
@@ -145,7 +145,7 @@ func RunMount(option *MountOptions, umask os.FileMode) bool {
options := []fuse.MountOption{
fuse.VolumeName(mountName),
- fuse.FSName(filer + ":" + filerMountRootPath),
+ fuse.FSName(*option.filer + ":" + filerMountRootPath),
fuse.Subtype("seaweedfs"),
// fuse.NoAppleDouble(), // include .DS_Store, otherwise can not delete non-empty folders
fuse.NoAppleXattr(),
@@ -181,8 +181,8 @@ func RunMount(option *MountOptions, umask os.FileMode) bool {
seaweedFileSystem := filesys.NewSeaweedFileSystem(&filesys.Option{
MountDirectory: dir,
- FilerAddress: filer,
- FilerGrpcAddress: filerGrpcAddress,
+ FilerAddresses: filers,
+ FilerGrpcAddresses: filerGrpcAddresses,
GrpcDialOption: grpcDialOption,
FilerMountRootPath: mountRoot,
Collection: *option.collection,
@@ -218,7 +218,7 @@ func RunMount(option *MountOptions, umask os.FileMode) bool {
c.Close()
})
- glog.V(0).Infof("mounted %s%s to %s", filer, mountRoot, dir)
+ glog.V(0).Infof("mounted %s%s to %v", *option.filer, mountRoot, dir)
server := fs.New(c, nil)
seaweedFileSystem.Server = server
err = server.Serve(seaweedFileSystem)
diff --git a/weed/command/scaffold.go b/weed/command/scaffold.go
index 88dc94df1..806e18fbc 100644
--- a/weed/command/scaffold.go
+++ b/weed/command/scaffold.go
@@ -101,6 +101,11 @@ dir = "./filerldb3" # directory to store level db files
enabled = false
dir = "./filerrdb" # directory to store rocksdb files
+[sqlite]
+# local on disk, similar to leveldb
+enabled = false
+dbFile = "./filer.db" # sqlite db file
+
[mysql] # or memsql, tidb
# CREATE TABLE IF NOT EXISTS filemeta (
# dirhash BIGINT COMMENT 'first 64 bits of MD5 hash value of directory field',
@@ -372,12 +377,6 @@ directory = "/data"
# so each date directory contains all new and updated files.
is_incremental = false
-[sink.local_incremental]
-# all replicated files are under modified time as yyyy-mm-dd directories
-# so each date directory contains all new and updated files.
-enabled = false
-directory = "/backup"
-
[sink.filer]
enabled = false
grpcAddress = "localhost:18888"