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