diff --git a/client/driver/exec.go b/client/driver/exec.go index 4e02a1e51..f7869e94b 100644 --- a/client/driver/exec.go +++ b/client/driver/exec.go @@ -7,7 +7,6 @@ import ( "time" "github.com/hashicorp/nomad/client/config" - "github.com/hashicorp/nomad/client/driver/args" "github.com/hashicorp/nomad/client/executor" "github.com/hashicorp/nomad/nomad/structs" ) @@ -52,17 +51,13 @@ func (d *ExecDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle, envVars := TaskEnvironmentVariables(ctx, task) // Look for arguments - var cmdArgs []string + var args []string if argRaw, ok := task.Config["args"]; ok { - parsed, err := args.ParseAndReplace(argRaw, envVars.Map()) - if err != nil { - return nil, err - } - cmdArgs = append(cmdArgs, parsed...) + args = append(args, argRaw) } // Setup the command - cmd := executor.Command(command, cmdArgs...) + cmd := executor.Command(command, args...) if err := cmd.Limit(task.Resources); err != nil { return nil, fmt.Errorf("failed to constrain resources: %s", err) } diff --git a/client/driver/exec_test.go b/client/driver/exec_test.go index 6dba6a4c9..4a05d5891 100644 --- a/client/driver/exec_test.go +++ b/client/driver/exec_test.go @@ -1,10 +1,16 @@ package driver import ( + "fmt" + "io/ioutil" + "path/filepath" + "reflect" "testing" "time" + "github.com/hashicorp/nomad/client/allocdir" "github.com/hashicorp/nomad/client/config" + "github.com/hashicorp/nomad/client/driver/environment" "github.com/hashicorp/nomad/nomad/structs" ctestutils "github.com/hashicorp/nomad/client/testutil" @@ -115,6 +121,55 @@ func TestExecDriver_Start_Wait(t *testing.T) { } } +func TestExecDriver_Start_Wait_AllocDir(t *testing.T) { + ctestutils.ExecCompatible(t) + + exp := []byte{'w', 'i', 'n'} + file := "output.txt" + task := &structs.Task{ + Name: "sleep", + Config: map[string]string{ + "command": "/bin/bash", + "args": fmt.Sprintf("-c \"sleep 1; echo -n %s > $%s/%s\"", string(exp), environment.AllocDir, file), + }, + Resources: basicResources, + } + + driverCtx := testDriverContext(task.Name) + ctx := testDriverExecContext(task, driverCtx) + defer ctx.AllocDir.Destroy() + d := NewExecDriver(driverCtx) + + handle, err := d.Start(ctx, task) + if err != nil { + t.Fatalf("err: %v", err) + } + if handle == nil { + t.Fatalf("missing handle") + } + + // Task should terminate quickly + select { + case err := <-handle.WaitCh(): + if err != nil { + t.Fatalf("err: %v", err) + } + case <-time.After(2 * time.Second): + t.Fatalf("timeout") + } + + // Check that data was written to the shared alloc directory. + outputFile := filepath.Join(ctx.AllocDir.AllocDir, allocdir.SharedAllocName, file) + act, err := ioutil.ReadFile(outputFile) + if err != nil { + t.Fatalf("Couldn't read expected output: %v", err) + } + + if !reflect.DeepEqual(act, exp) { + t.Fatalf("Command outputted %v; want %v", act, exp) + } +} + func TestExecDriver_Start_Kill_Wait(t *testing.T) { ctestutils.ExecCompatible(t) task := &structs.Task{ diff --git a/client/driver/java.go b/client/driver/java.go index dce154a62..198410878 100644 --- a/client/driver/java.go +++ b/client/driver/java.go @@ -16,7 +16,6 @@ import ( "github.com/hashicorp/nomad/client/allocdir" "github.com/hashicorp/nomad/client/config" - "github.com/hashicorp/nomad/client/driver/args" "github.com/hashicorp/nomad/client/executor" "github.com/hashicorp/nomad/nomad/structs" ) @@ -135,18 +134,14 @@ func (d *JavaDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle, envVars := TaskEnvironmentVariables(ctx, task) // Build the argument list. - cmdArgs := []string{"-jar", filepath.Join(allocdir.TaskLocal, fName)} + args := []string{"-jar", filepath.Join(allocdir.TaskLocal, fName)} if argRaw, ok := task.Config["args"]; ok { - parsed, err := args.ParseAndReplace(argRaw, envVars.Map()) - if err != nil { - return nil, err - } - cmdArgs = append(cmdArgs, parsed...) + args = append(args, argRaw) } // Setup the command // Assumes Java is in the $PATH, but could probably be detected - cmd := executor.Command("java", cmdArgs...) + cmd := executor.Command("java", args...) // Populate environment variables cmd.Command().Env = envVars.List() diff --git a/client/executor/exec_linux.go b/client/executor/exec_linux.go index b665df234..c837b8a53 100644 --- a/client/executor/exec_linux.go +++ b/client/executor/exec_linux.go @@ -16,6 +16,7 @@ import ( "github.com/hashicorp/go-multierror" "github.com/hashicorp/nomad/client/allocdir" + "github.com/hashicorp/nomad/client/driver/args" "github.com/hashicorp/nomad/client/driver/environment" "github.com/hashicorp/nomad/command" "github.com/hashicorp/nomad/helper/discover" @@ -133,7 +134,7 @@ func (e *LinuxExecutor) ConfigureTaskDir(taskName string, alloc *allocdir.AllocD if err != nil { return err } - env.SetAllocDir(filepath.Join(taskDir, allocdir.SharedAllocName)) + env.SetAllocDir(filepath.Join("/", allocdir.SharedAllocName)) e.Cmd.Env = env.List() e.alloc = alloc @@ -247,6 +248,20 @@ func (e *LinuxExecutor) Start() error { return errors.New("ConfigureTaskDir() must be called before Start()") } + // Parse the commands arguments and replace instances of Nomad environment + // variables. + envVars, err := environment.ParseFromList(e.Cmd.Env) + if err != nil { + return err + } + + combined := strings.Join(e.Cmd.Args, " ") + parsed, err := args.ParseAndReplace(combined, envVars.Map()) + if err != nil { + return err + } + e.Cmd.Args = parsed + return e.spawnDaemon() }