-
Notifications
You must be signed in to change notification settings - Fork 201
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add status-osh and status-omm options to maya cli (#24)
* Enhancing the CLI to get the node and job status * Adding openebs to the path * Adding glide in build script * Update vendor directory during bootstrap * updating some specific packages * ignoring some-packges * Running By Shell * Enhancing the CLI to get the node and job status * Adding openebs to the path * Adding glide in build script * Update vendor directory during bootstrap * updating some specific packages * ignoring some-packges * Running By Shell * Merging master-changes * Fixing marge conflict * Updating dep * updating gitignore * Adding Master and host status CLI commands * Updating make
- Loading branch information
1 parent
4b86f2e
commit 6fe624e
Showing
292 changed files
with
2,282 additions
and
126,306 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,3 +9,4 @@ nohup.out | |
hello.nomad | ||
clientpeers | ||
serverpeers | ||
vendor/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,6 +48,7 @@ fi | |
|
||
# Build! | ||
echo "==> Building..." | ||
#glide up | ||
gox \ | ||
-os="${XC_OS}" \ | ||
-arch="${XC_ARCH}" \ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package command | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
prateekpandey14
Author
Contributor
|
||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"text/template" | ||
) | ||
|
||
//DataFormatter is a transformer of the data. | ||
type DataFormatter interface { | ||
// TransformData should return transformed string data. | ||
TransformData(interface{}) (string, error) | ||
} | ||
|
||
// DataFormat returns the data formatter specified format. | ||
func DataFormat(format, tmpl string) (DataFormatter, error) { | ||
switch format { | ||
case "json": | ||
if len(tmpl) > 0 { | ||
return nil, fmt.Errorf("json format does not support template option.") | ||
} | ||
return &JSONFormat{}, nil | ||
case "template": | ||
return &TemplateFormat{tmpl}, nil | ||
} | ||
return nil, fmt.Errorf("Unsupported format is specified.") | ||
} | ||
|
||
type JSONFormat struct { | ||
} | ||
|
||
// TransformData returns JSON format string data. | ||
func (p *JSONFormat) TransformData(data interface{}) (string, error) { | ||
out, err := json.MarshalIndent(&data, "", " ") | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
return string(out), nil | ||
} | ||
|
||
type TemplateFormat struct { | ||
tmpl string | ||
} | ||
|
||
// TransformData returns template format string data. | ||
func (p *TemplateFormat) TransformData(data interface{}) (string, error) { | ||
var out io.Writer = new(bytes.Buffer) | ||
if len(p.tmpl) == 0 { | ||
return "", fmt.Errorf("template needs to be specified the golang templates.") | ||
} | ||
|
||
t, err := template.New("format").Parse(p.tmpl) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
err = t.Execute(out, data) | ||
if err != nil { | ||
return "", err | ||
} | ||
return fmt.Sprint(out), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,272 @@ | ||
package command | ||
|
||
import ( | ||
"fmt" | ||
"sort" | ||
"strings" | ||
|
||
"github.com/hashicorp/nomad/api" | ||
) | ||
|
||
type EvalStatusCommand struct { | ||
Meta | ||
} | ||
|
||
func (c *EvalStatusCommand) Help() string { | ||
helpText := ` | ||
Usage: nomad eval-status [options] <evaluation-id> | ||
This comment has been minimized.
Sorry, something went wrong.
AmitKumarDas
|
||
Display information about evaluations. This command can be used to inspect the | ||
current status of an evaluation as well as determine the reason an evaluation | ||
did not place all allocations. | ||
General Options: | ||
` + generalOptionsUsage() + ` | ||
Eval Status Options: | ||
-monitor | ||
Monitor an outstanding evaluation | ||
-verbose | ||
Show full information. | ||
-json | ||
Output the evaluation in its JSON format. | ||
-t | ||
Format and display evaluation using a Go template. | ||
` | ||
|
||
return strings.TrimSpace(helpText) | ||
} | ||
|
||
func (c *EvalStatusCommand) Synopsis() string { | ||
return "Display evaluation status and placement failure reasons" | ||
} | ||
|
||
func (c *EvalStatusCommand) Run(args []string) int { | ||
var monitor, verbose, json bool | ||
var tmpl string | ||
|
||
flags := c.Meta.FlagSet("eval-status", FlagSetClient) | ||
flags.Usage = func() { c.Ui.Output(c.Help()) } | ||
flags.BoolVar(&monitor, "monitor", false, "") | ||
flags.BoolVar(&verbose, "verbose", 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 evaluation ID | ||
This comment has been minimized.
Sorry, something went wrong.
AmitKumarDas
|
||
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 evaluations 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 { | ||
evals, _, err := client.Evaluations().List(nil) | ||
if err != nil { | ||
c.Ui.Error(fmt.Sprintf("Error querying evaluations: %v", err)) | ||
return 1 | ||
} | ||
// Return nothing if no evaluations found | ||
if len(evals) == 0 { | ||
This comment has been minimized.
Sorry, something went wrong. |
||
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(evals) | ||
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 | ||
} | ||
|
||
evalID := args[0] | ||
|
||
// Truncate the id unless full length is requested | ||
length := shortId | ||
if verbose { | ||
length = fullId | ||
} | ||
|
||
// Query the allocation info | ||
if len(evalID) == 1 { | ||
c.Ui.Error(fmt.Sprintf("Identifier must contain at least two characters.")) | ||
return 1 | ||
} | ||
if len(evalID)%2 == 1 { | ||
// Identifiers must be of even length, so we strip off the last byte | ||
// to provide a consistent user experience. | ||
evalID = evalID[:len(evalID)-1] | ||
} | ||
|
||
evals, _, err := client.Evaluations().PrefixList(evalID) | ||
if err != nil { | ||
c.Ui.Error(fmt.Sprintf("Error querying evaluation: %v", err)) | ||
return 1 | ||
} | ||
if len(evals) == 0 { | ||
c.Ui.Error(fmt.Sprintf("No evaluation(s) with prefix or id %q found", evalID)) | ||
return 1 | ||
} | ||
|
||
if len(evals) > 1 { | ||
// Format the evals | ||
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.Output(fmt.Sprintf("Prefix matched multiple evaluations\n\n%s", formatList(out))) | ||
return 0 | ||
} | ||
|
||
// If we are in monitor mode, monitor and exit | ||
if monitor { | ||
mon := newMonitor(c.Ui, client, length) | ||
return mon.monitor(evals[0].ID, true) | ||
} | ||
|
||
// Prefix lookup matched a single evaluation | ||
eval, _, err := client.Evaluations().Info(evals[0].ID, nil) | ||
if err != nil { | ||
c.Ui.Error(fmt.Sprintf("Error querying evaluation: %s", err)) | ||
return 1 | ||
} | ||
|
||
// If output format is specified, format and output the data | ||
var format string | ||
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(eval) | ||
if err != nil { | ||
c.Ui.Error(fmt.Sprintf("Error formatting the data: %s", err)) | ||
return 1 | ||
} | ||
c.Ui.Output(out) | ||
return 0 | ||
} | ||
|
||
failureString, failures := evalFailureStatus(eval) | ||
triggerNoun, triggerSubj := getTriggerDetails(eval) | ||
statusDesc := eval.StatusDescription | ||
if statusDesc == "" { | ||
statusDesc = eval.Status | ||
} | ||
|
||
// Format the evaluation data | ||
basic := []string{ | ||
fmt.Sprintf("ID|%s", limit(eval.ID, length)), | ||
fmt.Sprintf("Status|%s", eval.Status), | ||
fmt.Sprintf("Status Description|%s", statusDesc), | ||
fmt.Sprintf("Type|%s", eval.Type), | ||
fmt.Sprintf("TriggeredBy|%s", eval.TriggeredBy), | ||
fmt.Sprintf("%s|%s", triggerNoun, triggerSubj), | ||
fmt.Sprintf("Priority|%d", eval.Priority), | ||
fmt.Sprintf("Placement Failures|%s", failureString), | ||
} | ||
|
||
if verbose { | ||
// NextEval, PreviousEval, BlockedEval | ||
basic = append(basic, | ||
fmt.Sprintf("Previous Eval|%s", eval.PreviousEval), | ||
fmt.Sprintf("Next Eval|%s", eval.NextEval), | ||
fmt.Sprintf("Blocked Eval|%s", eval.BlockedEval)) | ||
} | ||
c.Ui.Output(formatKV(basic)) | ||
|
||
if failures { | ||
c.Ui.Output(c.Colorize().Color("\n[bold]Failed Placements[reset]")) | ||
sorted := sortedTaskGroupFromMetrics(eval.FailedTGAllocs) | ||
for _, tg := range sorted { | ||
metrics := eval.FailedTGAllocs[tg] | ||
|
||
noun := "allocation" | ||
if metrics.CoalescedFailures > 0 { | ||
noun += "s" | ||
} | ||
c.Ui.Output(fmt.Sprintf("Task Group %q (failed to place %d %s):", tg, metrics.CoalescedFailures+1, noun)) | ||
c.Ui.Output(formatAllocMetrics(metrics, false, " ")) | ||
c.Ui.Output("") | ||
} | ||
|
||
if eval.BlockedEval != "" { | ||
c.Ui.Output(fmt.Sprintf("Evaluation %q waiting for additional capacity to place remainder", | ||
limit(eval.BlockedEval, length))) | ||
} | ||
} | ||
|
||
return 0 | ||
} | ||
|
||
func sortedTaskGroupFromMetrics(groups map[string]*api.AllocationMetric) []string { | ||
tgs := make([]string, 0, len(groups)) | ||
for tg, _ := range groups { | ||
tgs = append(tgs, tg) | ||
} | ||
sort.Strings(tgs) | ||
return tgs | ||
} | ||
|
||
func getTriggerDetails(eval *api.Evaluation) (noun, subject string) { | ||
switch eval.TriggeredBy { | ||
case "job-register", "job-deregister", "periodic-job", "rolling-update": | ||
return "Job ID", eval.JobID | ||
case "node-update": | ||
return "Node ID", eval.NodeID | ||
case "max-plan-attempts": | ||
return "Previous Eval", eval.PreviousEval | ||
default: | ||
return "", "" | ||
} | ||
} |
Oops, something went wrong.
Did we try to use the original .go file by using go
import
?Do we need to duplicate this file ?
Is there anything that is Maya specific ?