diff --git a/api/allocations.go b/api/allocations.go index b7db0f29ac53..92baad9083f9 100644 --- a/api/allocations.go +++ b/api/allocations.go @@ -8,6 +8,12 @@ import ( "github.com/hashicorp/go-cleanhttp" ) +var ( + // NodeDownErr marks an operation as not able to complete since the node is + // down. + NodeDownErr = fmt.Errorf("node down") +) + // Allocations is used to query the alloc-related endpoints. type Allocations struct { client *Client @@ -48,6 +54,9 @@ func (a *Allocations) Stats(alloc *Allocation, q *QueryOptions) (*AllocResourceU if err != nil { return nil, err } + if node.Status == "down" { + return nil, NodeDownErr + } if node.HTTPAddr == "" { return nil, fmt.Errorf("http addr of the node where alloc %q is running is not advertised", alloc.ID) } diff --git a/command/alloc_status.go b/command/alloc_status.go index 566743e48454..d0c8b09e51b5 100644 --- a/command/alloc_status.go +++ b/command/alloc_status.go @@ -234,7 +234,11 @@ func (c *AllocStatusCommand) Run(args []string) int { stats, statsErr = client.Allocations().Stats(alloc, nil) if statsErr != nil { c.Ui.Output("") - c.Ui.Error(fmt.Sprintf("couldn't retrieve stats (HINT: ensure Client.Advertise.HTTP is set): %v", statsErr)) + if statsErr != api.NodeDownErr { + c.Ui.Error(fmt.Sprintf("couldn't retrieve stats (HINT: ensure Client.Advertise.HTTP is set): %v", statsErr)) + } else { + c.Ui.Output("Omitting resource statistics since the node is down.") + } } c.outputTaskDetails(alloc, stats, displayStats) } @@ -414,12 +418,14 @@ func (c *AllocStatusCommand) outputTaskResources(alloc *api.Allocation, task str // Display the rolled up stats. If possible prefer the live stastics cpuUsage := strconv.Itoa(resource.CPU) memUsage := humanize.IBytes(uint64(resource.MemoryMB * bytesPerMegabyte)) - if ru, ok := stats.Tasks[task]; ok && ru != nil && ru.ResourceUsage != nil { - if cs := ru.ResourceUsage.CpuStats; cs != nil { - cpuUsage = fmt.Sprintf("%v/%v", math.Floor(cs.TotalTicks), resource.CPU) - } - if ms := ru.ResourceUsage.MemoryStats; ms != nil { - memUsage = fmt.Sprintf("%v/%v", humanize.IBytes(ms.RSS), memUsage) + if stats != nil { + if ru, ok := stats.Tasks[task]; ok && ru != nil && ru.ResourceUsage != nil { + if cs := ru.ResourceUsage.CpuStats; cs != nil { + cpuUsage = fmt.Sprintf("%v/%v", math.Floor(cs.TotalTicks), resource.CPU) + } + if ms := ru.ResourceUsage.MemoryStats; ms != nil { + memUsage = fmt.Sprintf("%v/%v", humanize.IBytes(ms.RSS), memUsage) + } } } resourcesOutput = append(resourcesOutput, fmt.Sprintf("%v MHz|%v|%v|%v|%v", @@ -433,9 +439,11 @@ func (c *AllocStatusCommand) outputTaskResources(alloc *api.Allocation, task str } c.Ui.Output(formatListWithSpaces(resourcesOutput)) - if ru, ok := stats.Tasks[task]; ok && ru != nil && displayStats && ru.ResourceUsage != nil { - c.Ui.Output("") - c.outputVerboseResourceUsage(task, ru.ResourceUsage) + if stats != nil { + if ru, ok := stats.Tasks[task]; ok && ru != nil && displayStats && ru.ResourceUsage != nil { + c.Ui.Output("") + c.outputVerboseResourceUsage(task, ru.ResourceUsage) + } } }