github.com/nir0s/nomad@v0.8.7-rc1/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) Name() string { return "job revert" }
    67  
    68  func (c *JobRevertCommand) Run(args []string) int {
    69  	var detach, verbose bool
    70  
    71  	flags := c.Meta.FlagSet(c.Name(), FlagSetClient)
    72  	flags.Usage = func() { c.Ui.Output(c.Help()) }
    73  	flags.BoolVar(&detach, "detach", false, "")
    74  	flags.BoolVar(&verbose, "verbose", false, "")
    75  
    76  	if err := flags.Parse(args); err != nil {
    77  		return 1
    78  	}
    79  
    80  	// Truncate the id unless full length is requested
    81  	length := shortId
    82  	if verbose {
    83  		length = fullId
    84  	}
    85  
    86  	// Check that we got two args
    87  	args = flags.Args()
    88  	if l := len(args); l != 2 {
    89  		c.Ui.Error("This command takes two arguments: <job> <version>")
    90  		c.Ui.Error(commandErrorText(c))
    91  		return 1
    92  	}
    93  
    94  	// Get the HTTP client
    95  	client, err := c.Meta.Client()
    96  	if err != nil {
    97  		c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
    98  		return 1
    99  	}
   100  
   101  	jobID := args[0]
   102  	revertVersion, ok, err := parseVersion(args[1])
   103  	if !ok {
   104  		c.Ui.Error("The job version to revert to must be specified using the -job-version flag")
   105  		return 1
   106  	}
   107  	if err != nil {
   108  		c.Ui.Error(fmt.Sprintf("Failed to parse job-version flag: %v", err))
   109  		return 1
   110  	}
   111  
   112  	// Check if the job exists
   113  	jobs, _, err := client.Jobs().PrefixList(jobID)
   114  	if err != nil {
   115  		c.Ui.Error(fmt.Sprintf("Error listing jobs: %s", err))
   116  		return 1
   117  	}
   118  	if len(jobs) == 0 {
   119  		c.Ui.Error(fmt.Sprintf("No job(s) with prefix or id %q found", jobID))
   120  		return 1
   121  	}
   122  	if len(jobs) > 1 && strings.TrimSpace(jobID) != jobs[0].ID {
   123  		c.Ui.Error(fmt.Sprintf("Prefix matched multiple jobs\n\n%s", createStatusListOutput(jobs)))
   124  		return 1
   125  	}
   126  
   127  	// Prefix lookup matched a single job
   128  	resp, _, err := client.Jobs().Revert(jobs[0].ID, revertVersion, nil, nil)
   129  	if err != nil {
   130  		c.Ui.Error(fmt.Sprintf("Error retrieving job versions: %s", err))
   131  		return 1
   132  	}
   133  
   134  	// Nothing to do
   135  	evalCreated := resp.EvalID != ""
   136  	if detach || !evalCreated {
   137  		return 0
   138  	}
   139  
   140  	mon := newMonitor(c.Ui, client, length)
   141  	return mon.monitor(resp.EvalID, false)
   142  }