github.com/djenriquez/nomad-1@v0.8.1/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) Run(args []string) int { 70 var json bool 71 var tmpl, versionStr string 72 73 flags := c.Meta.FlagSet("job inspect", FlagSetClient) 74 flags.Usage = func() { c.Ui.Output(c.Help()) } 75 flags.BoolVar(&json, "json", false, "") 76 flags.StringVar(&tmpl, "t", "", "") 77 flags.StringVar(&versionStr, "version", "", "") 78 79 if err := flags.Parse(args); err != nil { 80 return 1 81 } 82 args = flags.Args() 83 84 // Get the HTTP client 85 client, err := c.Meta.Client() 86 if err != nil { 87 c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err)) 88 return 1 89 } 90 91 // If args not specified but output format is specified, format and output the jobs data list 92 if len(args) == 0 && json || len(tmpl) > 0 { 93 jobs, _, err := client.Jobs().List(nil) 94 if err != nil { 95 c.Ui.Error(fmt.Sprintf("Error querying jobs: %v", err)) 96 return 1 97 } 98 99 out, err := Format(json, tmpl, jobs) 100 if err != nil { 101 c.Ui.Error(err.Error()) 102 return 1 103 } 104 105 c.Ui.Output(out) 106 return 0 107 } 108 109 // Check that we got exactly one job 110 if len(args) != 1 { 111 c.Ui.Error(c.Help()) 112 return 1 113 } 114 jobID := args[0] 115 116 // Check if the job exists 117 jobs, _, err := client.Jobs().PrefixList(jobID) 118 if err != nil { 119 c.Ui.Error(fmt.Sprintf("Error inspecting job: %s", err)) 120 return 1 121 } 122 if len(jobs) == 0 { 123 c.Ui.Error(fmt.Sprintf("No job(s) with prefix or id %q found", jobID)) 124 return 1 125 } 126 if len(jobs) > 1 && strings.TrimSpace(jobID) != jobs[0].ID { 127 c.Ui.Error(fmt.Sprintf("Prefix matched multiple jobs\n\n%s", createStatusListOutput(jobs))) 128 return 1 129 } 130 131 var version *uint64 132 if versionStr != "" { 133 v, _, err := parseVersion(versionStr) 134 if err != nil { 135 c.Ui.Error(fmt.Sprintf("Error parsing version value %q: %v", versionStr, err)) 136 return 1 137 } 138 139 version = &v 140 } 141 142 // Prefix lookup matched a single job 143 job, err := getJob(client, jobs[0].ID, version) 144 if err != nil { 145 c.Ui.Error(fmt.Sprintf("Error inspecting job: %s", err)) 146 return 1 147 } 148 149 // If output format is specified, format and output the data 150 if json || len(tmpl) > 0 { 151 out, err := Format(json, tmpl, job) 152 if err != nil { 153 c.Ui.Error(err.Error()) 154 return 1 155 } 156 157 c.Ui.Output(out) 158 return 0 159 } 160 161 // Print the contents of the job 162 req := api.RegisterJobRequest{Job: job} 163 f, err := DataFormat("json", "") 164 if err != nil { 165 c.Ui.Error(fmt.Sprintf("Error getting formatter: %s", err)) 166 return 1 167 } 168 169 out, err := f.TransformData(req) 170 if err != nil { 171 c.Ui.Error(fmt.Sprintf("Error formatting the data: %s", err)) 172 return 1 173 } 174 c.Ui.Output(out) 175 return 0 176 } 177 178 // getJob retrieves the job optionally at a particular version. 179 func getJob(client *api.Client, jobID string, version *uint64) (*api.Job, error) { 180 if version == nil { 181 job, _, err := client.Jobs().Info(jobID, nil) 182 return job, err 183 } 184 185 versions, _, _, err := client.Jobs().Versions(jobID, false, nil) 186 if err != nil { 187 return nil, err 188 } 189 190 for _, j := range versions { 191 if *j.Version != *version { 192 continue 193 } 194 return j, nil 195 } 196 197 return nil, fmt.Errorf("job %q with version %d couldn't be found", jobID, *version) 198 }