command/stop: inital stop command

This commit is contained in:
Ryan Uber 2015-09-16 17:35:58 -07:00
parent 8f9877edaa
commit 099fd00760
3 changed files with 137 additions and 0 deletions

85
command/stop.go Normal file
View File

@ -0,0 +1,85 @@
package command
import (
"fmt"
"strings"
)
type StopCommand struct {
Meta
}
func (c *StopCommand) Help() string {
helpText := `
Usage: nomad stop [options] <job>
Stop an existing job. This command is used to signal allocations
to shut down for the given job ID. The shutdown happens
asynchronously, unless the -monitor flag is given, in which case
an interactive monitor session will display log lines as the
job unwinds and completes shutting down.
General Options:
` + generalOptionsUsage() + `
Stop Options:
-monitor
Starts an interactive monitor for the job deregistration. This
will display logs in the terminal related to the job shutdown,
and return once the job deregistration has completed.
`
return strings.TrimSpace(helpText)
}
func (c *StopCommand) Synopsis() string {
return "Stop a running job"
}
func (c *StopCommand) Run(args []string) int {
var monitor bool
flags := c.Meta.FlagSet("stop", FlagSetClient)
flags.Usage = func() { c.Ui.Output(c.Help()) }
flags.BoolVar(&monitor, "monitor", false, "")
if err := flags.Parse(args); err != nil {
return 1
}
// Check that we got exactly one job
args = flags.Args()
if len(args) != 1 {
c.Ui.Error(c.Help())
return 1
}
jobID := args[0]
// Get the HTTP client
client, err := c.Meta.Client()
if err != nil {
c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
return 1
}
// Check if the job exists
if _, _, err := client.Jobs().Info(jobID, nil); err != nil {
c.Ui.Error(fmt.Sprintf("Error deregistering job: %s", err))
return 1
}
// Invoke the stop
evalID, _, err := client.Jobs().Deregister(jobID, nil)
if err != nil {
c.Ui.Error(fmt.Sprintf("Error deregistering job: %s", err))
return 1
}
if monitor {
mon := newMonitor(c.Ui, client)
return mon.monitor(evalID)
}
return 0
}

46
command/stop_test.go Normal file
View File

@ -0,0 +1,46 @@
package command
import (
"strings"
"testing"
"github.com/mitchellh/cli"
)
func TestStopCommand_Implements(t *testing.T) {
var _ cli.Command = &StopCommand{}
}
func TestStopCommand_Fails(t *testing.T) {
srv, _, url := testServer(t, nil)
defer srv.Stop()
ui := new(cli.MockUi)
cmd := &StopCommand{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()
// Fails on non-existent job ID
if code := cmd.Run([]string{"-address=" + url, "nope"}); code != 1 {
t.Fatalf("expect exit 1, got: %d", code)
}
if out := ui.ErrorWriter.String(); !strings.Contains(out, "not found") {
t.Fatalf("expect not found error, got: %s", out)
}
ui.ErrorWriter.Reset()
// Fails on connection failure
if code := cmd.Run([]string{"-address=nope", "nope"}); code != 1 {
t.Fatalf("expected exit code 1, got: %d", code)
}
if out := ui.ErrorWriter.String(); !strings.Contains(out, "Error deregistering job") {
t.Fatalf("expected failed query error, got: %s", out)
}
}

View File

@ -94,6 +94,12 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory {
}, nil
},
"stop": func() (cli.Command, error) {
return &command.StopCommand{
Meta: meta,
}, nil
},
"version": func() (cli.Command, error) {
ver := Version
rel := VersionPrerelease