github.com/blixtra/nomad@v0.7.2-0.20171221000451-da9a1d7bb050/command/job_promote.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 flaghelper "github.com/hashicorp/nomad/helper/flag-helpers" 10 "github.com/posener/complete" 11 ) 12 13 type JobPromoteCommand struct { 14 Meta 15 } 16 17 func (c *JobPromoteCommand) Help() string { 18 helpText := ` 19 Usage: nomad job promote [options] <job id> 20 21 Promote is used to promote task groups in the most recent deployment for the 22 given job. Promotion should occur when the deployment has placed canaries for a 23 task group and those canaries have been deemed healthy. When a task group is 24 promoted, the rolling upgrade of the remaining allocations is unblocked. If the 25 canaries are found to be unhealthy, the deployment may either be failed using 26 the "nomad deployment fail" command, the job can be failed forward by submitting 27 a new version or failed backwards by reverting to an older version using the 28 "nomad job revert" command. 29 30 General Options: 31 32 ` + generalOptionsUsage() + ` 33 34 Promote Options: 35 36 -group 37 Group may be specified many times and is used to promote that particular 38 group. If no specific groups are specified, all groups are promoted. 39 40 -detach 41 Return immediately instead of entering monitor mode. After deployment 42 resume, the evaluation ID will be printed to the screen, which can be used 43 to examine the evaluation using the eval-status command. 44 45 -verbose 46 Display full information. 47 ` 48 return strings.TrimSpace(helpText) 49 } 50 51 func (c *JobPromoteCommand) Synopsis() string { 52 return "Promote a job's canaries" 53 } 54 55 func (c *JobPromoteCommand) AutocompleteFlags() complete.Flags { 56 return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient), 57 complete.Flags{ 58 "-group": complete.PredictAnything, 59 "-detach": complete.PredictNothing, 60 "-verbose": complete.PredictNothing, 61 }) 62 } 63 64 func (c *JobPromoteCommand) AutocompleteArgs() complete.Predictor { 65 return complete.PredictFunc(func(a complete.Args) []string { 66 client, err := c.Meta.Client() 67 if err != nil { 68 return nil 69 } 70 71 resp, _, err := client.Search().PrefixSearch(a.Last, contexts.Jobs, nil) 72 if err != nil { 73 return []string{} 74 } 75 return resp.Matches[contexts.Jobs] 76 }) 77 } 78 79 func (c *JobPromoteCommand) Run(args []string) int { 80 var detach, verbose bool 81 var groups []string 82 83 flags := c.Meta.FlagSet("job promote", FlagSetClient) 84 flags.Usage = func() { c.Ui.Output(c.Help()) } 85 flags.BoolVar(&detach, "detach", false, "") 86 flags.BoolVar(&verbose, "verbose", false, "") 87 flags.Var((*flaghelper.StringFlag)(&groups), "group", "") 88 89 if err := flags.Parse(args); err != nil { 90 return 1 91 } 92 93 // Check that we got no arguments 94 args = flags.Args() 95 if l := len(args); l != 1 { 96 c.Ui.Error(c.Help()) 97 return 1 98 } 99 100 // Truncate the id unless full length is requested 101 length := shortId 102 if verbose { 103 length = fullId 104 } 105 106 // Get the HTTP client 107 client, err := c.Meta.Client() 108 if err != nil { 109 c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err)) 110 return 1 111 } 112 113 // Check if the job exists 114 jobID := args[0] 115 jobs, _, err := client.Jobs().PrefixList(jobID) 116 if err != nil { 117 c.Ui.Error(fmt.Sprintf("Error promoting job: %s", err)) 118 return 1 119 } 120 if len(jobs) == 0 { 121 c.Ui.Error(fmt.Sprintf("No job(s) with prefix or id %q found", jobID)) 122 return 1 123 } 124 if len(jobs) > 1 && strings.TrimSpace(jobID) != jobs[0].ID { 125 c.Ui.Error(fmt.Sprintf("Prefix matched multiple jobs\n\n%s", createStatusListOutput(jobs))) 126 return 1 127 } 128 jobID = jobs[0].ID 129 130 // Do a prefix lookup 131 deploy, _, err := client.Jobs().LatestDeployment(jobID, nil) 132 if err != nil { 133 c.Ui.Error(fmt.Sprintf("Error retrieving deployment: %s", err)) 134 return 1 135 } 136 137 if deploy == nil { 138 c.Ui.Error(fmt.Sprintf("Job %q has no deployment to promote", jobID)) 139 return 1 140 } 141 142 var u *api.DeploymentUpdateResponse 143 if len(groups) == 0 { 144 u, _, err = client.Deployments().PromoteAll(deploy.ID, nil) 145 } else { 146 u, _, err = client.Deployments().PromoteGroups(deploy.ID, groups, nil) 147 } 148 149 if err != nil { 150 c.Ui.Error(fmt.Sprintf("Error promoting deployment %q for job %q: %s", deploy.ID, jobID, err)) 151 return 1 152 } 153 154 // Nothing to do 155 evalCreated := u.EvalID != "" 156 if detach || !evalCreated { 157 return 0 158 } 159 160 mon := newMonitor(c.Ui, client, length) 161 return mon.monitor(u.EvalID, false) 162 }