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