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  }