github.com/blixtra/nomad@v0.7.2-0.20171221000451-da9a1d7bb050/command/inspect.go (about)

     1  package command
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/hashicorp/nomad/api"
     8  	"github.com/hashicorp/nomad/api/contexts"
     9  	"github.com/posener/complete"
    10  )
    11  
    12  type InspectCommand struct {
    13  	Meta
    14  }
    15  
    16  func (c *InspectCommand) Help() string {
    17  	helpText := `
    18  Usage: nomad inspect [options] <job>
    19  
    20    Inspect is used to see the specification of a submitted job.
    21  
    22  General Options:
    23  
    24    ` + generalOptionsUsage() + `
    25  
    26  Inspect Options:
    27  
    28    -version <job version>
    29      Display the job at the given job version.
    30  
    31    -json
    32      Output the job in its JSON format.
    33  
    34    -t
    35      Format and display job using a Go template.
    36  `
    37  	return strings.TrimSpace(helpText)
    38  }
    39  
    40  func (c *InspectCommand) Synopsis() string {
    41  	return "Inspect a submitted job"
    42  }
    43  
    44  func (c *InspectCommand) AutocompleteFlags() complete.Flags {
    45  	return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient),
    46  		complete.Flags{
    47  			"-version": complete.PredictAnything,
    48  			"-json":    complete.PredictNothing,
    49  			"-t":       complete.PredictAnything,
    50  		})
    51  }
    52  
    53  func (c *InspectCommand) AutocompleteArgs() complete.Predictor {
    54  	return complete.PredictFunc(func(a complete.Args) []string {
    55  		client, err := c.Meta.Client()
    56  		if err != nil {
    57  			return nil
    58  		}
    59  
    60  		resp, _, err := client.Search().PrefixSearch(a.Last, contexts.Jobs, nil)
    61  		if err != nil {
    62  			return []string{}
    63  		}
    64  		return resp.Matches[contexts.Jobs]
    65  	})
    66  }
    67  
    68  func (c *InspectCommand) Run(args []string) int {
    69  	var json bool
    70  	var tmpl, versionStr string
    71  
    72  	flags := c.Meta.FlagSet("inspect", FlagSetClient)
    73  	flags.Usage = func() { c.Ui.Output(c.Help()) }
    74  	flags.BoolVar(&json, "json", false, "")
    75  	flags.StringVar(&tmpl, "t", "", "")
    76  	flags.StringVar(&versionStr, "version", "", "")
    77  
    78  	if err := flags.Parse(args); err != nil {
    79  		return 1
    80  	}
    81  	args = flags.Args()
    82  
    83  	// Get the HTTP client
    84  	client, err := c.Meta.Client()
    85  	if err != nil {
    86  		c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
    87  		return 1
    88  	}
    89  
    90  	// If args not specified but output format is specified, format and output the jobs data list
    91  	if len(args) == 0 && json || len(tmpl) > 0 {
    92  		jobs, _, err := client.Jobs().List(nil)
    93  		if err != nil {
    94  			c.Ui.Error(fmt.Sprintf("Error querying jobs: %v", err))
    95  			return 1
    96  		}
    97  
    98  		out, err := Format(json, tmpl, jobs)
    99  		if err != nil {
   100  			c.Ui.Error(err.Error())
   101  			return 1
   102  		}
   103  
   104  		c.Ui.Output(out)
   105  		return 0
   106  	}
   107  
   108  	// Check that we got exactly one job
   109  	if len(args) != 1 {
   110  		c.Ui.Error(c.Help())
   111  		return 1
   112  	}
   113  	jobID := args[0]
   114  
   115  	// Check if the job exists
   116  	jobs, _, err := client.Jobs().PrefixList(jobID)
   117  	if err != nil {
   118  		c.Ui.Error(fmt.Sprintf("Error inspecting job: %s", err))
   119  		return 1
   120  	}
   121  	if len(jobs) == 0 {
   122  		c.Ui.Error(fmt.Sprintf("No job(s) with prefix or id %q found", jobID))
   123  		return 1
   124  	}
   125  	if len(jobs) > 1 && strings.TrimSpace(jobID) != jobs[0].ID {
   126  		c.Ui.Error(fmt.Sprintf("Prefix matched multiple jobs\n\n%s", createStatusListOutput(jobs)))
   127  		return 1
   128  	}
   129  
   130  	var version *uint64
   131  	if versionStr != "" {
   132  		v, _, err := parseVersion(versionStr)
   133  		if err != nil {
   134  			c.Ui.Error(fmt.Sprintf("Error parsing version value %q: %v", versionStr, err))
   135  			return 1
   136  		}
   137  
   138  		version = &v
   139  	}
   140  
   141  	// Prefix lookup matched a single job
   142  	job, err := getJob(client, jobs[0].ID, version)
   143  	if err != nil {
   144  		c.Ui.Error(fmt.Sprintf("Error inspecting job: %s", err))
   145  		return 1
   146  	}
   147  
   148  	// If output format is specified, format and output the data
   149  	if json || len(tmpl) > 0 {
   150  		out, err := Format(json, tmpl, job)
   151  		if err != nil {
   152  			c.Ui.Error(err.Error())
   153  			return 1
   154  		}
   155  
   156  		c.Ui.Output(out)
   157  		return 0
   158  	}
   159  
   160  	// Print the contents of the job
   161  	req := api.RegisterJobRequest{Job: job}
   162  	f, err := DataFormat("json", "")
   163  	if err != nil {
   164  		c.Ui.Error(fmt.Sprintf("Error getting formatter: %s", err))
   165  		return 1
   166  	}
   167  
   168  	out, err := f.TransformData(req)
   169  	if err != nil {
   170  		c.Ui.Error(fmt.Sprintf("Error formatting the data: %s", err))
   171  		return 1
   172  	}
   173  	c.Ui.Output(out)
   174  	return 0
   175  }
   176  
   177  // getJob retrieves the job optionally at a particular version.
   178  func getJob(client *api.Client, jobID string, version *uint64) (*api.Job, error) {
   179  	if version == nil {
   180  		job, _, err := client.Jobs().Info(jobID, nil)
   181  		return job, err
   182  	}
   183  
   184  	versions, _, _, err := client.Jobs().Versions(jobID, false, nil)
   185  	if err != nil {
   186  		return nil, err
   187  	}
   188  
   189  	for _, j := range versions {
   190  		if *j.Version != *version {
   191  			continue
   192  		}
   193  		return j, nil
   194  	}
   195  
   196  	return nil, fmt.Errorf("job %q with version %d couldn't be found", jobID, *version)
   197  }