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 }