1package command
2
3import (
4	"fmt"
5	"strings"
6
7	"github.com/hashicorp/nomad/api/contexts"
8	"github.com/posener/complete"
9)
10
11type JobDeploymentsCommand struct {
12	Meta
13}
14
15func (c *JobDeploymentsCommand) Help() string {
16	helpText := `
17Usage: nomad job deployments [options] <job>
18
19  Deployments is used to display the deployments for a particular job.
20
21General Options:
22
23  ` + generalOptionsUsage() + `
24
25Deployments Options:
26
27  -json
28    Output the deployments in a JSON format.
29
30  -t
31    Format and display deployments using a Go template.
32
33  -latest
34    Display the latest deployment only.
35
36  -verbose
37    Display full information.
38
39  -all
40    Display all deployments matching the job ID, including those
41    from an older instance of the job.
42`
43	return strings.TrimSpace(helpText)
44}
45
46func (c *JobDeploymentsCommand) Synopsis() string {
47	return "List deployments for a job"
48}
49
50func (c *JobDeploymentsCommand) AutocompleteFlags() complete.Flags {
51	return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient),
52		complete.Flags{
53			"-json":    complete.PredictNothing,
54			"-t":       complete.PredictAnything,
55			"-latest":  complete.PredictNothing,
56			"-verbose": complete.PredictNothing,
57			"-all":     complete.PredictNothing,
58		})
59}
60
61func (c *JobDeploymentsCommand) AutocompleteArgs() complete.Predictor {
62	return complete.PredictFunc(func(a complete.Args) []string {
63		client, err := c.Meta.Client()
64		if err != nil {
65			return nil
66		}
67
68		resp, _, err := client.Search().PrefixSearch(a.Last, contexts.Jobs, nil)
69		if err != nil {
70			return []string{}
71		}
72		return resp.Matches[contexts.Jobs]
73	})
74}
75
76func (c *JobDeploymentsCommand) Name() string { return "job deployments" }
77
78func (c *JobDeploymentsCommand) Run(args []string) int {
79	var json, latest, verbose, all bool
80	var tmpl string
81
82	flags := c.Meta.FlagSet(c.Name(), FlagSetClient)
83	flags.Usage = func() { c.Ui.Output(c.Help()) }
84	flags.BoolVar(&latest, "latest", false, "")
85	flags.BoolVar(&verbose, "verbose", false, "")
86	flags.BoolVar(&all, "all", false, "")
87	flags.BoolVar(&json, "json", false, "")
88	flags.StringVar(&tmpl, "t", "", "")
89
90	if err := flags.Parse(args); err != nil {
91		return 1
92	}
93
94	// Check that we got exactly one node
95	args = flags.Args()
96	if l := len(args); l != 1 {
97		c.Ui.Error("This command takes one argument: <job>")
98		c.Ui.Error(commandErrorText(c))
99		return 1
100	}
101
102	// Get the HTTP client
103	client, err := c.Meta.Client()
104	if err != nil {
105		c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
106		return 1
107	}
108
109	jobID := args[0]
110
111	// Check if the job exists
112	jobs, _, err := client.Jobs().PrefixList(jobID)
113	if err != nil {
114		c.Ui.Error(fmt.Sprintf("Error listing jobs: %s", err))
115		return 1
116	}
117	if len(jobs) == 0 {
118		c.Ui.Error(fmt.Sprintf("No job(s) with prefix or id %q found", jobID))
119		return 1
120	}
121	if len(jobs) > 1 && strings.TrimSpace(jobID) != jobs[0].ID {
122		c.Ui.Error(fmt.Sprintf("Prefix matched multiple jobs\n\n%s", createStatusListOutput(jobs)))
123		return 1
124	}
125	jobID = jobs[0].ID
126
127	// Truncate the id unless full length is requested
128	length := shortId
129	if verbose {
130		length = fullId
131	}
132
133	if latest {
134		deploy, _, err := client.Jobs().LatestDeployment(jobID, nil)
135		if err != nil {
136			c.Ui.Error(fmt.Sprintf("Error retrieving deployments: %s", err))
137			return 1
138		}
139
140		if json || len(tmpl) > 0 {
141			out, err := Format(json, tmpl, deploy)
142			if err != nil {
143				c.Ui.Error(err.Error())
144				return 1
145			}
146
147			c.Ui.Output(out)
148			return 0
149		}
150
151		c.Ui.Output(c.Colorize().Color(formatDeployment(deploy, length)))
152		return 0
153	}
154
155	deploys, _, err := client.Jobs().Deployments(jobID, all, nil)
156	if err != nil {
157		c.Ui.Error(fmt.Sprintf("Error retrieving deployments: %s", err))
158		return 1
159	}
160
161	if json || len(tmpl) > 0 {
162		out, err := Format(json, tmpl, deploys)
163		if err != nil {
164			c.Ui.Error(err.Error())
165			return 1
166		}
167
168		c.Ui.Output(out)
169		return 0
170	}
171
172	c.Ui.Output(formatDeployments(deploys, length))
173	return 0
174}
175