command: simplify alloc status, dump during job run

This commit is contained in:
Ryan Uber
2015-09-20 17:38:25 -07:00
parent 4c53cbb608
commit ebfc98e0b6
2 changed files with 43 additions and 47 deletions

View File

@@ -3,6 +3,9 @@ package command
import (
"fmt"
"strings"
"github.com/hashicorp/nomad/api"
"github.com/mitchellh/cli"
)
type AllocStatusCommand struct {
@@ -54,52 +57,36 @@ func (c *AllocStatusCommand) Run(args []string) int {
return 1
}
// Format the allocation
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("TaskGroup|%s", alloc.TaskGroup),
fmt.Sprintf("DesiredStatus|%s", alloc.DesiredStatus),
fmt.Sprintf("DesiredDescription|%s", alloc.DesiredDescription),
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),
}
// Format exhaustion info
var exInfo []string
if ne := alloc.Metrics.NodesExhausted; ne > 0 {
exInfo = append(exInfo, fmt.Sprintf("Node resources (exhausted %d)", ne))
}
for class, num := range alloc.Metrics.ClassExhausted {
exInfo = append(exInfo, fmt.Sprintf("Class %q (exhausted %d)", class, num))
}
for dim, num := range alloc.Metrics.DimensionExhausted {
exInfo = append(exInfo, fmt.Sprintf("Dimension %q (exhausted %d)", dim, num))
}
// Format the filter info
var filterInfo []string
for class, num := range alloc.Metrics.ClassFiltered {
filterInfo = append(filterInfo, fmt.Sprintf("Class %q (filtered %d)", class, num))
}
for cs, num := range alloc.Metrics.ConstraintFiltered {
filterInfo = append(filterInfo, fmt.Sprintf("Constraint %q (filtered %d)", cs, num))
}
// Dump the output
c.Ui.Output(formatKV(basic))
if len(exInfo) > 0 {
c.Ui.Output("\n==> Nodes Exhausted")
c.Ui.Output(strings.Join(exInfo, "\n"))
}
if len(filterInfo) > 0 {
c.Ui.Output("\n==> Filters Applied")
c.Ui.Output(strings.Join(filterInfo, "\n"))
}
// Dump any allocation data
dumpAllocStatus(c.Ui, alloc)
return 0
}
// dumpAllocStatus is a helper to generate a more user-friendly error message
// for scheduling failures, displaying a high level status of why the job
// could not be scheduled out.
func dumpAllocStatus(ui cli.Ui, alloc *api.Allocation) {
// Print filter stats
ui.Output(fmt.Sprintf("Allocation %q status %q (%d/%d nodes filtered)",
alloc.ID, alloc.ClientStatus,
alloc.Metrics.NodesFiltered, alloc.Metrics.NodesEvaluated))
// Print exhaustion info
if ne := alloc.Metrics.NodesExhausted; ne > 0 {
ui.Output(fmt.Sprintf("Resources exhausted on %d nodes", ne))
}
for class, num := range alloc.Metrics.ClassExhausted {
ui.Output(fmt.Sprintf("Class %q exhausted on %d nodes", class, num))
}
for dim, num := range alloc.Metrics.DimensionExhausted {
ui.Output(fmt.Sprintf("Dimension %q exhausted on %d nodes", dim, num))
}
// Print filter info
for class, num := range alloc.Metrics.ClassFiltered {
ui.Output(fmt.Sprintf("Class %q filtered %d nodes", class, num))
}
for cs, num := range alloc.Metrics.ConstraintFiltered {
ui.Output(fmt.Sprintf("Constraint %q filtered %d nodes", cs, num))
}
}

View File

@@ -113,6 +113,15 @@ func (m *monitor) update(eval *api.Evaluation, allocs []*api.AllocationListStub)
m.ui.Output(fmt.Sprintf("Scheduling error for group %q (%s)",
alloc.group, alloc.desiredDesc))
// Generate a more descriptive error for why the allocation
// failed and dump it to the screen
fullAlloc, _, err := m.client.Allocations().Info(allocID, nil)
if err != nil {
m.ui.Output(fmt.Sprintf("Error querying alloc: %s", err))
continue
}
dumpAllocStatus(m.ui, fullAlloc)
case alloc.index < update.index:
// New alloc with create index lower than the eval
// create index indicates modification