mirror of
https://github.com/kemko/nomad.git
synced 2026-01-05 09:55:44 +03:00
add time flag to add created column to allocation
This commit is contained in:
@@ -23,6 +23,7 @@ type StatusCommand struct {
|
||||
length int
|
||||
evals bool
|
||||
verbose bool
|
||||
time bool
|
||||
}
|
||||
|
||||
func (c *StatusCommand) Help() string {
|
||||
@@ -45,6 +46,9 @@ Status Options:
|
||||
-evals
|
||||
Display the evaluations associated with the job.
|
||||
|
||||
-time
|
||||
Display allocation creation time.
|
||||
|
||||
-verbose
|
||||
Display full information.
|
||||
`
|
||||
@@ -63,6 +67,7 @@ func (c *StatusCommand) Run(args []string) int {
|
||||
flags.BoolVar(&short, "short", false, "")
|
||||
flags.BoolVar(&c.evals, "evals", false, "")
|
||||
flags.BoolVar(&c.verbose, "verbose", false, "")
|
||||
flags.BoolVar(&c.time, "time", false, "")
|
||||
|
||||
if err := flags.Parse(args); err != nil {
|
||||
return 1
|
||||
@@ -302,6 +307,9 @@ func (c *StatusCommand) outputJobInfo(client *api.Client, job *api.Job) error {
|
||||
if len(jobAllocs) > 0 {
|
||||
allocs = make([]string, len(jobAllocs)+1)
|
||||
allocs[0] = "ID|Eval ID|Node ID|Task Group|Desired|Status"
|
||||
if c.time {
|
||||
allocs[0] += "|Created"
|
||||
}
|
||||
for i, alloc := range jobAllocs {
|
||||
allocs[i+1] = fmt.Sprintf("%s|%s|%s|%s|%s|%s",
|
||||
limit(alloc.ID, c.length),
|
||||
@@ -310,6 +318,10 @@ func (c *StatusCommand) outputJobInfo(client *api.Client, job *api.Job) error {
|
||||
alloc.TaskGroup,
|
||||
alloc.DesiredStatus,
|
||||
alloc.ClientStatus)
|
||||
if c.time {
|
||||
allocs[i+1] += fmt.Sprintf("|%s",
|
||||
c.formatUnixNanoTime(alloc.CreateTime))
|
||||
}
|
||||
}
|
||||
|
||||
c.Ui.Output(formatList(allocs))
|
||||
@@ -346,6 +358,12 @@ func (c *StatusCommand) outputFailedPlacements(failedEval *api.Evaluation) {
|
||||
}
|
||||
}
|
||||
|
||||
// formatUnixNanoTime is a helper for formatting time for output.
|
||||
func (c *StatusCommand) formatUnixNanoTime(nano int64) string {
|
||||
t := time.Unix(0, nano)
|
||||
return formatTime(t)
|
||||
}
|
||||
|
||||
// convertApiJob is used to take a *api.Job and convert it to an *struct.Job.
|
||||
// This function is just a hammer and probably needs to be revisited.
|
||||
func convertApiJob(in *api.Job) (*structs.Job, error) {
|
||||
@@ -363,7 +381,7 @@ func convertApiJob(in *api.Job) (*structs.Job, error) {
|
||||
}
|
||||
|
||||
// list general information about a list of jobs
|
||||
func createStatusListOutput(jobs []*structs.JobListStub) ([]string) {
|
||||
func createStatusListOutput(jobs []*api.JobListStub) string {
|
||||
out := make([]string, len(jobs)+1)
|
||||
out[0] = "ID|Type|Priority|Status"
|
||||
for i, job := range jobs {
|
||||
@@ -374,4 +392,4 @@ func createStatusListOutput(jobs []*structs.JobListStub) ([]string) {
|
||||
job.Status)
|
||||
}
|
||||
return formatList(out)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/hashicorp/nomad/testutil"
|
||||
"github.com/hashicorp/nomad/api"
|
||||
)
|
||||
|
||||
func TestStatusCommand_Implements(t *testing.T) {
|
||||
@@ -12,7 +14,9 @@ func TestStatusCommand_Implements(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStatusCommand_Run(t *testing.T) {
|
||||
srv, client, url := testServer(t, nil)
|
||||
srv, client, url := testServer(t, func(c *testutil.TestServerConfig) {
|
||||
c.DevMode = true
|
||||
})
|
||||
defer srv.Stop()
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
@@ -33,14 +37,22 @@ func TestStatusCommand_Run(t *testing.T) {
|
||||
|
||||
// Register two jobs
|
||||
job1 := testJob("job1_sfx")
|
||||
evalId, _, err := client.Jobs().Register(job1, nil)
|
||||
evalId1, _, err := client.Jobs().Register(job1, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if code := waitForSuccess(ui, client, fullId, t, evalId1); code != 0 {
|
||||
t.Fatalf("status code non zero saw %d", code)
|
||||
}
|
||||
|
||||
job2 := testJob("job2_sfx")
|
||||
if _, _, err := client.Jobs().Register(job2, nil); err != nil {
|
||||
evalId2, _, err := client.Jobs().Register(job2, nil);
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if code := waitForSuccess(ui, client, fullId, t, evalId2); code != 0 {
|
||||
t.Fatalf("status code non zero saw %d", code)
|
||||
}
|
||||
|
||||
// Query again and check the result
|
||||
if code := cmd.Run([]string{"-address=" + url}); code != 0 {
|
||||
@@ -98,6 +110,25 @@ func TestStatusCommand_Run(t *testing.T) {
|
||||
if !strings.Contains(out, "Allocations") {
|
||||
t.Fatalf("should dump allocations")
|
||||
}
|
||||
if strings.Contains(out, "Created") {
|
||||
t.Fatal("should not have created header")
|
||||
}
|
||||
ui.OutputWriter.Reset()
|
||||
|
||||
// Query a single job in time mode
|
||||
if code := cmd.Run([]string{"-address=" + url, "-time", "job1_sfx"}); code != 0 {
|
||||
t.Fatalf("expected exit 0, got: %d", code)
|
||||
}
|
||||
out = ui.OutputWriter.String()
|
||||
if strings.Contains(out, "job2_sfx") || !strings.Contains(out, "job1_sfx") {
|
||||
t.Fatalf("expected only job1_sfx, got: %s", out)
|
||||
}
|
||||
if !strings.Contains(out, "Allocations") {
|
||||
t.Fatal("should dump allocations")
|
||||
}
|
||||
if !strings.Contains(out, "Created") {
|
||||
t.Fatal("should have created header")
|
||||
}
|
||||
ui.OutputWriter.Reset()
|
||||
|
||||
// Query jobs with prefix match
|
||||
@@ -134,7 +165,7 @@ func TestStatusCommand_Run(t *testing.T) {
|
||||
if strings.Contains(out, "Allocations") {
|
||||
t.Fatalf("should not dump allocations")
|
||||
}
|
||||
if strings.Contains(out, evalId) {
|
||||
if strings.Contains(out, evalId1) {
|
||||
t.Fatalf("should not contain full identifiers, got %s", out)
|
||||
}
|
||||
ui.OutputWriter.Reset()
|
||||
@@ -144,7 +175,7 @@ func TestStatusCommand_Run(t *testing.T) {
|
||||
t.Fatalf("expected exit 0, got: %d", code)
|
||||
}
|
||||
out = ui.OutputWriter.String()
|
||||
if !strings.Contains(out, evalId) {
|
||||
if !strings.Contains(out, evalId1) {
|
||||
t.Fatalf("should contain full identifiers, got %s", out)
|
||||
}
|
||||
}
|
||||
@@ -170,3 +201,9 @@ func TestStatusCommand_Fails(t *testing.T) {
|
||||
t.Fatalf("expected failed query error, got: %s", out)
|
||||
}
|
||||
}
|
||||
|
||||
func waitForSuccess(ui cli.Ui, client *api.Client, length int, t *testing.T, evalId string) int {
|
||||
mon := newMonitor(ui, client, length)
|
||||
monErr := mon.monitor(evalId, false)
|
||||
return monErr
|
||||
}
|
||||
@@ -39,7 +39,7 @@ func testServer(
|
||||
}
|
||||
|
||||
func testJob(jobID string) *api.Job {
|
||||
task := api.NewTask("task1", "exec").
|
||||
task := api.NewTask("task1", "raw_exec").
|
||||
SetConfig("command", "/bin/sleep").
|
||||
Require(&api.Resources{
|
||||
MemoryMB: 256,
|
||||
|
||||
@@ -94,11 +94,13 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory {
|
||||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
|
||||
"plan": func() (cli.Command, error) {
|
||||
return &command.PlanCommand{
|
||||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
|
||||
"run": func() (cli.Command, error) {
|
||||
return &command.RunCommand{
|
||||
Meta: meta,
|
||||
|
||||
Reference in New Issue
Block a user