aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lu <chris.lu@gmail.com>2014-07-20 23:12:49 -0700
committerChris Lu <chris.lu@gmail.com>2014-07-20 23:12:49 -0700
commit77fd5ecd982ddb32affd6911b4808e4bf5d28dc8 (patch)
tree4f621ef75363f0f4703016baeb83a50aa0f8437b
parent8e7f08d04daa6c80a1790e8d86bad149e9fb14b6 (diff)
downloadseaweedfs-77fd5ecd982ddb32affd6911b4808e4bf5d28dc8.tar.xz
seaweedfs-77fd5ecd982ddb32affd6911b4808e4bf5d28dc8.zip
Add /admin/mv to move a file or a folder
-rw-r--r--go/filer/directory_in_map.go16
-rw-r--r--go/filer/directory_test.go60
-rw-r--r--go/filer/filer.go2
-rw-r--r--go/filer/filer_embedded.go33
-rw-r--r--go/filer/files_in_leveldb.go7
-rw-r--r--go/images/resizing.go4
-rw-r--r--go/weed/weed_server/filer_server.go1
-rw-r--r--go/weed/weed_server/filer_server_handlers_admin.go28
-rw-r--r--go/weed/weed_server/master_server_handlers_admin.go2
9 files changed, 119 insertions, 34 deletions
diff --git a/go/filer/directory_in_map.go b/go/filer/directory_in_map.go
index d288f3502..9c2ecdf80 100644
--- a/go/filer/directory_in_map.go
+++ b/go/filer/directory_in_map.go
@@ -81,7 +81,11 @@ func (dm *DirectoryManagerInMap) processEachLine(line string) error {
return e
}
case "mov":
- if e := dm.MoveUnderDirectory(parts[1], parts[2]); e != nil {
+ newName := ""
+ if len(parts) >= 4 {
+ newName = parts[3]
+ }
+ if e := dm.MoveUnderDirectory(parts[1], parts[2], newName); e != nil {
return e
}
case "del":
@@ -188,7 +192,7 @@ func (dm *DirectoryManagerInMap) MakeDirectory(dirPath string) (DirectoryId, err
return dir.Id, nil
}
-func (dm *DirectoryManagerInMap) MoveUnderDirectory(oldDirPath string, newParentDirPath string) error {
+func (dm *DirectoryManagerInMap) MoveUnderDirectory(oldDirPath string, newParentDirPath string, newName string) error {
oldDir, oe := dm.findDirectory(oldDirPath)
if oe != nil {
return oe
@@ -197,10 +201,14 @@ func (dm *DirectoryManagerInMap) MoveUnderDirectory(oldDirPath string, newParent
if pe != nil {
return pe
}
+ dm.log("mov", oldDirPath, newParentDirPath, newName)
delete(oldDir.Parent.SubDirectories, oldDir.Name)
- parentDir.SubDirectories[oldDir.Name] = oldDir
+ if newName == "" {
+ newName = oldDir.Name
+ }
+ parentDir.SubDirectories[newName] = oldDir
+ oldDir.Name = newName
oldDir.Parent = parentDir
- dm.log("mov", oldDirPath, newParentDirPath)
return nil
}
diff --git a/go/filer/directory_test.go b/go/filer/directory_test.go
index bfd1493e5..40c53755b 100644
--- a/go/filer/directory_test.go
+++ b/go/filer/directory_test.go
@@ -7,38 +7,44 @@ import (
)
func TestDirectory(t *testing.T) {
- {
- dm, _ := NewDirectoryManagerInMap("/tmp/dir.log")
- dm.MakeDirectory("/a/b/c")
- dm.MakeDirectory("/a/b/d")
- dm.MakeDirectory("/a/b/e")
- dm.MakeDirectory("/a/b/e/f")
- dm.MakeDirectory("/a/b/e/f/g")
- dm.MoveUnderDirectory("/a/b/e/f/g", "/a/b")
- dm.MakeDirectory("/a/b/g/h/i")
- dm.DeleteDirectory("/a/b/e/f")
- dm.DeleteDirectory("/a/b/e")
- dirNames, _ := dm.ListDirectories("/a/b/e")
- for _, v := range dirNames {
- println("sub1 dir:", v.Name, "id", v.Id)
+ dm, _ := NewDirectoryManagerInMap("/tmp/dir.log")
+ defer func() {
+ if true {
+ os.Remove("/tmp/dir.log")
}
- dm.logFile.Close()
+ }()
+ dm.MakeDirectory("/a/b/c")
+ dm.MakeDirectory("/a/b/d")
+ dm.MakeDirectory("/a/b/e")
+ dm.MakeDirectory("/a/b/e/f")
+ dm.MakeDirectory("/a/b/e/f/g")
+ dm.MoveUnderDirectory("/a/b/e/f/g", "/a/b")
+ if _, err := dm.FindDirectory("/a/b/e/f/g"); err == nil {
+ t.Fatal("/a/b/e/f/g should not exist any more after moving")
+ }
+ if _, err := dm.FindDirectory("/a/b/g"); err != nil {
+ t.Fatal("/a/b/g should exist after moving")
+ }
+ dm.MakeDirectory("/a/b/g/h/i")
+ dm.DeleteDirectory("/a/b/e/f")
+ dm.DeleteDirectory("/a/b/e")
+ dirNames, _ := dm.ListDirectories("/a/b/e")
+ for _, v := range dirNames {
+ println("sub1 dir:", v.Name, "id", v.Id)
+ }
+ dm.logFile.Close()
- var path []string
- printTree(dm.Root, path)
+ var path []string
+ printTree(dm.Root, path)
- dm2, e := NewDirectoryManagerInMap("/tmp/dir.log")
- if e != nil {
- println("load error", e.Error())
- }
- if !compare(dm.Root, dm2.Root) {
- t.Fatal("restored dir not the same!")
- }
- printTree(dm2.Root, path)
+ dm2, e := NewDirectoryManagerInMap("/tmp/dir.log")
+ if e != nil {
+ println("load error", e.Error())
}
- if true {
- os.Remove("/tmp/dir.log")
+ if !compare(dm.Root, dm2.Root) {
+ t.Fatal("restored dir not the same!")
}
+ printTree(dm2.Root, path)
}
func printTree(node *DirectoryEntryInMap, path []string) {
diff --git a/go/filer/filer.go b/go/filer/filer.go
index 8d2da901b..de877fc1f 100644
--- a/go/filer/filer.go
+++ b/go/filer/filer.go
@@ -12,8 +12,10 @@ type FileEntry struct {
type Filer interface {
CreateFile(filePath string, fid string) (err error)
FindFile(filePath string) (fid string, err error)
+ FindDirectory(dirPath string) (dirId DirectoryId, err error)
ListDirectories(dirPath string) (dirs []DirectoryEntry, err error)
ListFiles(dirPath string, lastFileName string, limit int) (files []FileEntry, err error)
DeleteDirectory(dirPath string, recursive bool) (err error)
DeleteFile(filePath string) (fid string, err error)
+ Move(fromPath string, toPath string) (err error)
}
diff --git a/go/filer/filer_embedded.go b/go/filer/filer_embedded.go
index 2a13805e9..a3b64d37b 100644
--- a/go/filer/filer_embedded.go
+++ b/go/filer/filer_embedded.go
@@ -47,6 +47,9 @@ func (filer *FilerEmbedded) FindFile(filePath string) (fid string, err error) {
}
return filer.files.FindFile(dirId, file)
}
+func (filer *FilerEmbedded) FindDirectory(dirPath string) (dirId DirectoryId, err error) {
+ return filer.directories.FindDirectory(dirPath)
+}
func (filer *FilerEmbedded) ListDirectories(dirPath string) (dirs []DirectoryEntry, err error) {
return filer.directories.ListDirectories(dirPath)
}
@@ -98,6 +101,7 @@ func (filer *FilerEmbedded) DeleteDirectory(dirPath string, recursive bool) (err
}
}
+
func (filer *FilerEmbedded) DeleteFile(filePath string) (fid string, err error) {
dir, file := filepath.Split(filePath)
dirId, e := filer.directories.FindDirectory(dir)
@@ -106,3 +110,32 @@ func (filer *FilerEmbedded) DeleteFile(filePath string) (fid string, err error)
}
return filer.files.DeleteFile(dirId, file)
}
+
+/*
+Move a folder or a file, with 4 Use cases:
+mv fromDir toNewDir
+mv fromDir toOldDir
+mv fromFile toDir
+mv fromFile toFile
+*/
+func (filer *FilerEmbedded) Move(fromPath string, toPath string) error {
+ if _, dir_err := filer.FindDirectory(fromPath); dir_err == nil {
+ if _, err := filer.FindDirectory(toPath); err == nil {
+ // move folder under an existing folder
+ return filer.directories.MoveUnderDirectory(fromPath, toPath, "")
+ } else {
+ // move folder to a new folder
+ return filer.directories.MoveUnderDirectory(fromPath, filepath.Dir(toPath), filepath.Base(toPath))
+ }
+ }
+ if fid, file_err := filer.DeleteFile(fromPath); file_err == nil {
+ if _, err := filer.FindDirectory(toPath); err == nil {
+ // move file under an existing folder
+ return filer.CreateFile(filepath.Join(toPath, filepath.Base(fromPath)), fid)
+ } else {
+ // move to a folder with new name
+ return filer.CreateFile(toPath, fid)
+ }
+ }
+ return fmt.Errorf("File %s is not found!", fromPath)
+}
diff --git a/go/filer/files_in_leveldb.go b/go/filer/files_in_leveldb.go
index aef43a7c3..dbf2e6c52 100644
--- a/go/filer/files_in_leveldb.go
+++ b/go/filer/files_in_leveldb.go
@@ -7,6 +7,13 @@ import (
"github.com/syndtr/goleveldb/leveldb/util"
)
+/*
+The entry in level db has this format:
+ key: genKey(dirId, fileName)
+ value: []byte(fid)
+And genKey(dirId, fileName) use first 4 bytes to store dirId, and rest for fileName
+*/
+
type FileListInLevelDb struct {
db *leveldb.DB
}
diff --git a/go/images/resizing.go b/go/images/resizing.go
index 7e21db70b..08a1e15d2 100644
--- a/go/images/resizing.go
+++ b/go/images/resizing.go
@@ -23,8 +23,8 @@ func Resized(ext string, data []byte, width, height int) (resized []byte, w int,
} else {
dstImage = imaging.Resize(srcImage, width, height, imaging.Lanczos)
}
- }else{
- return data, bounds.Dx(), bounds.Dy()
+ } else {
+ return data, bounds.Dx(), bounds.Dy()
}
var buf bytes.Buffer
switch ext {
diff --git a/go/weed/weed_server/filer_server.go b/go/weed/weed_server/filer_server.go
index 996de5020..e56cb5964 100644
--- a/go/weed/weed_server/filer_server.go
+++ b/go/weed/weed_server/filer_server.go
@@ -26,6 +26,7 @@ func NewFilerServer(r *http.ServeMux, port int, master string, dir string, colle
return
}
+ r.HandleFunc("/admin/mv", fs.moveHandler)
r.HandleFunc("/", fs.filerHandler)
return fs, nil
diff --git a/go/weed/weed_server/filer_server_handlers_admin.go b/go/weed/weed_server/filer_server_handlers_admin.go
new file mode 100644
index 000000000..08b0e336e
--- /dev/null
+++ b/go/weed/weed_server/filer_server_handlers_admin.go
@@ -0,0 +1,28 @@
+package weed_server
+
+import (
+ "code.google.com/p/weed-fs/go/glog"
+ "net/http"
+)
+
+/*
+Move a folder or a file, with 4 Use cases:
+mv fromDir toNewDir
+mv fromDir toOldDir
+mv fromFile toDir
+mv fromFile toFile
+
+Wildcard is not supported.
+
+*/
+func (fs *FilerServer) moveHandler(w http.ResponseWriter, r *http.Request) {
+ from := r.FormValue("from")
+ to := r.FormValue("to")
+ err := fs.filer.Move(from, to)
+ if err != nil {
+ glog.V(4).Infoln("moving", from, "->", to, err.Error())
+ writeJsonError(w, r, err)
+ } else {
+ w.WriteHeader(http.StatusOK)
+ }
+}
diff --git a/go/weed/weed_server/master_server_handlers_admin.go b/go/weed/weed_server/master_server_handlers_admin.go
index bd6747e99..d50075fd5 100644
--- a/go/weed/weed_server/master_server_handlers_admin.go
+++ b/go/weed/weed_server/master_server_handlers_admin.go
@@ -99,7 +99,7 @@ func (ms *MasterServer) volumeGrowHandler(w http.ResponseWriter, r *http.Request
w.WriteHeader(http.StatusNotAcceptable)
writeJsonQuiet(w, r, map[string]string{"error": err.Error()})
} else {
- w.WriteHeader(http.StatusNotAcceptable)
+ w.WriteHeader(http.StatusOK)
writeJsonQuiet(w, r, map[string]interface{}{"count": count})
}
}