command: first pass at alloc-status command

This commit is contained in:
Ryan Uber 2015-09-27 12:02:14 -07:00
parent 402bcaef18
commit 3d771c5780
3 changed files with 126 additions and 0 deletions

86
command/alloc_status.go Normal file
View File

@ -0,0 +1,86 @@
package command
import (
"fmt"
"strings"
"github.com/hashicorp/nomad/nomad/structs"
)
type AllocStatusCommand struct {
Meta
}
func (c *AllocStatusCommand) Help() string {
helpText := `
Usage: nomad alloc-stauts [options] <allocation>
Display information about existing allocations. This command can
be used to inspect the current status of all allocation,
including its running status, metadata, and verbose failure
messages reported by internal subsystems.
General Options:
` + generalOptionsUsage()
return strings.TrimSpace(helpText)
}
func (c *AllocStatusCommand) Synopsis() string {
return "Display allocation status information and metadata"
}
func (c *AllocStatusCommand) Run(args []string) int {
flags := c.Meta.FlagSet("alloc-status", FlagSetClient)
flags.Usage = func() { c.Ui.Output(c.Help()) }
if err := flags.Parse(args); err != nil {
return 1
}
// Check that we got exactly one allocation ID
args = flags.Args()
if len(args) != 1 {
c.Ui.Error(c.Help())
return 1
}
allocID := 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
}
// Query the allocation info
alloc, _, err := client.Allocations().Info(allocID, nil)
if err != nil {
c.Ui.Error(fmt.Sprintf("Error querying allocation: %s", err))
return 1
}
// Format the allocation data
basic := []string{
fmt.Sprintf("ID|%s", alloc.ID),
fmt.Sprintf("EvalID|%s", alloc.EvalID),
fmt.Sprintf("Name|%s", alloc.Name),
fmt.Sprintf("NodeID|%s", alloc.NodeID),
fmt.Sprintf("JobID|%s", alloc.JobID),
fmt.Sprintf("ClientStatus|%s", alloc.ClientStatus),
fmt.Sprintf("ClientDescription|%s", alloc.ClientDescription),
fmt.Sprintf("NodesEvaluated|%d", alloc.Metrics.NodesEvaluated),
fmt.Sprintf("NodesFiltered|%d", alloc.Metrics.NodesFiltered),
fmt.Sprintf("NodesExhausted|%d", alloc.Metrics.NodesExhausted),
fmt.Sprintf("AllocationTime|%s", alloc.Metrics.AllocationTime),
fmt.Sprintf("CoalescedFailures|%s", alloc.Metrics.CoalescedFailures),
}
c.Ui.Output(formatKV(basic))
// Format any scheduling failures
if alloc.DesiredStatus == structs.AllocDesiredStatusFailed {
c.Ui.Output("\n==> Scheduling Errors")
dumpAllocStatus(c.Ui, alloc)
}
return 0
}

View File

@ -0,0 +1,34 @@
package command
import (
"strings"
"testing"
"github.com/mitchellh/cli"
)
func TestAllocStatusCommand_Implements(t *testing.T) {
var _ cli.Command = &AllocStatusCommand{}
}
func TestAllocStatusCommand_Fails(t *testing.T) {
ui := new(cli.MockUi)
cmd := &AllocStatusCommand{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 connection failure
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 querying allocation") {
t.Fatalf("expected failed query error, got: %s", out)
}
}

View File

@ -24,6 +24,12 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory {
}
return map[string]cli.CommandFactory{
"alloc-status": func() (cli.Command, error) {
return &command.AllocStatusCommand{
Meta: meta,
}, nil
},
"agent": func() (cli.Command, error) {
return &agent.Command{
Revision: GitCommit,