ParseAndReplace args at the executor level

This commit is contained in:
Alex Dadgar 2015-09-27 12:17:51 -07:00
parent 76dfa9bb0f
commit a4a440da8e
4 changed files with 77 additions and 17 deletions

View File

@ -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)
}

View File

@ -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{

View File

@ -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()

View File

@ -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()
}