From d4b8133220d726499b0fc54f9a19b587a63e9815 Mon Sep 17 00:00:00 2001 From: Jake Champlin Date: Wed, 4 May 2016 23:59:38 -0700 Subject: [PATCH 1/3] Refactor fs subcommands into fs command Refactors `nomad fs` command to eliminate `fs` subcommands. Automatically displays the file, if the path specified is a file; lists the directory if the path is a directory; or displays stat information if the `-stat` flag is set. Currently running `nomad fs ls` to find a file, then running the exact same command with the exception of `cat` instead of `ls` is time consuming and awkward. This allows operational testing to be greatly enhanced, and makes our lives so much better. --- command/fs.go | 201 ++++++++++++++++++++++++++++++++++++++++++++- command/fs_cat.go | 143 -------------------------------- command/fs_ls.go | 172 -------------------------------------- command/fs_stat.go | 165 ------------------------------------- commands.go | 23 ------ 5 files changed, 198 insertions(+), 506 deletions(-) delete mode 100644 command/fs_cat.go delete mode 100644 command/fs_ls.go delete mode 100644 command/fs_stat.go diff --git a/command/fs.go b/command/fs.go index f42b60334dc1..b5b537fb2050 100644 --- a/command/fs.go +++ b/command/fs.go @@ -2,11 +2,14 @@ package command import ( "fmt" + "io" "math/rand" + "os" + "strings" "time" + humanize "github.com/dustin/go-humanize" "github.com/hashicorp/nomad/api" - "github.com/mitchellh/cli" ) type FSCommand struct { @@ -14,7 +17,33 @@ type FSCommand struct { } func (f *FSCommand) Help() string { - return "This command is accessed by using one of the subcommands below." + helpText := ` +Usage: nomad fs + + fs displays either the contents of an allocation directory for the passed allocation, + or displays the file at the given path. The path is relative to the root of the alloc + dir and defaults to root if unspecified. + + General Options: + + ` + generalOptionsUsage() + ` + +Fs Options: + + -H + Machine friendly output. + + -verbose + Show full information. + + -job + Use a random allocation from a specified job-id. + + -stat + Show file stat information instead of displaying the file, or listing the directory. + +` + return strings.TrimSpace(helpText) } func (f *FSCommand) Synopsis() string { @@ -22,7 +51,173 @@ func (f *FSCommand) Synopsis() string { } func (f *FSCommand) Run(args []string) int { - return cli.RunResultHelp + var verbose, machine, job, stat bool + flags := f.Meta.FlagSet("fs-list", FlagSetClient) + flags.Usage = func() { f.Ui.Output(f.Help()) } + flags.BoolVar(&verbose, "verbose", false, "") + flags.BoolVar(&machine, "H", false, "") + flags.BoolVar(&job, "job", false, "") + flags.BoolVar(&stat, "stat", false, "") + + if err := flags.Parse(args); err != nil { + return 1 + } + args = flags.Args() + + if len(args) < 1 { + f.Ui.Error("allocation id is a required parameter") + return 1 + } + + path := "/" + if len(args) == 2 { + path = args[1] + } + + client, err := f.Meta.Client() + if err != nil { + f.Ui.Error(fmt.Sprintf("Error initializing client: %v", err)) + return 1 + } + + // If -job is specified, use random allocation, otherwise use provided allocation + allocID := args[0] + if job { + allocID, err = getRandomJobAlloc(client, args[0]) + if err != nil { + f.Ui.Error(fmt.Sprintf("Error fetching allocations: %v", err)) + return 1 + } + } + + // Truncate the id unless full length is requested + length := shortId + if verbose { + length = fullId + } + // Query the allocation info + if len(allocID) == 1 { + f.Ui.Error(fmt.Sprintf("Alloc ID must contain at least two characters.")) + return 1 + } + if len(allocID)%2 == 1 { + // Identifiers must be of even length, so we strip off the last byte + // to provide a consistent user experience. + allocID = allocID[:len(allocID)-1] + } + + allocs, _, err := client.Allocations().PrefixList(allocID) + if err != nil { + f.Ui.Error(fmt.Sprintf("Error querying allocation: %v", err)) + return 1 + } + if len(allocs) == 0 { + f.Ui.Error(fmt.Sprintf("No allocation(s) with prefix or id %q found", allocID)) + return 1 + } + if len(allocs) > 1 { + // Format the allocs + out := make([]string, len(allocs)+1) + out[0] = "ID|Eval ID|Job ID|Task Group|Desired Status|Client Status" + for i, alloc := range allocs { + out[i+1] = fmt.Sprintf("%s|%s|%s|%s|%s|%s", + limit(alloc.ID, length), + limit(alloc.EvalID, length), + alloc.JobID, + alloc.TaskGroup, + alloc.DesiredStatus, + alloc.ClientStatus, + ) + } + f.Ui.Output(fmt.Sprintf("Prefix matched multiple allocations\n\n%s", formatList(out))) + return 0 + } + // Prefix lookup matched a single allocation + alloc, _, err := client.Allocations().Info(allocs[0].ID, nil) + if err != nil { + f.Ui.Error(fmt.Sprintf("Error querying allocation: %s", err)) + return 1 + } + + if alloc.DesiredStatus == "failed" { + allocID := limit(alloc.ID, length) + msg := fmt.Sprintf(`The allocation %q failed to be placed. To see the cause, run: +nomad alloc-status %s`, allocID, allocID) + f.Ui.Error(msg) + return 0 + } + + // Get file stat info + file, _, err := client.AllocFS().Stat(alloc, path, nil) + if err != nil { + f.Ui.Error(err.Error()) + return 1 + } + + // If we want file stats, print those and exit. + if stat { + // Display the file information + out := make([]string, 2) + out[0] = "Mode|Size|Modified Time|Name" + if file != nil { + fn := file.Name + if file.IsDir { + fn = fmt.Sprintf("%s/", fn) + } + var size string + if machine { + size = fmt.Sprintf("%d", file.Size) + } else { + size = humanize.Bytes(uint64(file.Size)) + } + out[1] = fmt.Sprintf("%s|%s|%s|%s", file.FileMode, size, + formatTime(file.ModTime), fn) + } + f.Ui.Output(formatList(out)) + return 0 + } + + // Determine if the path is a file or a directory. + if file.IsDir { + // We have a directory, list it. + files, _, err := client.AllocFS().List(alloc, path, nil) + if err != nil { + f.Ui.Error(fmt.Sprintf("Error listing alloc dir: %s", err)) + return 1 + } + // Display the file information in a tabular format + out := make([]string, len(files)+1) + out[0] = "Mode|Size|Modfied Time|Name" + for i, file := range files { + fn := file.Name + if file.IsDir { + fn = fmt.Sprintf("%s/", fn) + } + var size string + if machine { + size = fmt.Sprintf("%d", file.Size) + } else { + size = humanize.Bytes(uint64(file.Size)) + } + out[i+1] = fmt.Sprintf("%s|%s|%s|%s", + file.FileMode, + size, + formatTime(file.ModTime), + fn, + ) + } + f.Ui.Output(formatList(out)) + } else { + // We have a file, cat it. + r, _, err := client.AllocFS().Cat(alloc, path, nil) + if err != nil { + f.Ui.Error(fmt.Sprintf("Error reading file: %s", err)) + return 1 + } + io.Copy(os.Stdout, r) + } + + return 0 } // Get Random Allocation ID from a known jobID. Prefer to use a running allocation, diff --git a/command/fs_cat.go b/command/fs_cat.go deleted file mode 100644 index 801472a67515..000000000000 --- a/command/fs_cat.go +++ /dev/null @@ -1,143 +0,0 @@ -package command - -import ( - "fmt" - "io" - "os" - "strings" -) - -type FSCatCommand struct { - Meta -} - -func (f *FSCatCommand) Help() string { - helpText := ` - Usage: nomad fs cat - - Dispays a file in an allocation directory at the given path. - The path is relative to the allocation directory and defaults to root if unspecified. - - General Options: - - ` + generalOptionsUsage() + ` - -Cat Options: - - -verbose - Show full information. - - -job - Use a random allocation from a specified job-id. -` - return strings.TrimSpace(helpText) -} - -func (f *FSCatCommand) Synopsis() string { - return "Cat a file in an allocation directory" -} - -func (f *FSCatCommand) Run(args []string) int { - var verbose, job bool - flags := f.Meta.FlagSet("fs-list", FlagSetClient) - flags.Usage = func() { f.Ui.Output(f.Help()) } - flags.BoolVar(&verbose, "verbose", false, "") - flags.BoolVar(&job, "job", false, "") - - if err := flags.Parse(args); err != nil { - return 1 - } - args = flags.Args() - - if len(args) < 1 { - f.Ui.Error("allocation id is a required parameter") - return 1 - } - - path := "/" - if len(args) == 2 { - path = args[1] - } - - client, err := f.Meta.Client() - if err != nil { - f.Ui.Error(fmt.Sprintf("Error initializing client: %v", err)) - return 1 - } - - // If -job is specified, use random allocation, otherwise use provided allocation - allocID := args[0] - if job { - allocID, err = getRandomJobAlloc(client, args[0]) - if err != nil { - f.Ui.Error(fmt.Sprintf("Error querying API: %v", err)) - return 1 - } - } - - // Truncate the id unless full length is requested - length := shortId - if verbose { - length = fullId - } - // Query the allocation info - if len(allocID) == 1 { - f.Ui.Error(fmt.Sprintf("Alloc ID must contain at least two characters.")) - return 1 - } - if len(allocID)%2 == 1 { - // Identifiers must be of even length, so we strip off the last byte - // to provide a consistent user experience. - allocID = allocID[:len(allocID)-1] - } - - allocs, _, err := client.Allocations().PrefixList(allocID) - if err != nil { - f.Ui.Error(fmt.Sprintf("Error querying allocation: %v", err)) - return 1 - } - if len(allocs) == 0 { - f.Ui.Error(fmt.Sprintf("No allocation(s) with prefix or id %q found", allocID)) - return 1 - } - if len(allocs) > 1 { - // Format the allocs - out := make([]string, len(allocs)+1) - out[0] = "ID|Eval ID|Job ID|Task Group|Desired Status|Client Status" - for i, alloc := range allocs { - out[i+1] = fmt.Sprintf("%s|%s|%s|%s|%s|%s", - limit(alloc.ID, length), - limit(alloc.EvalID, length), - alloc.JobID, - alloc.TaskGroup, - alloc.DesiredStatus, - alloc.ClientStatus, - ) - } - f.Ui.Output(fmt.Sprintf("Prefix matched multiple allocations\n\n%s", formatList(out))) - return 0 - } - // Prefix lookup matched a single allocation - alloc, _, err := client.Allocations().Info(allocs[0].ID, nil) - if err != nil { - f.Ui.Error(fmt.Sprintf("Error querying allocation: %s", err)) - return 1 - } - - if alloc.DesiredStatus == "failed" { - allocID := limit(alloc.ID, length) - msg := fmt.Sprintf(`The allocation %q failed to be placed. To see the cause, run: -nomad alloc-status %s`, allocID, allocID) - f.Ui.Error(msg) - return 0 - } - - // Get the contents of the file - r, _, err := client.AllocFS().Cat(alloc, path, nil) - if err != nil { - f.Ui.Error(fmt.Sprintf("Error reading file: %v", err)) - return 1 - } - io.Copy(os.Stdout, r) - return 0 -} diff --git a/command/fs_ls.go b/command/fs_ls.go deleted file mode 100644 index d86de1bf19e8..000000000000 --- a/command/fs_ls.go +++ /dev/null @@ -1,172 +0,0 @@ -package command - -import ( - "fmt" - "strings" - - humanize "github.com/dustin/go-humanize" -) - -type FSListCommand struct { - Meta -} - -func (f *FSListCommand) Help() string { - helpText := ` -Usage: nomad fs ls - - ls displays the contents of the allocation directory for the passed allocation. The path - is relative to the root of the alloc dir and defaults to root if unspecified. - - General Options: - - ` + generalOptionsUsage() + ` - -Ls Options: - - -H - Machine friendly output. - - -verbose - Show full information. - - -job - Use a random allocation from a specified job-id. - -` - return strings.TrimSpace(helpText) -} - -func (f *FSListCommand) Synopsis() string { - return "List files in an allocation directory" -} - -func (f *FSListCommand) Run(args []string) int { - var verbose bool - var machine bool - var job bool - flags := f.Meta.FlagSet("fs-list", FlagSetClient) - flags.Usage = func() { f.Ui.Output(f.Help()) } - flags.BoolVar(&verbose, "verbose", false, "") - flags.BoolVar(&machine, "H", false, "") - flags.BoolVar(&job, "job", false, "") - - if err := flags.Parse(args); err != nil { - return 1 - } - args = flags.Args() - - if len(args) < 1 { - f.Ui.Error("allocation id is a required parameter") - return 1 - } - - path := "/" - if len(args) == 2 { - path = args[1] - } - - client, err := f.Meta.Client() - if err != nil { - f.Ui.Error(fmt.Sprintf("Error initializing client: %v", err)) - return 1 - } - - // If -job is specified, use random allocation, otherwise use provided allocation - allocID := args[0] - if job { - allocID, err = getRandomJobAlloc(client, args[0]) - if err != nil { - f.Ui.Error(fmt.Sprintf("Error fetching allocations: %v", err)) - return 1 - } - } - - // Truncate the id unless full length is requested - length := shortId - if verbose { - length = fullId - } - // Query the allocation info - if len(allocID) == 1 { - f.Ui.Error(fmt.Sprintf("Alloc ID must contain at least two characters.")) - return 1 - } - if len(allocID)%2 == 1 { - // Identifiers must be of even length, so we strip off the last byte - // to provide a consistent user experience. - allocID = allocID[:len(allocID)-1] - } - - allocs, _, err := client.Allocations().PrefixList(allocID) - if err != nil { - f.Ui.Error(fmt.Sprintf("Error querying allocation: %v", err)) - return 1 - } - if len(allocs) == 0 { - f.Ui.Error(fmt.Sprintf("No allocation(s) with prefix or id %q found", allocID)) - return 1 - } - if len(allocs) > 1 { - // Format the allocs - out := make([]string, len(allocs)+1) - out[0] = "ID|Eval ID|Job ID|Task Group|Desired Status|Client Status" - for i, alloc := range allocs { - out[i+1] = fmt.Sprintf("%s|%s|%s|%s|%s|%s", - limit(alloc.ID, length), - limit(alloc.EvalID, length), - alloc.JobID, - alloc.TaskGroup, - alloc.DesiredStatus, - alloc.ClientStatus, - ) - } - f.Ui.Output(fmt.Sprintf("Prefix matched multiple allocations\n\n%s", formatList(out))) - return 0 - } - // Prefix lookup matched a single allocation - alloc, _, err := client.Allocations().Info(allocs[0].ID, nil) - if err != nil { - f.Ui.Error(fmt.Sprintf("Error querying allocation: %s", err)) - return 1 - } - - if alloc.DesiredStatus == "failed" { - allocID := limit(alloc.ID, length) - msg := fmt.Sprintf(`The allocation %q failed to be placed. To see the cause, run: -nomad alloc-status %s`, allocID, allocID) - f.Ui.Error(msg) - return 0 - } - // Get the file at the given path - files, _, err := client.AllocFS().List(alloc, path, nil) - if err != nil { - f.Ui.Error(fmt.Sprintf("Error listing alloc dir: %v", err)) - return 1 - } - - // Display the file information in a tabular format - out := make([]string, len(files)+1) - out[0] = "Mode|Size|Modfied Time|Name" - for i, file := range files { - fn := file.Name - if file.IsDir { - fn = fmt.Sprintf("%s/", fn) - } - var size string - if machine { - size = fmt.Sprintf("%d", file.Size) - } else { - size = humanize.Bytes(uint64(file.Size)) - } - out[i+1] = fmt.Sprintf("%s|%s|%s|%s", - file.FileMode, - size, - formatTime(file.ModTime), - fn, - ) - } - - f.Ui.Output(formatList(out)) - return 0 -} diff --git a/command/fs_stat.go b/command/fs_stat.go deleted file mode 100644 index 361650b185f0..000000000000 --- a/command/fs_stat.go +++ /dev/null @@ -1,165 +0,0 @@ -package command - -import ( - "fmt" - "strings" - - humanize "github.com/dustin/go-humanize" -) - -type FSStatCommand struct { - Meta -} - -func (f *FSStatCommand) Help() string { - helpText := ` -Usage: nomad fs stat - - Displays information about an entry in an allocation directory at the given path. - The path is relative to the allocation directory and defaults to root if unspecified. - - General Options: - - ` + generalOptionsUsage() + ` - -Stat Options: - - -H - Machine friendly output. - - -verbose - Show full information. - - -job - Use a random allocation from a specified job-id. -` - return strings.TrimSpace(helpText) -} - -func (f *FSStatCommand) Synopsis() string { - return "Stat an entry in an allocation directory" -} - -func (f *FSStatCommand) Run(args []string) int { - var verbose bool - var machine bool - var job bool - flags := f.Meta.FlagSet("fs-list", FlagSetClient) - flags.Usage = func() { f.Ui.Output(f.Help()) } - flags.BoolVar(&verbose, "verbose", false, "") - flags.BoolVar(&machine, "H", false, "") - flags.BoolVar(&job, "job", false, "") - - if err := flags.Parse(args); err != nil { - return 1 - } - args = flags.Args() - - if len(args) < 1 { - f.Ui.Error("allocation id is a required parameter") - return 1 - } - - path := "/" - if len(args) == 2 { - path = args[1] - } - - client, err := f.Meta.Client() - if err != nil { - f.Ui.Error(fmt.Sprintf("Error initializing client: %v", err)) - return 1 - } - - allocID := args[0] - if job { - allocID, err = getRandomJobAlloc(client, args[0]) - if err != nil { - f.Ui.Error(fmt.Sprintf("Error querying API: %v", err)) - return 1 - } - } - - // Truncate the id unless full length is requested - length := shortId - if verbose { - length = fullId - } - // Query the allocation info - if len(allocID) == 1 { - f.Ui.Error(fmt.Sprintf("Alloc ID must contain at least two characters.")) - return 1 - } - if len(allocID)%2 == 1 { - // Identifiers must be of even length, so we strip off the last byte - // to provide a consistent user experience. - allocID = allocID[:len(allocID)-1] - } - - allocs, _, err := client.Allocations().PrefixList(allocID) - if err != nil { - f.Ui.Error(fmt.Sprintf("Error querying allocation: %v", err)) - return 1 - } - if len(allocs) == 0 { - f.Ui.Error(fmt.Sprintf("No allocation(s) with prefix or id %q found", allocID)) - return 1 - } - if len(allocs) > 1 { - // Format the allocs - out := make([]string, len(allocs)+1) - out[0] = "ID|Eval ID|Job ID|Task Group|Desired Status|Client Status" - for i, alloc := range allocs { - out[i+1] = fmt.Sprintf("%s|%s|%s|%s|%s|%s", - limit(alloc.ID, length), - limit(alloc.EvalID, length), - alloc.JobID, - alloc.TaskGroup, - alloc.DesiredStatus, - alloc.ClientStatus, - ) - } - f.Ui.Output(fmt.Sprintf("Prefix matched multiple allocations\n\n%s", formatList(out))) - return 0 - } - // Prefix lookup matched a single allocation - alloc, _, err := client.Allocations().Info(allocs[0].ID, nil) - if err != nil { - f.Ui.Error(fmt.Sprintf("Error querying allocation: %s", err)) - return 1 - } - - if alloc.DesiredStatus == "failed" { - allocID := limit(alloc.ID, length) - msg := fmt.Sprintf(`The allocation %q failed to be placed. To see the cause, run: -nomad alloc-status %s`, allocID, allocID) - f.Ui.Error(msg) - return 0 - } - // Get the file information - file, _, err := client.AllocFS().Stat(alloc, path, nil) - if err != nil { - f.Ui.Error(err.Error()) - return 1 - } - - // Display the file information - out := make([]string, 2) - out[0] = "Mode|Size|Modified Time|Name" - if file != nil { - fn := file.Name - if file.IsDir { - fn = fmt.Sprintf("%s/", fn) - } - var size string - if machine { - size = fmt.Sprintf("%d", file.Size) - } else { - size = humanize.Bytes(uint64(file.Size)) - } - out[1] = fmt.Sprintf("%s|%s|%s|%s", file.FileMode, size, - formatTime(file.ModTime), fn) - } - f.Ui.Output(formatList(out)) - return 0 -} diff --git a/commands.go b/commands.go index 2374dea068b7..2c23b0f40475 100644 --- a/commands.go +++ b/commands.go @@ -52,7 +52,6 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { Meta: meta, }, nil }, - "eval-monitor": func() (cli.Command, error) { return &command.EvalMonitorCommand{ Meta: meta, @@ -68,21 +67,6 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { Meta: meta, }, nil }, - "fs ls": func() (cli.Command, error) { - return &command.FSListCommand{ - Meta: meta, - }, nil - }, - "fs stat": func() (cli.Command, error) { - return &command.FSStatCommand{ - Meta: meta, - }, nil - }, - "fs cat": func() (cli.Command, error) { - return &command.FSCatCommand{ - Meta: meta, - }, nil - }, "init": func() (cli.Command, error) { return &command.InitCommand{ Meta: meta, @@ -98,13 +82,11 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { Meta: meta, }, nil }, - "node-status": func() (cli.Command, error) { return &command.NodeStatusCommand{ Meta: meta, }, nil }, - "run": func() (cli.Command, error) { return &command.RunCommand{ Meta: meta, @@ -120,13 +102,11 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { Meta: meta, }, nil }, - "server-join": func() (cli.Command, error) { return &command.ServerJoinCommand{ Meta: meta, }, nil }, - "server-members": func() (cli.Command, error) { return &command.ServerMembersCommand{ Meta: meta, @@ -137,19 +117,16 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { Meta: meta, }, nil }, - "stop": func() (cli.Command, error) { return &command.StopCommand{ Meta: meta, }, nil }, - "validate": func() (cli.Command, error) { return &command.ValidateCommand{ Meta: meta, }, nil }, - "version": func() (cli.Command, error) { ver := Version rel := VersionPrerelease From cf2d8b6601e30d8f33e976b647c5440310eb90b9 Mon Sep 17 00:00:00 2001 From: Jake Champlin Date: Mon, 9 May 2016 09:57:37 -0400 Subject: [PATCH 2/3] Update documentation --- website/source/docs/commands/fs.html.md.erb | 25 ++++++++++----------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/website/source/docs/commands/fs.html.md.erb b/website/source/docs/commands/fs.html.md.erb index 64565646736e..206722aed03e 100644 --- a/website/source/docs/commands/fs.html.md.erb +++ b/website/source/docs/commands/fs.html.md.erb @@ -8,19 +8,18 @@ description: > # Command: fs -The `fs` family of commands allows a user to navigate an allocation directory on a Nomad -client. The following subcommands are available - `cat`, `ls` and `stat` +The `fs` command allows a user to navigate an allocation directory on a Nomad +client. The following functionalities are available - `cat`, `ls` and `stat` -`cat`: Reads contents of files and writes them to the standard output. -`ls`: Displays the name of a file and directories and their associated information. -`stat`: Displays information about a file. +`cat`: If the target path is a file, Nomad will cat the target path. +`ls`: If the target path is a directory, Nomad displays the name of a file and directories and their associated information. +`stat`: If the `-s` flag is used, Nomad will Display information about a file. ## Usage ``` -nomad fs ls -nomad fs stat -nomad fs cat +nomad fs +nomad fs -s ``` A valid allocation id is necessary unless `-job` is specified and the path is relative to the root of the allocation directory. @@ -28,25 +27,25 @@ The path is optional and it defaults to `/` of the allocation directory ## Examples -$ nomad fs ls eb17e557 +$ nomad fs eb17e557 Mode Size Modfied Time Name drwxrwxr-x 4096 28 Jan 16 05:39 UTC alloc/ drwxrwxr-x 4096 28 Jan 16 05:39 UTC redis/ -rw-rw-r-- 0 28 Jan 16 05:39 UTC redis_exit_status -$ nomad fs ls redis/local +$ nomad fs redis/local Mode Size Modfied Time Name -rw-rw-rw- 0 28 Jan 16 05:39 UTC redis.stderr -rw-rw-rw- 17 28 Jan 16 05:39 UTC redis.stdout -$ nomad fs stat redis/local/redis.stdout +$ nomad fs -s redis/local/redis.stdout Mode Size Modified Time Name -rw-rw-rw- 17 28 Jan 16 05:39 UTC redis.stdout -$ nomad fs cat redis/local/redis.stdout +$ nomad fs redis/local/redis.stdout 6710:C 27 Jan 22:04:03.794 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf 6710:M 27 Jan 22:04:03.795 * Increased maximum number of open files to 10032 (it was originally set to 256). @@ -55,7 +54,7 @@ $ nomad fs cat redis/local/redis.stdout Passing `-job` into one of the `fs` commands will allow the `fs` command to randomly select an allocation ID from the specified job. ``` -nomad fs ls -job +nomad fs -job ``` Nomad will prefer to select a running allocation ID for the job, but if no running allocations for the job are found, Nomad will use a dead allocation. From c1ef910f4d7502df3935e04c0a8992acdec35e77 Mon Sep 17 00:00:00 2001 From: Jake Champlin Date: Mon, 16 May 2016 13:17:37 -0400 Subject: [PATCH 3/3] Update per comments --- command/fs.go | 8 +++----- website/source/docs/commands/fs.html.md.erb | 6 +++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/command/fs.go b/command/fs.go index b5b537fb2050..af252bcc366f 100644 --- a/command/fs.go +++ b/command/fs.go @@ -20,16 +20,14 @@ func (f *FSCommand) Help() string { helpText := ` Usage: nomad fs - fs displays either the contents of an allocation directory for the passed allocation, + fs displays either the contents of an allocation directory for the passed allocation, or displays the file at the given path. The path is relative to the root of the alloc dir and defaults to root if unspecified. - General Options: +General Options: ` + generalOptionsUsage() + ` -Fs Options: - -H Machine friendly output. @@ -65,7 +63,7 @@ func (f *FSCommand) Run(args []string) int { args = flags.Args() if len(args) < 1 { - f.Ui.Error("allocation id is a required parameter") + f.Ui.Error("allocation id or -job is required") return 1 } diff --git a/website/source/docs/commands/fs.html.md.erb b/website/source/docs/commands/fs.html.md.erb index 206722aed03e..aca165d415a3 100644 --- a/website/source/docs/commands/fs.html.md.erb +++ b/website/source/docs/commands/fs.html.md.erb @@ -13,13 +13,13 @@ client. The following functionalities are available - `cat`, `ls` and `stat` `cat`: If the target path is a file, Nomad will cat the target path. `ls`: If the target path is a directory, Nomad displays the name of a file and directories and their associated information. -`stat`: If the `-s` flag is used, Nomad will Display information about a file. +`stat`: If the `-stat` flag is used, Nomad will Display information about a file. ## Usage ``` nomad fs -nomad fs -s +nomad fs -stat ``` A valid allocation id is necessary unless `-job` is specified and the path is relative to the root of the allocation directory. @@ -40,7 +40,7 @@ Mode Size Modfied Time Name -rw-rw-rw- 17 28 Jan 16 05:39 UTC redis.stdout -$ nomad fs -s redis/local/redis.stdout +$ nomad fs -stat redis/local/redis.stdout Mode Size Modified Time Name -rw-rw-rw- 17 28 Jan 16 05:39 UTC redis.stdout