func (c *AllocStatusCommand) Run(args []string) int { var short, displayStats, verbose, json bool var tmpl string flags := c.Meta.FlagSet("alloc-status", FlagSetClient) flags.Usage = func() { c.Ui.Output(c.Help()) } flags.BoolVar(&short, "short", false, "") flags.BoolVar(&verbose, "verbose", false, "") flags.BoolVar(&displayStats, "stats", false, "") flags.BoolVar(&json, "json", false, "") flags.StringVar(&tmpl, "t", "", "") if err := flags.Parse(args); err != nil { return 1 } // Check that we got exactly one allocation ID args = flags.Args() // Get the HTTP client client, err := c.Meta.Client() if err != nil { c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err)) return 1 } // If args not specified but output format is specified, format and output the allocations data list if len(args) == 0 { var format string if json && len(tmpl) > 0 { c.Ui.Error("Both -json and -t are not allowed") return 1 } else if json { format = "json" } else if len(tmpl) > 0 { format = "template" } if len(format) > 0 { allocs, _, err := client.Allocations().List(nil) if err != nil { c.Ui.Error(fmt.Sprintf("Error querying allocations: %v", err)) return 1 } // Return nothing if no allocations found if len(allocs) == 0 { return 0 } f, err := DataFormat(format, tmpl) if err != nil { c.Ui.Error(fmt.Sprintf("Error getting formatter: %s", err)) return 1 } out, err := f.TransformData(allocs) if err != nil { c.Ui.Error(fmt.Sprintf("Error formatting the data: %s", err)) return 1 } c.Ui.Output(out) return 0 } } if len(args) != 1 { c.Ui.Error(c.Help()) return 1 } allocID := args[0] // Truncate the id unless full length is requested length := shortId if verbose { length = fullId } // Query the allocation info if len(allocID) == 1 { c.Ui.Error(fmt.Sprintf("Identifier must contain at least two characters.")) return 1 } if len(allocID)%2 == 1 { // Identifiers must be of even length, so we strip off the last byte // to provide a consistent user experience. allocID = allocID[:len(allocID)-1] } allocs, _, err := client.Allocations().PrefixList(allocID) if err != nil { c.Ui.Error(fmt.Sprintf("Error querying allocation: %v", err)) return 1 } if len(allocs) == 0 { c.Ui.Error(fmt.Sprintf("No allocation(s) with prefix or id %q found", allocID)) return 1 } if len(allocs) > 1 { // Format the allocs out := make([]string, len(allocs)+1) out[0] = "ID|Eval ID|Job ID|Task Group|Desired Status|Client Status" for i, alloc := range allocs { out[i+1] = fmt.Sprintf("%s|%s|%s|%s|%s|%s", limit(alloc.ID, length), limit(alloc.EvalID, length), alloc.JobID, alloc.TaskGroup, alloc.DesiredStatus, alloc.ClientStatus, ) } c.Ui.Output(fmt.Sprintf("Prefix matched multiple allocations\n\n%s", formatList(out))) return 0 } // Prefix lookup matched a single allocation alloc, _, err := client.Allocations().Info(allocs[0].ID, nil) if err != nil { c.Ui.Error(fmt.Sprintf("Error querying allocation: %s", err)) return 1 } // If output format is specified, format and output the data var format string if json && len(tmpl) > 0 { c.Ui.Error("Both -json and -t are not allowed") return 1 } else if json { format = "json" } else if len(tmpl) > 0 { format = "template" } if len(format) > 0 { f, err := DataFormat(format, tmpl) if err != nil { c.Ui.Error(fmt.Sprintf("Error getting formatter: %s", err)) return 1 } out, err := f.TransformData(alloc) if err != nil { c.Ui.Error(fmt.Sprintf("Error formatting the data: %s", err)) return 1 } c.Ui.Output(out) return 0 } // Format the allocation data basic := []string{ fmt.Sprintf("ID|%s", limit(alloc.ID, length)), fmt.Sprintf("Eval ID|%s", limit(alloc.EvalID, length)), fmt.Sprintf("Name|%s", alloc.Name), fmt.Sprintf("Node ID|%s", limit(alloc.NodeID, length)), fmt.Sprintf("Job ID|%s", alloc.JobID), fmt.Sprintf("Client Status|%s", alloc.ClientStatus), fmt.Sprintf("Created At|%s", formatUnixNanoTime(alloc.CreateTime)), } if verbose { basic = append(basic, fmt.Sprintf("Evaluated Nodes|%d", alloc.Metrics.NodesEvaluated), fmt.Sprintf("Filtered Nodes|%d", alloc.Metrics.NodesFiltered), fmt.Sprintf("Exhausted Nodes|%d", alloc.Metrics.NodesExhausted), fmt.Sprintf("Allocation Time|%s", alloc.Metrics.AllocationTime), fmt.Sprintf("Failures|%d", alloc.Metrics.CoalescedFailures)) } c.Ui.Output(formatKV(basic)) if short { c.shortTaskStatus(alloc) } else { var statsErr error var stats *api.AllocResourceUsage 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)) } c.outputTaskDetails(alloc, stats, displayStats) } // Format the detailed status if verbose { c.Ui.Output(c.Colorize().Color("\n[bold]Placement Metrics[reset]")) c.Ui.Output(formatAllocMetrics(alloc.Metrics, true, " ")) } return 0 }
func (c *AllocStatusCommand) Run(args []string) int { var short, verbose bool flags := c.Meta.FlagSet("alloc-status", FlagSetClient) flags.Usage = func() { c.Ui.Output(c.Help()) } flags.BoolVar(&short, "short", false, "") flags.BoolVar(&verbose, "verbose", false, "") 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 } // Truncate the id unless full length is requested length := shortId if verbose { length = fullId } // Query the allocation info if len(allocID) == 1 { c.Ui.Error(fmt.Sprintf("Identifier must contain at least two characters.")) return 1 } if len(allocID)%2 == 1 { // Identifiers must be of even length, so we strip off the last byte // to provide a consistent user experience. allocID = allocID[:len(allocID)-1] } allocs, _, err := client.Allocations().PrefixList(allocID) if err != nil { c.Ui.Error(fmt.Sprintf("Error querying allocation: %v", err)) return 1 } if len(allocs) == 0 { c.Ui.Error(fmt.Sprintf("No allocation(s) with prefix or id %q found", allocID)) return 1 } if len(allocs) > 1 { // Format the allocs out := make([]string, len(allocs)+1) out[0] = "ID|Eval ID|Job ID|Task Group|Desired Status|Client Status" for i, alloc := range allocs { out[i+1] = fmt.Sprintf("%s|%s|%s|%s|%s|%s", limit(alloc.ID, length), limit(alloc.EvalID, length), alloc.JobID, alloc.TaskGroup, alloc.DesiredStatus, alloc.ClientStatus, ) } c.Ui.Output(fmt.Sprintf("Prefix matched multiple allocations\n\n%s", formatList(out))) return 0 } // Prefix lookup matched a single allocation alloc, _, err := client.Allocations().Info(allocs[0].ID, nil) if err != nil { c.Ui.Error(fmt.Sprintf("Error querying allocation: %s", err)) return 1 } stats, err := client.Allocations().Stats(alloc, nil) if err != nil { c.Ui.Error(fmt.Sprintf("couldn't retreive stats: %v", err)) } // Format the allocation data basic := []string{ fmt.Sprintf("ID|%s", limit(alloc.ID, length)), fmt.Sprintf("Eval ID|%s", limit(alloc.EvalID, length)), fmt.Sprintf("Name|%s", alloc.Name), fmt.Sprintf("Node ID|%s", limit(alloc.NodeID, length)), fmt.Sprintf("Job ID|%s", alloc.JobID), fmt.Sprintf("Client Status|%s", alloc.ClientStatus), } if verbose { basic = append(basic, fmt.Sprintf("Evaluated Nodes|%d", alloc.Metrics.NodesEvaluated), fmt.Sprintf("Filtered Nodes|%d", alloc.Metrics.NodesFiltered), fmt.Sprintf("Exhausted Nodes|%d", alloc.Metrics.NodesExhausted), fmt.Sprintf("Allocation Time|%s", alloc.Metrics.AllocationTime), fmt.Sprintf("Failures|%d", alloc.Metrics.CoalescedFailures)) } c.Ui.Output(formatKV(basic)) if !short { c.taskResources(alloc, stats) } // Print the state of each task. if short { c.shortTaskStatus(alloc) } else { c.taskStatus(alloc) } // Format the detailed status if verbose || alloc.DesiredStatus == "failed" { c.Ui.Output("\n==> Status") dumpAllocStatus(c.Ui, alloc, length) } return 0 }