Support nomad plan to take jobfile from stdin
This commit is contained in:
parent
00721861b0
commit
64db388af2
|
@ -2,6 +2,8 @@ package command
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -26,6 +28,9 @@ potentially invalid.`
|
|||
type PlanCommand struct {
|
||||
Meta
|
||||
color *colorstring.Colorize
|
||||
|
||||
// The fields below can be overwritten for tests
|
||||
testStdin io.Reader
|
||||
}
|
||||
|
||||
func (c *PlanCommand) Help() string {
|
||||
|
@ -37,6 +42,9 @@ Usage: nomad plan [options] <file>
|
|||
changes to the cluster but gives insight into whether the job could be run
|
||||
successfully and how it would affect existing allocations.
|
||||
|
||||
If the supplied path is "-", the jobfile is read from stdin. Otherwise
|
||||
it is read from the file at the supplied path.
|
||||
|
||||
A job modify index is returned with the plan. This value can be used when
|
||||
submitting the job using "nomad run -check-index", which will check that the job
|
||||
was not modified between the plan and run command before invoking the
|
||||
|
@ -86,12 +94,33 @@ func (c *PlanCommand) Run(args []string) int {
|
|||
c.Ui.Error(c.Help())
|
||||
return 1
|
||||
}
|
||||
file := args[0]
|
||||
|
||||
// Parse the job file
|
||||
job, err := jobspec.ParseFile(file)
|
||||
// Read the Jobfile
|
||||
path := args[0]
|
||||
|
||||
var f io.Reader
|
||||
switch path {
|
||||
case "-":
|
||||
if c.testStdin != nil {
|
||||
f = c.testStdin
|
||||
} else {
|
||||
f = os.Stdin
|
||||
}
|
||||
path = "stdin"
|
||||
default:
|
||||
file, err := os.Open(path)
|
||||
defer file.Close()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error opening file %q: %v", path, err))
|
||||
return 1
|
||||
}
|
||||
f = file
|
||||
}
|
||||
|
||||
// Parse the JobFile
|
||||
job, err := jobspec.Parse(f)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error parsing job file %s: %s", file, err))
|
||||
c.Ui.Error(fmt.Sprintf("Error parsing job file %s: %v", path, err))
|
||||
return 1
|
||||
}
|
||||
|
||||
|
@ -142,7 +171,7 @@ func (c *PlanCommand) Run(args []string) int {
|
|||
c.Ui.Output("")
|
||||
|
||||
// Print the job index info
|
||||
c.Ui.Output(c.Colorize().Color(formatJobModifyIndex(resp.JobModifyIndex, file)))
|
||||
c.Ui.Output(c.Colorize().Color(formatJobModifyIndex(resp.JobModifyIndex, path)))
|
||||
return 0
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ func TestPlanCommand_Fails(t *testing.T) {
|
|||
if code := cmd.Run([]string{"/unicorns/leprechauns"}); code != 1 {
|
||||
t.Fatalf("expect exit 1, got: %d", code)
|
||||
}
|
||||
if out := ui.ErrorWriter.String(); !strings.Contains(out, "Error parsing") {
|
||||
if out := ui.ErrorWriter.String(); !strings.Contains(out, "Error opening") {
|
||||
t.Fatalf("expect parsing error, got: %s", out)
|
||||
}
|
||||
ui.ErrorWriter.Reset()
|
||||
|
@ -101,3 +101,46 @@ job "job1" {
|
|||
t.Fatalf("expected failed query error, got: %s", out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlanCommand_From_STDIN(t *testing.T) {
|
||||
stdinR, stdinW, err := os.Pipe()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
cmd := &PlanCommand{
|
||||
Meta: Meta{Ui: ui},
|
||||
testStdin: stdinR,
|
||||
}
|
||||
|
||||
go func() {
|
||||
stdinW.WriteString(`
|
||||
job "job1" {
|
||||
type = "service"
|
||||
datacenters = [ "dc1" ]
|
||||
group "group1" {
|
||||
count = 1
|
||||
task "task1" {
|
||||
driver = "exec"
|
||||
resources = {
|
||||
cpu = 1000
|
||||
disk = 150
|
||||
memory = 512
|
||||
}
|
||||
}
|
||||
}
|
||||
}`)
|
||||
stdinW.Close()
|
||||
}()
|
||||
|
||||
args := []string{"-"}
|
||||
if code := cmd.Run(args); code != 1 {
|
||||
t.Fatalf("expected exit code 1, got %d: %q", code, ui.ErrorWriter.String())
|
||||
}
|
||||
|
||||
if out := ui.ErrorWriter.String(); !strings.Contains(out, "connection refused") {
|
||||
t.Fatalf("expected runtime error, got: %s", out)
|
||||
}
|
||||
ui.ErrorWriter.Reset()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue