job revert
This commit is contained in:
parent
2471b86dec
commit
7719306ef3
|
@ -247,7 +247,6 @@ func (j *Jobs) Dispatch(jobID string, meta map[string]string,
|
|||
return &resp, wm, nil
|
||||
}
|
||||
|
||||
// XXX
|
||||
// Revert is used to revert the given job to the passed version. If
|
||||
// enforceVersion is set, the job is only reverted if the current version is at
|
||||
// the passed version.
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type JobRevertCommand struct {
|
||||
Meta
|
||||
formatter DataFormatter
|
||||
}
|
||||
|
||||
func (c *JobRevertCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: nomad job revert [options] <job>
|
||||
|
||||
Revert is used to revert a job to a prior version of the job. The available
|
||||
versions to revert to can be found using "nomad job history" command.
|
||||
|
||||
General Options:
|
||||
|
||||
` + generalOptionsUsage() + `
|
||||
|
||||
History Options:
|
||||
|
||||
-job-version <job version>
|
||||
Revert to the given job version.
|
||||
|
||||
-detach
|
||||
Return immediately instead of entering monitor mode. After job dispatch,
|
||||
the evaluation ID will be printed to the screen, which can be used to
|
||||
examine the evaluation using the eval-status command.
|
||||
|
||||
-verbose
|
||||
Display full information.
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *JobRevertCommand) Synopsis() string {
|
||||
return "Revert to a prior version of the job"
|
||||
}
|
||||
|
||||
func (c *JobRevertCommand) Run(args []string) int {
|
||||
var detach, verbose bool
|
||||
var versionStr string
|
||||
|
||||
flags := c.Meta.FlagSet("job history", FlagSetClient)
|
||||
flags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
flags.StringVar(&versionStr, "job-version", "", "")
|
||||
flags.BoolVar(&detach, "detach", false, "")
|
||||
flags.BoolVar(&verbose, "verbose", false, "")
|
||||
|
||||
if err := flags.Parse(args); err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
// Truncate the id unless full length is requested
|
||||
length := shortId
|
||||
if verbose {
|
||||
length = fullId
|
||||
}
|
||||
|
||||
// Check that we got exactly one node
|
||||
args = flags.Args()
|
||||
if l := len(args); l < 1 || l > 2 {
|
||||
c.Ui.Error(c.Help())
|
||||
return 1
|
||||
}
|
||||
|
||||
// Get the HTTP client
|
||||
client, err := c.Meta.Client()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
jobID := args[0]
|
||||
|
||||
// Check if the job exists
|
||||
jobs, _, err := client.Jobs().PrefixList(jobID)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error listing jobs: %s", err))
|
||||
return 1
|
||||
}
|
||||
if len(jobs) == 0 {
|
||||
c.Ui.Error(fmt.Sprintf("No job(s) with prefix or id %q found", jobID))
|
||||
return 1
|
||||
}
|
||||
if len(jobs) > 1 && strings.TrimSpace(jobID) != jobs[0].ID {
|
||||
c.Ui.Output(fmt.Sprintf("Prefix matched multiple jobs\n\n%s", createStatusListOutput(jobs)))
|
||||
return 0
|
||||
}
|
||||
|
||||
revertVersion, ok, err := parseVersion(versionStr)
|
||||
if !ok {
|
||||
c.Ui.Error("The job version to revert to must be specified using the -job-version flag")
|
||||
return 1
|
||||
}
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Failed to parse job-version flag: %v", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
// Prefix lookup matched a single job
|
||||
resp, _, err := client.Jobs().Revert(jobs[0].ID, revertVersion, nil, nil)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error retrieving job versions: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
// Nothing to do
|
||||
evalCreated := resp.EvalID != ""
|
||||
if detach || !evalCreated {
|
||||
return 0
|
||||
}
|
||||
|
||||
mon := newMonitor(c.Ui, client, length)
|
||||
return mon.monitor(resp.EvalID, false)
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func TestJobRevertCommand_Implements(t *testing.T) {
|
||||
var _ cli.Command = &JobDispatchCommand{}
|
||||
}
|
||||
|
||||
func TestJobRevertCommand_Fails(t *testing.T) {
|
||||
ui := new(cli.MockUi)
|
||||
cmd := &JobRevertCommand{Meta: Meta{Ui: ui}}
|
||||
|
||||
// Fails on misuse
|
||||
if code := cmd.Run([]string{"some", "bad", "args"}); code != 1 {
|
||||
t.Fatalf("expected exit code 1, got: %d", code)
|
||||
}
|
||||
if out := ui.ErrorWriter.String(); !strings.Contains(out, cmd.Help()) {
|
||||
t.Fatalf("expected help output, got: %s", out)
|
||||
}
|
||||
ui.ErrorWriter.Reset()
|
||||
|
||||
if code := cmd.Run([]string{"-address=nope", "foo"}); code != 1 {
|
||||
t.Fatalf("expected exit code 1, got: %d", code)
|
||||
}
|
||||
if out := ui.ErrorWriter.String(); !strings.Contains(out, "Error listing jobs") {
|
||||
t.Fatalf("expected failed query error, got: %s", out)
|
||||
}
|
||||
ui.ErrorWriter.Reset()
|
||||
}
|
|
@ -104,6 +104,11 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory {
|
|||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
"job revert": func() (cli.Command, error) {
|
||||
return &command.JobRevertCommand{
|
||||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
"logs": func() (cli.Command, error) {
|
||||
return &command.LogsCommand{
|
||||
Meta: meta,
|
||||
|
|
2
main.go
2
main.go
|
@ -40,7 +40,7 @@ func RunCustom(args []string, commands map[string]cli.CommandFactory) int {
|
|||
case "executor":
|
||||
case "syslog":
|
||||
case "operator raft", "operator raft list-peers", "operator raft remove-peer":
|
||||
case "job dispatch", "job history":
|
||||
case "job dispatch", "job history", "job revert":
|
||||
case "fs ls", "fs cat", "fs stat":
|
||||
case "check":
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue