github.com/blixtra/nomad@v0.7.2-0.20171221000451-da9a1d7bb050/command/job_revert.go (about)

     1  package command
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/hashicorp/nomad/api/contexts"
     8  	"github.com/posener/complete"
     9  )
    10  
    11  type JobRevertCommand struct {
    12  	Meta
    13  }
    14  
    15  func (c *JobRevertCommand) Help() string {
    16  	helpText := `
    17  Usage: nomad job revert [options] <job> <version>
    18  
    19    Revert is used to revert a job to a prior version of the job. The available
    20    versions to revert to can be found using "nomad job history" command.
    21  
    22  General Options:
    23  
    24    ` + generalOptionsUsage() + `
    25  
    26  Revert Options:
    27  
    28    -detach
    29      Return immediately instead of entering monitor mode. After job revert,
    30      the evaluation ID will be printed to the screen, which can be used to
    31      examine the evaluation using the eval-status command.
    32  
    33    -verbose
    34      Display full information.
    35  `
    36  	return strings.TrimSpace(helpText)
    37  }
    38  
    39  func (c *JobRevertCommand) Synopsis() string {
    40  	return "Revert to a prior version of the job"
    41  }
    42  
    43  func (c *JobRevertCommand) AutocompleteFlags() complete.Flags {
    44  	return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient),
    45  		complete.Flags{
    46  			"-detach":  complete.PredictNothing,
    47  			"-verbose": complete.PredictNothing,
    48  		})
    49  }
    50  
    51  func (c *JobRevertCommand) AutocompleteArgs() complete.Predictor {
    52  	return complete.PredictFunc(func(a complete.Args) []string {
    53  		client, err := c.Meta.Client()
    54  		if err != nil {
    55  			return nil
    56  		}
    57  
    58  		resp, _, err := client.Search().PrefixSearch(a.Last, contexts.Jobs, nil)
    59  		if err != nil {
    60  			return []string{}
    61  		}
    62  		return resp.Matches[contexts.Jobs]
    63  	})
    64  }
    65  
    66  func (c *JobRevertCommand) Run(args []string) int {
    67  	var detach, verbose bool
    68  
    69  	flags := c.Meta.FlagSet("job revert", FlagSetClient)
    70  	flags.Usage = func() { c.Ui.Output(c.Help()) }
    71  	flags.BoolVar(&detach, "detach", false, "")
    72  	flags.BoolVar(&verbose, "verbose", false, "")
    73  
    74  	if err := flags.Parse(args); err != nil {
    75  		return 1
    76  	}
    77  
    78  	// Truncate the id unless full length is requested
    79  	length := shortId
    80  	if verbose {
    81  		length = fullId
    82  	}
    83  
    84  	// Check that we got two args
    85  	args = flags.Args()
    86  	if l := len(args); l != 2 {
    87  		c.Ui.Error(c.Help())
    88  		return 1
    89  	}
    90  
    91  	// Get the HTTP client
    92  	client, err := c.Meta.Client()
    93  	if err != nil {
    94  		c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
    95  		return 1
    96  	}
    97  
    98  	jobID := args[0]
    99  	revertVersion, ok, err := parseVersion(args[1])
   100  	if !ok {
   101  		c.Ui.Error("The job version to revert to must be specified using the -job-version flag")
   102  		return 1
   103  	}
   104  	if err != nil {
   105  		c.Ui.Error(fmt.Sprintf("Failed to parse job-version flag: %v", err))
   106  		return 1
   107  	}
   108  
   109  	// Check if the job exists
   110  	jobs, _, err := client.Jobs().PrefixList(jobID)
   111  	if err != nil {
   112  		c.Ui.Error(fmt.Sprintf("Error listing jobs: %s", err))
   113  		return 1
   114  	}
   115  	if len(jobs) == 0 {
   116  		c.Ui.Error(fmt.Sprintf("No job(s) with prefix or id %q found", jobID))
   117  		return 1
   118  	}
   119  	if len(jobs) > 1 && strings.TrimSpace(jobID) != jobs[0].ID {
   120  		c.Ui.Error(fmt.Sprintf("Prefix matched multiple jobs\n\n%s", createStatusListOutput(jobs)))
   121  		return 1
   122  	}
   123  
   124  	// Prefix lookup matched a single job
   125  	resp, _, err := client.Jobs().Revert(jobs[0].ID, revertVersion, nil, nil)
   126  	if err != nil {
   127  		c.Ui.Error(fmt.Sprintf("Error retrieving job versions: %s", err))
   128  		return 1
   129  	}
   130  
   131  	// Nothing to do
   132  	evalCreated := resp.EvalID != ""
   133  	if detach || !evalCreated {
   134  		return 0
   135  	}
   136  
   137  	mon := newMonitor(c.Ui, client, length)
   138  	return mon.monitor(resp.EvalID, false)
   139  }