github.com/ranjib/nomad@v0.1.1-0.20160225204057-97751b02f70b/command/fs_ls.go (about) 1 package command 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/dustin/go-humanize" 8 ) 9 10 type FSListCommand struct { 11 Meta 12 } 13 14 func (f *FSListCommand) Help() string { 15 helpText := ` 16 Usage: nomad fs ls <alloc-id> <path> 17 18 ls displays the contents of the allocation directory for the passed allocation. The path 19 is relative to the root of the alloc dir and defaults to root if unspecified. 20 21 General Options: 22 23 ` + generalOptionsUsage() + ` 24 25 Ls Options: 26 27 -H 28 Machine friendly output. 29 30 -verbose 31 Show full information. 32 33 ` 34 return strings.TrimSpace(helpText) 35 } 36 37 func (f *FSListCommand) Synopsis() string { 38 return "List files in an allocation directory" 39 } 40 41 func (f *FSListCommand) Run(args []string) int { 42 var verbose bool 43 var machine bool 44 flags := f.Meta.FlagSet("fs-list", FlagSetClient) 45 flags.Usage = func() { f.Ui.Output(f.Help()) } 46 flags.BoolVar(&verbose, "verbose", false, "") 47 flags.BoolVar(&machine, "H", false, "") 48 49 if err := flags.Parse(args); err != nil { 50 return 1 51 } 52 args = flags.Args() 53 54 if len(args) < 1 { 55 f.Ui.Error("allocation id is a required parameter") 56 return 1 57 } 58 59 allocID := args[0] 60 path := "/" 61 if len(args) == 2 { 62 path = args[1] 63 } 64 65 client, err := f.Meta.Client() 66 if err != nil { 67 f.Ui.Error(fmt.Sprintf("Error inititalizing client: %v", err)) 68 return 1 69 } 70 71 // Truncate the id unless full length is requested 72 length := shortId 73 if verbose { 74 length = fullId 75 } 76 // Query the allocation info 77 alloc, _, err := client.Allocations().Info(allocID, nil) 78 if err != nil { 79 if len(allocID) == 1 { 80 f.Ui.Error(fmt.Sprintf("Alloc ID must contain at least two characters.")) 81 return 1 82 } 83 if len(allocID)%2 == 1 { 84 // Identifiers must be of even length, so we strip off the last byte 85 // to provide a consistent user experience. 86 allocID = allocID[:len(allocID)-1] 87 } 88 89 allocs, _, err := client.Allocations().PrefixList(allocID) 90 if err != nil { 91 f.Ui.Error(fmt.Sprintf("Error querying allocation: %v", err)) 92 return 1 93 } 94 if len(allocs) == 0 { 95 f.Ui.Error(fmt.Sprintf("No allocation(s) with prefix or id %q found", allocID)) 96 return 1 97 } 98 if len(allocs) > 1 { 99 // Format the allocs 100 out := make([]string, len(allocs)+1) 101 out[0] = "ID|Eval ID|Job ID|Task Group|Desired Status|Client Status" 102 for i, alloc := range allocs { 103 out[i+1] = fmt.Sprintf("%s|%s|%s|%s|%s|%s", 104 limit(alloc.ID, length), 105 limit(alloc.EvalID, length), 106 alloc.JobID, 107 alloc.TaskGroup, 108 alloc.DesiredStatus, 109 alloc.ClientStatus, 110 ) 111 } 112 f.Ui.Output(fmt.Sprintf("Prefix matched multiple allocations\n\n%s", formatList(out))) 113 return 0 114 } 115 // Prefix lookup matched a single allocation 116 alloc, _, err = client.Allocations().Info(allocs[0].ID, nil) 117 if err != nil { 118 f.Ui.Error(fmt.Sprintf("Error querying allocation: %s", err)) 119 return 1 120 } 121 } 122 123 // Get the file at the given path 124 files, _, err := client.AllocFS().List(alloc, path, nil) 125 if err != nil { 126 f.Ui.Error(fmt.Sprintf("Error listing alloc dir: %v", err)) 127 return 1 128 } 129 130 // Display the file information in a tabular format 131 out := make([]string, len(files)+1) 132 out[0] = "Mode|Size|Modfied Time|Name" 133 for i, file := range files { 134 fn := file.Name 135 if file.IsDir { 136 fn = fmt.Sprintf("%s/", fn) 137 } 138 var size string 139 if machine { 140 size = fmt.Sprintf("%d", file.Size) 141 } else { 142 size = humanize.Bytes(uint64(file.Size)) 143 } 144 out[i+1] = fmt.Sprintf("%s|%s|%s|%s", 145 file.FileMode, 146 size, 147 formatTime(file.ModTime), 148 fn, 149 ) 150 } 151 152 f.Ui.Output(formatList(out)) 153 return 0 154 }