From a70e5dbdc748d18df86c2034c0d5206538eaaa2c Mon Sep 17 00:00:00 2001 From: Diptanu Choudhury Date: Tue, 26 Jan 2016 15:03:26 -0800 Subject: [PATCH] Added an impl for stating a file --- api/fs.go | 35 ++++++++++++++++++++++ command/fs_list.go | 18 +++++------ command/fs_stat.go | 75 ++++++++++++++++++++++++++++++++++++++++++++++ commands.go | 6 ++++ 4 files changed, 125 insertions(+), 9 deletions(-) create mode 100644 command/fs_stat.go diff --git a/api/fs.go b/api/fs.go index 5316e497e..0748e06ac 100644 --- a/api/fs.go +++ b/api/fs.go @@ -52,3 +52,38 @@ func (a *AllocFS) List(alloc *Allocation, path string, q *QueryOptions) ([]*allo } return files, nil, nil } + +// Stat is used to stat a file at a given path of an allocation directory +func (a *AllocFS) Stat(alloc *Allocation, path string, q *QueryOptions) (*allocdir.AllocFileInfo, *QueryMeta, error) { + node, _, err := a.client.Nodes().Info(alloc.NodeID, &QueryOptions{}) + if err != nil { + return nil, nil, err + } + + if node.HTTPAddr == "" { + return nil, nil, fmt.Errorf("http addr of the node where alloc %q is running is not advertised", alloc.ID) + } + u := &url.URL{ + Scheme: "http", + Host: node.HTTPAddr, + Path: fmt.Sprintf("/v1/client/fs/stat/%s", alloc.ID), + } + v := url.Values{} + v.Set("path", path) + u.RawQuery = v.Encode() + req := &http.Request{ + Method: "GET", + URL: u, + } + c := http.Client{} + resp, err := c.Do(req) + if err != nil { + return nil, nil, err + } + decoder := json.NewDecoder(resp.Body) + var file *allocdir.AllocFileInfo + if err := decoder.Decode(&file); err != nil { + return nil, nil, err + } + return file, nil, nil +} diff --git a/command/fs_list.go b/command/fs_list.go index 3b0c3744a..e0187482c 100644 --- a/command/fs_list.go +++ b/command/fs_list.go @@ -23,9 +23,9 @@ func (f *FSListCommand) Synopsis() string { return "Displays list of files of an alloc dir" } -func (c *FSListCommand) Run(args []string) int { - flags := c.Meta.FlagSet("fs-list", FlagSetClient) - flags.Usage = func() { c.Ui.Output(c.Help()) } +func (f *FSListCommand) Run(args []string) int { + flags := f.Meta.FlagSet("fs-list", FlagSetClient) + flags.Usage = func() { f.Ui.Output(f.Help()) } if err := flags.Parse(args); err != nil { return 1 @@ -33,7 +33,7 @@ func (c *FSListCommand) Run(args []string) int { args = flags.Args() if len(args) < 1 { - c.Ui.Error("a valid alloc id is essential") + f.Ui.Error("a valid alloc id is essential") return 1 } @@ -43,21 +43,21 @@ func (c *FSListCommand) Run(args []string) int { path = args[1] } - client, err := c.Meta.Client() + client, err := f.Meta.Client() if err != nil { - c.Ui.Error(fmt.Sprintf("Error inititalizing client: %v", err)) + f.Ui.Error(fmt.Sprintf("Error inititalizing client: %v", err)) return 1 } alloc, _, err := client.Allocations().Info(allocID, nil) if err != nil { - c.Ui.Error(fmt.Sprintf("Error getting alloc: %v", err)) + f.Ui.Error(fmt.Sprintf("Error getting alloc: %v", err)) return 1 } files, _, err := client.AllocFS().List(alloc, path, nil) if err != nil { - c.Ui.Error(fmt.Sprintf("Error listing alloc dir: %v", err)) + f.Ui.Error(fmt.Sprintf("Error listing alloc dir: %v", err)) return 1 } @@ -73,6 +73,6 @@ func (c *FSListCommand) Run(args []string) int { file.Size) } - c.Ui.Output(formatList(out)) + f.Ui.Output(formatList(out)) return 0 } diff --git a/command/fs_stat.go b/command/fs_stat.go new file mode 100644 index 000000000..2fc22b37e --- /dev/null +++ b/command/fs_stat.go @@ -0,0 +1,75 @@ +package command + +import ( + "fmt" + "strings" +) + +type FSStatCommand struct { + Meta +} + +func (f *FSStatCommand) Help() string { + helpText := ` +Usage: nomad fs-stat [alloc-id] [path] + + Displays information about a file in an allocation directory at the given path. + The path is relative to the allocation directory. +` + return strings.TrimSpace(helpText) +} + +func (f *FSStatCommand) Synopsis() string { + return "Stats a file in an allocation directory" +} + +func (f *FSStatCommand) Run(args []string) int { + flags := f.Meta.FlagSet("fs-list", FlagSetClient) + flags.Usage = func() { f.Ui.Output(f.Help()) } + + if err := flags.Parse(args); err != nil { + return 1 + } + args = flags.Args() + + if len(args) < 1 { + f.Ui.Error("a valid alloc id is essential") + return 1 + } + + allocID := args[0] + path := "/" + if len(args) == 2 { + path = args[1] + } + + client, err := f.Meta.Client() + if err != nil { + f.Ui.Error(fmt.Sprintf("Error inititalizing client: %v", err)) + return 1 + } + + alloc, _, err := client.Allocations().Info(allocID, nil) + if err != nil { + f.Ui.Error(fmt.Sprintf("Error getting alloc: %v", err)) + return 1 + } + + file, _, err := client.AllocFS().Stat(alloc, path, nil) + if err != nil { + f.Ui.Error(fmt.Sprintf("Error stating file: %v:", err)) + return 1 + } + + out := make([]string, 2) + out[0] = "Name|Size" + if file != nil { + fn := file.Name + if file.IsDir { + fn = fmt.Sprintf("%s/", fn) + } + out[1] = fmt.Sprintf("%s|%d", fn, file.Size) + } + f.Ui.Output(formatList(out)) + return 0 +} diff --git a/commands.go b/commands.go index 87ea506bf..75af6130e 100644 --- a/commands.go +++ b/commands.go @@ -62,6 +62,12 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { Meta: meta, }, nil }, + "fs-stat": func() (cli.Command, error) { + return &command.FSStatCommand{ + Meta: meta, + }, nil + }, + "init": func() (cli.Command, error) { return &command.InitCommand{ Meta: meta,