github.com/djenriquez/nomad-1@v0.8.1/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 }