cli: improve output of eval commands (#13581)
Use the same output format when listing multiple evals in the `eval list` command and when `eval status <prefix>` matches more than one eval. Include the eval namespace in all output formats and always include the job ID in `eval status` since, even `node-update` evals are related to a job. Add Node ID to the evals table output to help differentiate `node-update` evals. Co-authored-by: James Rasell <jrasell@hashicorp.com>
This commit is contained in:
parent
6a032a54d2
commit
03433dd8af
|
@ -0,0 +1,7 @@
|
||||||
|
```release-note:improvement
|
||||||
|
cli: display namespace and node ID in the `eval list` command and when `eval status` matches multiple evals
|
||||||
|
```
|
||||||
|
|
||||||
|
```release-note:improvement
|
||||||
|
cli: always display job ID and namespace in the `eval status` command
|
||||||
|
```
|
|
@ -1,10 +1,8 @@
|
||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/nomad/api"
|
|
||||||
"github.com/mitchellh/cli"
|
"github.com/mitchellh/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -46,23 +44,3 @@ func (f *EvalCommand) Synopsis() string {
|
||||||
func (f *EvalCommand) Name() string { return "eval" }
|
func (f *EvalCommand) Name() string { return "eval" }
|
||||||
|
|
||||||
func (f *EvalCommand) Run(_ []string) int { return cli.RunResultHelp }
|
func (f *EvalCommand) Run(_ []string) int { return cli.RunResultHelp }
|
||||||
|
|
||||||
// outputEvalList is a helper which outputs an array of evaluations as a list
|
|
||||||
// to the UI with key information such as ID and status.
|
|
||||||
func outputEvalList(ui cli.Ui, evals []*api.Evaluation, length int) {
|
|
||||||
|
|
||||||
out := make([]string, len(evals)+1)
|
|
||||||
out[0] = "ID|Priority|Triggered By|Job ID|Status|Placement Failures"
|
|
||||||
for i, eval := range evals {
|
|
||||||
failures, _ := evalFailureStatus(eval)
|
|
||||||
out[i+1] = fmt.Sprintf("%s|%d|%s|%s|%s|%s",
|
|
||||||
limit(eval.ID, length),
|
|
||||||
eval.Priority,
|
|
||||||
eval.TriggeredBy,
|
|
||||||
eval.JobID,
|
|
||||||
eval.Status,
|
|
||||||
failures,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
ui.Output(formatList(out))
|
|
||||||
}
|
|
||||||
|
|
|
@ -334,7 +334,7 @@ func (e *EvalDeleteCommand) batchDelete(evals []*api.Evaluation) (int, bool, err
|
||||||
// avoided when deleting large quantities of evals.
|
// avoided when deleting large quantities of evals.
|
||||||
if listEvals {
|
if listEvals {
|
||||||
e.Ui.Output("")
|
e.Ui.Output("")
|
||||||
outputEvalList(e.Ui, evals, shortId)
|
e.Ui.Output(formatEvalList(evals, false))
|
||||||
e.Ui.Output("")
|
e.Ui.Output("")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,13 +161,7 @@ func (c *EvalListCommand) Run(args []string) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Truncate the id unless full length is requested
|
c.Ui.Output(formatEvalList(evals, verbose))
|
||||||
length := shortId
|
|
||||||
if verbose {
|
|
||||||
length = fullId
|
|
||||||
}
|
|
||||||
|
|
||||||
outputEvalList(c.Ui, evals, length)
|
|
||||||
|
|
||||||
if qm.NextToken != "" {
|
if qm.NextToken != "" {
|
||||||
c.Ui.Output(fmt.Sprintf(`
|
c.Ui.Output(fmt.Sprintf(`
|
||||||
|
@ -204,3 +198,29 @@ func argsWithoutPageToken(osArgs []string) string {
|
||||||
}
|
}
|
||||||
return strings.Join(args, " ")
|
return strings.Join(args, " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func formatEvalList(evals []*api.Evaluation, verbose bool) string {
|
||||||
|
// Truncate IDs unless full length is requested
|
||||||
|
length := shortId
|
||||||
|
if verbose {
|
||||||
|
length = fullId
|
||||||
|
}
|
||||||
|
|
||||||
|
out := make([]string, len(evals)+1)
|
||||||
|
out[0] = "ID|Priority|Triggered By|Job ID|Namespace|Node ID|Status|Placement Failures"
|
||||||
|
for i, eval := range evals {
|
||||||
|
failures, _ := evalFailureStatus(eval)
|
||||||
|
out[i+1] = fmt.Sprintf("%s|%d|%s|%s|%s|%s|%s|%s",
|
||||||
|
limit(eval.ID, length),
|
||||||
|
eval.Priority,
|
||||||
|
eval.TriggeredBy,
|
||||||
|
eval.JobID,
|
||||||
|
eval.Namespace,
|
||||||
|
limit(eval.NodeID, length),
|
||||||
|
eval.Status,
|
||||||
|
failures,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return formatList(out)
|
||||||
|
}
|
||||||
|
|
|
@ -155,20 +155,7 @@ func (c *EvalStatusCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(evals) > 1 {
|
if len(evals) > 1 {
|
||||||
// Format the evals
|
c.Ui.Error(fmt.Sprintf("Prefix matched multiple evaluations\n\n%s", formatEvalList(evals, verbose)))
|
||||||
out := make([]string, len(evals)+1)
|
|
||||||
out[0] = "ID|Priority|Triggered By|Status|Placement Failures"
|
|
||||||
for i, eval := range evals {
|
|
||||||
failures, _ := evalFailureStatus(eval)
|
|
||||||
out[i+1] = fmt.Sprintf("%s|%d|%s|%s|%s",
|
|
||||||
limit(eval.ID, length),
|
|
||||||
eval.Priority,
|
|
||||||
eval.TriggeredBy,
|
|
||||||
eval.Status,
|
|
||||||
failures,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
c.Ui.Error(fmt.Sprintf("Prefix matched multiple evaluations\n\n%s", formatList(out)))
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,6 +210,8 @@ func (c *EvalStatusCommand) Run(args []string) int {
|
||||||
fmt.Sprintf("Status Description|%s", statusDesc),
|
fmt.Sprintf("Status Description|%s", statusDesc),
|
||||||
fmt.Sprintf("Type|%s", eval.Type),
|
fmt.Sprintf("Type|%s", eval.Type),
|
||||||
fmt.Sprintf("TriggeredBy|%s", eval.TriggeredBy),
|
fmt.Sprintf("TriggeredBy|%s", eval.TriggeredBy),
|
||||||
|
fmt.Sprintf("Job ID|%s", eval.JobID),
|
||||||
|
fmt.Sprintf("Namespace|%s", eval.Namespace),
|
||||||
}
|
}
|
||||||
|
|
||||||
if triggerNoun != "" && triggerSubj != "" {
|
if triggerNoun != "" && triggerSubj != "" {
|
||||||
|
@ -282,8 +271,6 @@ func sortedTaskGroupFromMetrics(groups map[string]*api.AllocationMetric) []strin
|
||||||
|
|
||||||
func getTriggerDetails(eval *api.Evaluation) (noun, subject string) {
|
func getTriggerDetails(eval *api.Evaluation) (noun, subject string) {
|
||||||
switch eval.TriggeredBy {
|
switch eval.TriggeredBy {
|
||||||
case "job-register", "job-deregister", "periodic-job", "rolling-update", "deployment-watcher":
|
|
||||||
return "Job ID", eval.JobID
|
|
||||||
case "node-update":
|
case "node-update":
|
||||||
return "Node ID", eval.NodeID
|
return "Node ID", eval.NodeID
|
||||||
case "max-plan-attempts":
|
case "max-plan-attempts":
|
||||||
|
|
|
@ -54,10 +54,10 @@ Delete all evaluations with status `pending` for the `example` job:
|
||||||
$ nomad eval delete -filter='Stauts == "pending" and JobID == "example"'
|
$ nomad eval delete -filter='Stauts == "pending" and JobID == "example"'
|
||||||
Do you want to list evals (3) before deletion? [y/N] y
|
Do you want to list evals (3) before deletion? [y/N] y
|
||||||
|
|
||||||
ID Priority Triggered By Job ID Status Placement Failures
|
ID Priority Triggered By Job ID Namespace Node ID Status Placement Failures
|
||||||
cef92121 50 job-register example pending false
|
cef92121 50 job-register example default <none> pending false
|
||||||
1c905ca0 50 job-register example pending false
|
1c905ca0 50 job-register example default <none> pending false
|
||||||
b9e77692 50 job-register example pending false
|
b9e77692 50 job-register example default <none> pending false
|
||||||
|
|
||||||
Are you sure you want to delete 3 evals? [y/N] y
|
Are you sure you want to delete 3 evals? [y/N] y
|
||||||
|
|
||||||
|
|
|
@ -41,10 +41,10 @@ List all tracked evaluations:
|
||||||
|
|
||||||
```shell-session
|
```shell-session
|
||||||
$ nomad eval list -per-page 3 -status complete
|
$ nomad eval list -per-page 3 -status complete
|
||||||
ID Priority Triggered By Job ID Status Placement Failures
|
ID Priority Triggered By Job ID Namespace Node ID Status Placement Failures
|
||||||
456e37aa 50 deployment-watcher example complete false
|
456e37aa 50 deployment-watcher example default <none> complete false
|
||||||
1a1eafe6 50 alloc-stop example complete false
|
1a1eafe6 50 alloc-stop example default <node> complete false
|
||||||
3411e37b 50 job-register example complete false
|
3411e37b 50 job-register example default <node> complete false
|
||||||
|
|
||||||
Results have been paginated. To get the next page run:
|
Results have been paginated. To get the next page run:
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,7 @@ Status Description = complete
|
||||||
Type = service
|
Type = service
|
||||||
TriggeredBy = job-register
|
TriggeredBy = job-register
|
||||||
Job ID = example
|
Job ID = example
|
||||||
|
Namespace = default
|
||||||
Priority = 50
|
Priority = 50
|
||||||
Placement Failures = true
|
Placement Failures = true
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue