diff --git a/client/driver/executor/executor.go b/client/driver/executor/executor.go index 295dc8928..9cf3ad2b5 100644 --- a/client/driver/executor/executor.go +++ b/client/driver/executor/executor.go @@ -290,14 +290,20 @@ func (e *UniversalExecutor) LaunchCmd(command *ExecCommand) (*ProcessState, erro func (e *UniversalExecutor) Exec(deadline time.Time, name string, args []string) ([]byte, int, error) { ctx, cancel := context.WithDeadline(context.Background(), deadline) defer cancel() + return ExecScript(ctx, e.cmd.Dir, e.ctx.TaskEnv, e.cmd.SysProcAttr, name, args) +} - name = e.ctx.TaskEnv.ReplaceEnv(name) - cmd := exec.CommandContext(ctx, name, e.ctx.TaskEnv.ParseAndReplace(args)...) +// ExecScript executes cmd with args and returns the output, exit code, and +// error. Output is truncated to client/driver/structs.CheckBufSize +func ExecScript(ctx context.Context, dir string, env *env.TaskEnvironment, attrs *syscall.SysProcAttr, + name string, args []string) ([]byte, int, error) { + name = env.ReplaceEnv(name) + cmd := exec.CommandContext(ctx, name, env.ParseAndReplace(args)...) // Copy runtime environment from the main command - cmd.SysProcAttr = e.cmd.SysProcAttr - cmd.Dir = e.cmd.Dir - cmd.Env = e.ctx.TaskEnv.EnvList() + cmd.SysProcAttr = attrs + cmd.Dir = dir + cmd.Env = env.EnvList() // Capture output buf, _ := circbuf.NewBuffer(int64(dstructs.CheckBufSize)) diff --git a/client/driver/raw_exec.go b/client/driver/raw_exec.go index b799a3204..558289fdd 100644 --- a/client/driver/raw_exec.go +++ b/client/driver/raw_exec.go @@ -255,7 +255,7 @@ func (h *rawExecHandle) Update(task *structs.Task) error { } func (h *rawExecHandle) Exec(ctx context.Context, cmd string, args []string) ([]byte, int, error) { - return execScript(ctx, h.taskDir.Dir, h.taskEnv, cmd, args) + return executor.ExecScript(ctx, h.taskDir.Dir, h.taskEnv, nil, cmd, args) } func (h *rawExecHandle) Signal(s os.Signal) error { diff --git a/client/driver/rkt.go b/client/driver/rkt.go index 930d66728..0c5e350ef 100644 --- a/client/driver/rkt.go +++ b/client/driver/rkt.go @@ -573,7 +573,7 @@ func (h *rktHandle) Exec(ctx context.Context, cmd string, args []string) ([]byte enterArgs[1] = h.uuid enterArgs[2] = cmd copy(enterArgs[3:], args) - return execScript(ctx, h.taskDir.Dir, h.env, rktCmd, enterArgs) + return executor.ExecScript(ctx, h.taskDir.Dir, h.env, nil, rktCmd, enterArgs) } func (h *rktHandle) Signal(s os.Signal) error { diff --git a/client/driver/rkt_test.go b/client/driver/rkt_test.go index b61ba04af..3dae05cf8 100644 --- a/client/driver/rkt_test.go +++ b/client/driver/rkt_test.go @@ -22,7 +22,7 @@ import ( func TestRktVersionRegex(t *testing.T) { if os.Getenv("NOMAD_TEST_RKT") == "" { - t.Skip("skipping rkt tests") + t.Skip("NOMAD_TEST_RKT unset, skipping") } input_rkt := "rkt version 0.8.1" diff --git a/client/driver/utils.go b/client/driver/utils.go index 07864bae4..fb61e1f6f 100644 --- a/client/driver/utils.go +++ b/client/driver/utils.go @@ -1,7 +1,6 @@ package driver import ( - "context" "encoding/json" "fmt" "io" @@ -9,14 +8,11 @@ import ( "os/exec" "path/filepath" "strings" - "syscall" "time" - "github.com/armon/circbuf" "github.com/hashicorp/go-multierror" "github.com/hashicorp/go-plugin" "github.com/hashicorp/nomad/client/config" - "github.com/hashicorp/nomad/client/driver/env" "github.com/hashicorp/nomad/client/driver/executor" cstructs "github.com/hashicorp/nomad/client/driver/structs" "github.com/hashicorp/nomad/helper/discover" @@ -182,35 +178,3 @@ func getExecutorUser(task *structs.Task) string { } return task.User } - -// execScript executes cmd with args and returns the output, exit code, and -// error. Output is truncated to client/driver/structs.CheckBufSize -func execScript(ctx context.Context, dir string, env *env.TaskEnvironment, name string, args []string) ([]byte, int, error) { - name = env.ReplaceEnv(name) - args = env.ParseAndReplace(args) - cmd := exec.CommandContext(ctx, name, args...) - cmd.Dir = dir - cmd.Env = env.EnvList() - buf, _ := circbuf.NewBuffer(int64(cstructs.CheckBufSize)) - cmd.Stdout = buf - cmd.Stderr = buf - if err := cmd.Run(); err != nil { - exitErr, ok := err.(*exec.ExitError) - if !ok { - // Non-exit error, return it and let the caller treat - // it as a critical failure - return nil, 0, err - } - - // Some kind of error happened; default to critical - exitCode := 2 - if status, ok := exitErr.Sys().(syscall.WaitStatus); ok { - exitCode = status.ExitStatus() - } - - // Don't return the exitError as the caller only needs the - // output and code. - return buf.Bytes(), exitCode, nil - } - return buf.Bytes(), 0, nil -}