Browse Source
releasing 0.58 to handle control+c interrupts.
releasing 0.58 to handle control+c interrupts.
compilable now. but FUSE mount is not working.pull/2/head
Chris Lu
11 years ago
8 changed files with 221 additions and 166 deletions
-
71go/filer/client_operations.go
-
58go/filer/operations.go
-
2go/util/constants.go
-
108go/weed/mount.go
-
15go/weed/mount_notsupported.go
-
112go/weed/mount_std.go
-
1go/weed/weed_server/filer_server.go
-
20go/weed/weed_server/filer_server_handlers_api.go
@ -0,0 +1,71 @@ |
|||||
|
package filer |
||||
|
|
||||
|
import () |
||||
|
|
||||
|
import ( |
||||
|
"code.google.com/p/weed-fs/go/util" |
||||
|
"encoding/json" |
||||
|
"errors" |
||||
|
"fmt" |
||||
|
"net/url" |
||||
|
) |
||||
|
|
||||
|
type ApiRequest struct { |
||||
|
Command string //"listFiles", "listDirectories"
|
||||
|
DirectoryId DirectoryId |
||||
|
FileName string |
||||
|
} |
||||
|
|
||||
|
type ListFilesResult struct { |
||||
|
Files []FileEntry |
||||
|
Error string `json:"error,omitempty"` |
||||
|
} |
||||
|
|
||||
|
func ListFiles(server string, directoryId DirectoryId, fileName string) (*ListFilesResult, error) { |
||||
|
var ret ListFilesResult |
||||
|
if err := call(server, ApiRequest{Command: "listFiles", DirectoryId: directoryId, FileName: fileName}, &ret); err == nil { |
||||
|
if ret.Error != "" { |
||||
|
return nil, errors.New(ret.Error) |
||||
|
} |
||||
|
return &ret, nil |
||||
|
} else { |
||||
|
return nil, err |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
type ListDirectoriesResult struct { |
||||
|
Directories []DirectoryEntry |
||||
|
Error string `json:"error,omitempty"` |
||||
|
} |
||||
|
|
||||
|
func ListDirectories(server string, directoryId DirectoryId) (*ListDirectoriesResult, error) { |
||||
|
var ret ListDirectoriesResult |
||||
|
if err := call(server, ApiRequest{Command: "listDirectories", DirectoryId: directoryId}, &ret); err == nil { |
||||
|
if ret.Error != "" { |
||||
|
return nil, errors.New(ret.Error) |
||||
|
} |
||||
|
return &ret, nil |
||||
|
} else { |
||||
|
return nil, err |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func call(server string, request ApiRequest, ret interface{}) error { |
||||
|
b, err := json.Marshal(request) |
||||
|
if err != nil { |
||||
|
fmt.Println("error:", err) |
||||
|
return nil |
||||
|
} |
||||
|
values := make(url.Values) |
||||
|
values.Add("request", string(b)) |
||||
|
jsonBlob, err := util.Post("http://"+server+"/__api__", values) |
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
err = json.Unmarshal(jsonBlob, ret) |
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
return nil |
||||
|
} |
||||
|
|
@ -1,58 +0,0 @@ |
|||||
package filer |
|
||||
|
|
||||
import () |
|
||||
|
|
||||
import ( |
|
||||
"code.google.com/p/weed-fs/go/util" |
|
||||
"encoding/json" |
|
||||
"errors" |
|
||||
_ "fmt" |
|
||||
"net/url" |
|
||||
"strconv" |
|
||||
) |
|
||||
|
|
||||
type ListFilesResult struct { |
|
||||
Files []FileEntry |
|
||||
Error string `json:"error,omitempty"` |
|
||||
} |
|
||||
|
|
||||
func ListFiles(server string, directoryId DirectoryId, fileName string) (*ListFilesResult, error) { |
|
||||
values := make(url.Values) |
|
||||
values.Add("directoryId", strconv.Itoa(int(directoryId))) |
|
||||
jsonBlob, err := util.Post("http://"+server+"/dir/lookup", values) |
|
||||
if err != nil { |
|
||||
return nil, err |
|
||||
} |
|
||||
var ret ListFilesResult |
|
||||
err = json.Unmarshal(jsonBlob, &ret) |
|
||||
if err != nil { |
|
||||
return nil, err |
|
||||
} |
|
||||
if ret.Error != "" { |
|
||||
return nil, errors.New(ret.Error) |
|
||||
} |
|
||||
return &ret, nil |
|
||||
} |
|
||||
|
|
||||
type ListDirectoriesResult struct { |
|
||||
Directories []DirectoryEntry |
|
||||
Error string `json:"error,omitempty"` |
|
||||
} |
|
||||
|
|
||||
func ListDirectories(server string, directoryId DirectoryId) (*ListDirectoriesResult, error) { |
|
||||
values := make(url.Values) |
|
||||
values.Add("directoryId", strconv.Itoa(int(directoryId))) |
|
||||
jsonBlob, err := util.Post("http://"+server+"/dir/lookup", values) |
|
||||
if err != nil { |
|
||||
return nil, err |
|
||||
} |
|
||||
var ret ListDirectoriesResult |
|
||||
err = json.Unmarshal(jsonBlob, &ret) |
|
||||
if err != nil { |
|
||||
return nil, err |
|
||||
} |
|
||||
if ret.Error != "" { |
|
||||
return nil, errors.New(ret.Error) |
|
||||
} |
|
||||
return &ret, nil |
|
||||
} |
|
@ -0,0 +1,15 @@ |
|||||
|
// +build !linux
|
||||
|
// +build !darwin
|
||||
|
|
||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"fmt" |
||||
|
"runtime" |
||||
|
) |
||||
|
|
||||
|
func runMount(cmd *Command, args []string) bool { |
||||
|
fmt.Printf("Mount is not supported on %s %s\n", runtime.GOOS, runtime.GOARCH) |
||||
|
|
||||
|
return true |
||||
|
} |
@ -0,0 +1,112 @@ |
|||||
|
// +build linux darwin
|
||||
|
|
||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"bazil.org/fuse" |
||||
|
"bazil.org/fuse/fs" |
||||
|
"code.google.com/p/weed-fs/go/filer" |
||||
|
"code.google.com/p/weed-fs/go/glog" |
||||
|
"code.google.com/p/weed-fs/go/storage" |
||||
|
"code.google.com/p/weed-fs/go/util" |
||||
|
"fmt" |
||||
|
"os" |
||||
|
"os/signal" |
||||
|
"runtime" |
||||
|
) |
||||
|
|
||||
|
func runMount(cmd *Command, args []string) bool { |
||||
|
fmt.Printf("This is Weed File System version %s %s %s\n", util.VERSION, runtime.GOOS, runtime.GOARCH) |
||||
|
if *mountOptions.dir == "" { |
||||
|
fmt.Printf("Please specify the mount directory via \"-dir\"") |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
c, err := fuse.Mount(*mountOptions.dir) |
||||
|
if err != nil { |
||||
|
glog.Fatal(err) |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
signalChan := make(chan os.Signal, 1) |
||||
|
signal.Notify(signalChan, os.Interrupt) |
||||
|
go func() { |
||||
|
for _ = range signalChan { |
||||
|
// sig is a ^C, handle it
|
||||
|
fuse.Unmount(*mountOptions.dir) |
||||
|
c.Close() |
||||
|
os.Exit(0) |
||||
|
} |
||||
|
}() |
||||
|
|
||||
|
err = fs.Serve(c, WFS{}) |
||||
|
if err != nil { |
||||
|
fuse.Unmount(*mountOptions.dir) |
||||
|
} |
||||
|
|
||||
|
// check if the mount process has an error to report
|
||||
|
<-c.Ready |
||||
|
if err := c.MountError; err != nil { |
||||
|
glog.Fatal(err) |
||||
|
} |
||||
|
|
||||
|
return true |
||||
|
} |
||||
|
|
||||
|
type File struct { |
||||
|
FileId filer.FileId |
||||
|
Name string |
||||
|
} |
||||
|
|
||||
|
func (File) Attr() fuse.Attr { |
||||
|
return fuse.Attr{Mode: 0444} |
||||
|
} |
||||
|
func (File) ReadAll(intr fs.Intr) ([]byte, fuse.Error) { |
||||
|
return []byte("hello, world\n"), nil |
||||
|
} |
||||
|
|
||||
|
type Dir struct { |
||||
|
DirectoryId filer.DirectoryId |
||||
|
Name string |
||||
|
} |
||||
|
|
||||
|
func (dir Dir) Attr() fuse.Attr { |
||||
|
return fuse.Attr{Inode: 1, Mode: os.ModeDir | 0555} |
||||
|
} |
||||
|
|
||||
|
func (dir Dir) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) { |
||||
|
files_result, e := filer.ListFiles(*mountOptions.filer, dir.DirectoryId, name) |
||||
|
if e != nil { |
||||
|
return nil, fuse.ENOENT |
||||
|
} |
||||
|
if len(files_result.Files) > 0 { |
||||
|
return File{files_result.Files[0].Id, files_result.Files[0].Name}, nil |
||||
|
} |
||||
|
return nil, fmt.Errorf("File Not Found for %s", name) |
||||
|
} |
||||
|
|
||||
|
type WFS struct{} |
||||
|
|
||||
|
func (WFS) Root() (fs.Node, fuse.Error) { |
||||
|
return Dir{}, nil |
||||
|
} |
||||
|
|
||||
|
func (dir *Dir) ReadDir(intr fs.Intr) ([]fuse.Dirent, fuse.Error) { |
||||
|
ret := make([]fuse.Dirent, 0) |
||||
|
if dirs, e := filer.ListDirectories(*mountOptions.filer, dir.DirectoryId); e == nil { |
||||
|
for _, d := range dirs.Directories { |
||||
|
dirId := uint64(d.Id) |
||||
|
ret = append(ret, fuse.Dirent{Inode: dirId, Name: d.Name, Type: fuse.DT_Dir}) |
||||
|
} |
||||
|
} |
||||
|
if files, e := filer.ListFiles(*mountOptions.filer, dir.DirectoryId, ""); e == nil { |
||||
|
for _, f := range files.Files { |
||||
|
if fileId, e := storage.ParseFileId(string(f.Id)); e == nil { |
||||
|
fileInode := uint64(fileId.VolumeId)<<48 + fileId.Key |
||||
|
ret = append(ret, fuse.Dirent{Inode: fileInode, Name: f.Name, Type: fuse.DT_File}) |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
return ret, nil |
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
package weed_server |
||||
|
|
||||
|
import ( |
||||
|
"net/http" |
||||
|
) |
||||
|
|
||||
|
func (fs *FilerServer) filerApiHandler(w http.ResponseWriter, r *http.Request) { |
||||
|
switch r.Method { |
||||
|
case "GET": |
||||
|
fs.GetOrHeadHandler(w, r, true) |
||||
|
case "HEAD": |
||||
|
fs.GetOrHeadHandler(w, r, false) |
||||
|
case "DELETE": |
||||
|
fs.DeleteHandler(w, r) |
||||
|
case "PUT": |
||||
|
fs.PostHandler(w, r) |
||||
|
case "POST": |
||||
|
fs.PostHandler(w, r) |
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue