From e1c4fcf721910cce50ea4d60852d071b9629cff9 Mon Sep 17 00:00:00 2001 From: Ryan Uber Date: Sun, 27 Sep 2015 12:02:14 -0700 Subject: [PATCH] command: first pass at alloc-status command --- command/alloc_status.go | 86 ++++++++++++++++++++++++++++++++++++ command/alloc_status_test.go | 34 ++++++++++++++ commands.go | 6 +++ 3 files changed, 126 insertions(+) create mode 100644 command/alloc_status.go create mode 100644 command/alloc_status_test.go diff --git a/command/alloc_status.go b/command/alloc_status.go new file mode 100644 index 000000000..c80eadb3a --- /dev/null +++ b/command/alloc_status.go @@ -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] + + 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 +} diff --git a/command/alloc_status_test.go b/command/alloc_status_test.go new file mode 100644 index 000000000..c8478bb7a --- /dev/null +++ b/command/alloc_status_test.go @@ -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) + } +} diff --git a/commands.go b/commands.go index 3e130a525..aedabecb5 100644 --- a/commands.go +++ b/commands.go @@ -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,