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