aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lu <chris.lu@gmail.com>2019-07-11 09:29:04 -0700
committerChris Lu <chris.lu@gmail.com>2019-07-11 09:29:04 -0700
commit9e47c4749a20822db454467518f67b8ff720bb99 (patch)
treefd70f83166b57b4fb913371ab57f9a74961570e2
parent1d1b355f9ea48492dcba938f6b3457a5115cff41 (diff)
downloadseaweedfs-9e47c4749a20822db454467518f67b8ff720bb99.tar.xz
seaweedfs-9e47c4749a20822db454467518f67b8ff720bb99.zip
shell: add fs.mv
fix https://github.com/chrislusf/seaweedfs/issues/954
-rw-r--r--weed/server/filer_grpc_server_rename.go5
-rw-r--r--weed/shell/command_fs_mv.go96
2 files changed, 101 insertions, 0 deletions
diff --git a/weed/server/filer_grpc_server_rename.go b/weed/server/filer_grpc_server_rename.go
index 568b10428..7142f7606 100644
--- a/weed/server/filer_grpc_server_rename.go
+++ b/weed/server/filer_grpc_server_rename.go
@@ -96,6 +96,11 @@ func (fs *FilerServer) moveSelfEntry(ctx context.Context, oldParent filer2.FullP
glog.V(1).Infof("moving entry %s => %s", oldPath, newPath)
+ if oldPath == newPath {
+ glog.V(1).Infof("skip moving entry %s => %s", oldPath, newPath)
+ return nil
+ }
+
// add to new directory
newEntry := &filer2.Entry{
FullPath: newPath,
diff --git a/weed/shell/command_fs_mv.go b/weed/shell/command_fs_mv.go
new file mode 100644
index 000000000..130bfe4e7
--- /dev/null
+++ b/weed/shell/command_fs_mv.go
@@ -0,0 +1,96 @@
+package shell
+
+import (
+ "context"
+ "fmt"
+ "io"
+ "path/filepath"
+
+ "github.com/chrislusf/seaweedfs/weed/filer2"
+ "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
+)
+
+func init() {
+ Commands = append(Commands, &commandFsMv{})
+}
+
+type commandFsMv struct {
+}
+
+func (c *commandFsMv) Name() string {
+ return "fs.mv"
+}
+
+func (c *commandFsMv) Help() string {
+ return `move or rename a file or a folder
+
+ fs.mv <source entry> <destination entry>
+
+ fs.mv /dir/file_name /dir2/filename2
+ fs.mv /dir/file_name /dir2
+
+ fs.mv /dir/dir2 /dir3/dir4/
+ fs.mv /dir/dir2 /dir3/new_dir
+
+`
+}
+
+func (c *commandFsMv) Do(args []string, commandEnv *CommandEnv, writer io.Writer) (err error) {
+
+ filerServer, filerPort, sourcePath, err := commandEnv.parseUrl(args[0])
+ if err != nil {
+ return err
+ }
+
+ _, _, destinationPath, err := commandEnv.parseUrl(args[1])
+ if err != nil {
+ return err
+ }
+
+ ctx := context.Background()
+
+
+ sourceDir, sourceName := filer2.FullPath(sourcePath).DirAndName()
+
+ destinationDir, destinationName := filer2.FullPath(destinationPath).DirAndName()
+
+
+ return commandEnv.withFilerClient(ctx, filerServer, filerPort, func(client filer_pb.SeaweedFilerClient) error {
+
+ // collect destination entry info
+ destinationRequest := &filer_pb.LookupDirectoryEntryRequest{
+ Name: destinationDir,
+ Directory: destinationName,
+ }
+ respDestinationLookupEntry, err := client.LookupDirectoryEntry(ctx, destinationRequest)
+
+ var targetDir, targetName string
+
+ // moving a file or folder
+ if err == nil && respDestinationLookupEntry.Entry.IsDirectory {
+ // to a directory
+ targetDir = filepath.ToSlash(filepath.Join(destinationDir, destinationName))
+ targetName = sourceName
+ } else {
+ // to a file or folder
+ targetDir = destinationDir
+ targetName = destinationName
+ }
+
+
+ request := &filer_pb.AtomicRenameEntryRequest{
+ OldDirectory: sourceDir,
+ OldName: sourceName,
+ NewDirectory: targetDir,
+ NewName: targetName,
+ }
+
+ _, err = client.AtomicRenameEntry(ctx, request)
+
+ fmt.Fprintf(writer, "move: %s => %s\n", sourcePath, filer2.NewFullPath(targetDir, targetName))
+
+ return err
+
+ })
+
+}