github.com/jrxfive/nomad@v0.6.1-0.20170802162750-1fef470e89bf/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  }