aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lu <chris.lu@gmail.com>2019-04-03 00:20:00 -0700
committerChris Lu <chris.lu@gmail.com>2019-04-03 00:20:00 -0700
commit715a38da1e4fce05631f230ccf09ce92c99a4fd4 (patch)
treedc443bbe30b2178f24c67c19ef732013b8cabd0f
parent20dcb44077bcb8164b8351ee506af8385e8fd6ef (diff)
downloadseaweedfs-715a38da1e4fce05631f230ccf09ce92c99a4fd4.tar.xz
seaweedfs-715a38da1e4fce05631f230ccf09ce92c99a4fd4.zip
weed shell: add fs.cd, fs.pwd to change to a directory and print current directory
-rw-r--r--weed/command/shell.go4
-rw-r--r--weed/shell/command_fs_cd.go99
-rw-r--r--weed/shell/command_fs_du.go25
-rw-r--r--weed/shell/command_fs_ls.go16
-rw-r--r--weed/shell/command_fs_pwd.go32
-rw-r--r--weed/shell/commands.go38
6 files changed, 189 insertions, 25 deletions
diff --git a/weed/command/shell.go b/weed/command/shell.go
index 1c3ce5f10..3216d5d48 100644
--- a/weed/command/shell.go
+++ b/weed/command/shell.go
@@ -31,6 +31,10 @@ func runShell(command *Command, args []string) bool {
weed_server.LoadConfiguration("security", false)
shellOptions.GrpcDialOption = security.LoadClientTLS(viper.Sub("grpc"), "client")
+ shellOptions.FilerHost = "localhost"
+ shellOptions.FilerPort = 8888
+ shellOptions.Directory = ""
+
shell.RunShell(shellOptions)
return true
diff --git a/weed/shell/command_fs_cd.go b/weed/shell/command_fs_cd.go
new file mode 100644
index 000000000..13208a3f8
--- /dev/null
+++ b/weed/shell/command_fs_cd.go
@@ -0,0 +1,99 @@
+package shell
+
+import (
+ "context"
+ "fmt"
+ "github.com/chrislusf/seaweedfs/weed/filer2"
+ "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
+ "io"
+ "strings"
+)
+
+func init() {
+ commands = append(commands, &commandFsCd{})
+}
+
+type commandFsCd struct {
+}
+
+func (c *commandFsCd) Name() string {
+ return "fs.cd"
+}
+
+func (c *commandFsCd) Help() string {
+ return `change directory to http://<filer_server>:<port>/dir/
+
+ The full path can be too long to type. For example,
+ fs.ls http://<filer_server>:<port>/some/path/to/file_name
+
+ can be simplified as
+
+ fs.cd http://<filer_server>:<port>/some/path
+ fs.ls to/file_name
+`
+}
+
+func (c *commandFsCd) Do(args []string, commandEnv *commandEnv, writer io.Writer) (err error) {
+
+ input := ""
+ if len(args) > 0 {
+ input = args[len(args)-1]
+ }
+
+ filerServer, filerPort, path, err := commandEnv.parseUrl(input)
+ if err != nil {
+ return err
+ }
+
+ dir, name := filer2.FullPath(path).DirAndName()
+ if strings.HasSuffix(path, "/") {
+ if path == "/" {
+ dir, name = "/", ""
+ } else {
+ dir, name = filer2.FullPath(path[0:len(path)-1]).DirAndName()
+ }
+ }
+
+ ctx := context.Background()
+
+ err = commandEnv.withFilerClient(ctx, filerServer, filerPort, func(client filer_pb.SeaweedFilerClient) error {
+
+ resp, listErr := client.ListEntries(ctx, &filer_pb.ListEntriesRequest{
+ Directory: dir,
+ Prefix: name,
+ StartFromFileName: name,
+ InclusiveStartFrom: true,
+ Limit: 1,
+ })
+ if listErr != nil {
+ return listErr
+ }
+
+ if path == "" || path == "/" {
+ return nil
+ }
+
+ if len(resp.Entries) == 0 {
+ return fmt.Errorf("entry not found")
+ }
+
+ if resp.Entries[0].Name != name {
+ println("path", path, "dir", dir, "name", name, "found", resp.Entries[0].Name)
+ return fmt.Errorf("not a valid directory, found %s", resp.Entries[0].Name)
+ }
+
+ if !resp.Entries[0].IsDirectory {
+ return fmt.Errorf("not a directory")
+ }
+
+ return nil
+ })
+
+ if err == nil {
+ commandEnv.option.FilerHost = filerServer
+ commandEnv.option.FilerPort = filerPort
+ commandEnv.option.Directory = path
+ }
+
+ return err
+}
diff --git a/weed/shell/command_fs_du.go b/weed/shell/command_fs_du.go
index 3fecac9a8..98e2eebd1 100644
--- a/weed/shell/command_fs_du.go
+++ b/weed/shell/command_fs_du.go
@@ -8,8 +8,6 @@ import (
"github.com/chrislusf/seaweedfs/weed/util"
"google.golang.org/grpc"
"io"
- "net/url"
- "strconv"
"strings"
)
@@ -35,7 +33,7 @@ func (c *commandFsDu) Help() string {
func (c *commandFsDu) Do(args []string, commandEnv *commandEnv, writer io.Writer) (err error) {
- filerServer, filerPort, path, err := parseFilerUrl(args[0])
+ filerServer, filerPort, path, err := commandEnv.parseUrl(args[0])
if err != nil {
return err
}
@@ -45,7 +43,7 @@ func (c *commandFsDu) Do(args []string, commandEnv *commandEnv, writer io.Writer
if path == "/" {
dir, name = "/", ""
} else {
- dir, name = path[0:len(path)-1], ""
+ dir, name = path[0 : len(path)-1], ""
}
}
@@ -112,25 +110,6 @@ func paginateDirectory(ctx context.Context, writer io.Writer, client filer_pb.Se
}
-func parseFilerUrl(entryPath string) (filerServer string, filerPort int64, path string, err error) {
- if strings.HasPrefix(entryPath, "http") {
- var u *url.URL
- u, err = url.Parse(entryPath)
- if err != nil {
- return
- }
- filerServer = u.Hostname()
- portString := u.Port()
- if portString != "" {
- filerPort, err = strconv.ParseInt(portString, 10, 32)
- }
- path = u.Path
- } else {
- err = fmt.Errorf("path should have full url http://<filer_server>:<port>/path/to/dirOrFile : %s", entryPath)
- }
- return
-}
-
func (env *commandEnv) withFilerClient(ctx context.Context, filerServer string, filerPort int64, fn func(filer_pb.SeaweedFilerClient) error) error {
filerGrpcAddress := fmt.Sprintf("%s:%d", filerServer, filerPort+10000)
diff --git a/weed/shell/command_fs_ls.go b/weed/shell/command_fs_ls.go
index b94f24694..7b8d1d0cc 100644
--- a/weed/shell/command_fs_ls.go
+++ b/weed/shell/command_fs_ls.go
@@ -44,17 +44,29 @@ func (c *commandFsLs) Do(args []string, commandEnv *commandEnv, writer io.Writer
}
}
- filerServer, filerPort, path, err := parseFilerUrl(args[len(args)-1])
+ input := ""
+ if len(args) > 0 {
+ input = args[len(args)-1]
+ if strings.HasPrefix(input, "-") {
+ input = ""
+ }
+ }
+
+ filerServer, filerPort, path, err := commandEnv.parseUrl(input)
if err != nil {
return err
}
+ if input == "" && !strings.HasSuffix(path, "/") {
+ path = path + "/"
+ }
dir, name := filer2.FullPath(path).DirAndName()
+ // println("path", path, "dir", dir, "name", name)
if strings.HasSuffix(path, "/") {
if path == "/" {
dir, name = "/", ""
} else {
- dir, name = path[0:len(path)-1], ""
+ dir, name = path[0 : len(path)-1], ""
}
}
diff --git a/weed/shell/command_fs_pwd.go b/weed/shell/command_fs_pwd.go
new file mode 100644
index 000000000..0b0a7f176
--- /dev/null
+++ b/weed/shell/command_fs_pwd.go
@@ -0,0 +1,32 @@
+package shell
+
+import (
+ "fmt"
+ "io"
+)
+
+func init() {
+ commands = append(commands, &commandFsPwd{})
+}
+
+type commandFsPwd struct {
+}
+
+func (c *commandFsPwd) Name() string {
+ return "fs.pwd"
+}
+
+func (c *commandFsPwd) Help() string {
+ return `print out current directory`
+}
+
+func (c *commandFsPwd) Do(args []string, commandEnv *commandEnv, writer io.Writer) (err error) {
+
+ fmt.Fprintf(writer, "http://%s:%d%s\n",
+ commandEnv.option.FilerHost,
+ commandEnv.option.FilerPort,
+ commandEnv.option.Directory,
+ )
+
+ return nil
+}
diff --git a/weed/shell/commands.go b/weed/shell/commands.go
index 280900c80..2a262d913 100644
--- a/weed/shell/commands.go
+++ b/weed/shell/commands.go
@@ -1,14 +1,23 @@
package shell
import (
+ "fmt"
"github.com/chrislusf/seaweedfs/weed/wdclient"
"google.golang.org/grpc"
"io"
+ "net/url"
+ "path/filepath"
+ "strconv"
+ "strings"
)
type ShellOptions struct {
Masters *string
GrpcDialOption grpc.DialOption
+ // shell transient context
+ FilerHost string
+ FilerPort int64
+ Directory string
}
type commandEnv struct {
@@ -26,3 +35,32 @@ type command interface {
var (
commands = []command{}
)
+
+func (ce *commandEnv) parseUrl(input string) (filerServer string, filerPort int64, path string, err error) {
+ if strings.HasPrefix(input, "http") {
+ return parseFilerUrl(input)
+ }
+ if !strings.HasPrefix(input, "/") {
+ input = filepath.ToSlash(filepath.Join(ce.option.Directory, input))
+ }
+ return ce.option.FilerHost, ce.option.FilerPort, input, err
+}
+
+func parseFilerUrl(entryPath string) (filerServer string, filerPort int64, path string, err error) {
+ if strings.HasPrefix(entryPath, "http") {
+ var u *url.URL
+ u, err = url.Parse(entryPath)
+ if err != nil {
+ return
+ }
+ filerServer = u.Hostname()
+ portString := u.Port()
+ if portString != "" {
+ filerPort, err = strconv.ParseInt(portString, 10, 32)
+ }
+ path = u.Path
+ } else {
+ err = fmt.Errorf("path should have full url http://<filer_server>:<port>/path/to/dirOrFile : %s", entryPath)
+ }
+ return
+}