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.
This commit is contained in:
parent
b3cfde98cc
commit
6d3c76ceb3
201
command/fs.go
201
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 <alloc-id> <path>
|
||||
|
||||
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 <job-id>
|
||||
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,
|
||||
|
|
|
@ -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 <alloc-id> <path>
|
||||
|
||||
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 <job-id>
|
||||
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
|
||||
}
|
172
command/fs_ls.go
172
command/fs_ls.go
|
@ -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 <alloc-id> <path>
|
||||
|
||||
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 <job-id>
|
||||
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
|
||||
}
|
|
@ -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 <alloc-id> <path>
|
||||
|
||||
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 <job-id>
|
||||
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
|
||||
}
|
23
commands.go
23
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
|
||||
|
|
Loading…
Reference in New Issue