Skip to content

Commit

Permalink
update raw_exec to support artifact_source
Browse files Browse the repository at this point in the history
  • Loading branch information
catsby committed Oct 19, 2015
1 parent 3fe532e commit ebc9ef6
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 8 deletions.
2 changes: 1 addition & 1 deletion client/driver/exec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func TestExecDriver_Start_Wait(t *testing.T) {
}
}

func TestExecDriver_Start_Artifact_Wait(t *testing.T) {
func TestRawExecDriver_Start_Artifact_Wait(t *testing.T) {
ctestutils.ExecCompatible(t)
task := &structs.Task{
Name: "sleep",
Expand Down
38 changes: 32 additions & 6 deletions client/driver/raw_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ package driver

import (
"fmt"
"log"
"os"
"os/exec"
"path"
"path/filepath"
"runtime"
"strconv"
"strings"
"time"

"github.com/hashicorp/go-getter"
"github.com/hashicorp/nomad/client/allocdir"
"github.com/hashicorp/nomad/client/config"
"github.com/hashicorp/nomad/client/driver/args"
Expand Down Expand Up @@ -61,12 +64,6 @@ func (d *RawExecDriver) Fingerprint(cfg *config.Config, node *structs.Node) (boo
}

func (d *RawExecDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle, error) {
// Get the command
command, ok := task.Config["command"]
if !ok || command == "" {
return nil, fmt.Errorf("missing command for raw_exec driver")
}

// Get the tasks local directory.
taskName := d.DriverContext.taskName
taskDir, ok := ctx.AllocDir.TaskDirs[taskName]
Expand All @@ -75,6 +72,35 @@ func (d *RawExecDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandl
}
taskLocal := filepath.Join(taskDir, allocdir.TaskLocal)

// Get the command
command, ok := task.Config["command"]
if !ok || command == "" {
source, sok := task.Config["artifact_source"]
if !sok || source == "" {
return nil, fmt.Errorf("missing command or source for exec driver")
}

// Proceed to download an artifact to be executed.
// We use go-getter to support a variety of protocols, but need to change
// file permissions of the resulted download to be executable
destDir := filepath.Join(taskDir, allocdir.TaskLocal)

// Create a location to download the artifact.
artifactName := path.Base(source)
command = filepath.Join(destDir, artifactName)
if err := getter.GetFile(command, source); err != nil {
return nil, fmt.Errorf("[Err] driver.Exec: Error downloading source for Exec driver: %s", err)
}

cmd := exec.Command("chmod", "+x", command)
if err := cmd.Run(); err != nil {
log.Printf("[Err] driver.Exec: Error making artifact executable: %s", err)
}

// re-assign the command to be the local execution path
command = filepath.Join(allocdir.TaskLocal, artifactName)
}

// Get the environment variables.
envVars := TaskEnvironmentVariables(ctx, task)

Expand Down
44 changes: 44 additions & 0 deletions client/driver/raw_exec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,50 @@ func TestRawExecDriver_StartOpen_Wait(t *testing.T) {
}
}

func TestRawExecDriver_StartOpen_Artifact_Source_Wait(t *testing.T) {
task := &structs.Task{
Name: "sleep",
Config: map[string]string{
"artifact_source": "https://dl.dropboxusercontent.com/u/47675/jar_thing/hi_linux_amd64",
},
}
driverCtx := testDriverContext(task.Name)
ctx := testDriverExecContext(task, driverCtx)
defer ctx.AllocDir.Destroy()

d := NewRawExecDriver(driverCtx)
handle, err := d.Start(ctx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}

// Attempt to open
handle2, err := d.Open(ctx, handle.ID())
if err != nil {
t.Fatalf("err: %v", err)
}
if handle2 == nil {
t.Fatalf("missing handle")
}

// Task should terminate quickly
select {
case <-handle2.WaitCh():
case <-time.After(2 * time.Second):
t.Fatalf("timeout")
}

// Check they are both tracking the same PID.
pid1 := handle.(*rawExecHandle).proc.Pid
pid2 := handle2.(*rawExecHandle).proc.Pid
if pid1 != pid2 {
t.Fatalf("tracking incorrect Pid; %v != %v", pid1, pid2)
}
}

func TestRawExecDriver_Start_Wait(t *testing.T) {
task := &structs.Task{
Name: "sleep",
Expand Down
6 changes: 5 additions & 1 deletion website/source/docs/drivers/raw_exec.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ As such, it should be used with extreme care and is disabled by default.
The `raw_exec` driver supports the following configuration in the job spec:

* `command` - The command to execute. Must be provided.

* `artifact_source` – Source location of an executable artifact. Must be accessible
from the Nomad client
* `args` - The argument list to the command, space seperated. Optional.

## Client Requirements
Expand All @@ -35,6 +36,9 @@ options = {
}
```

You must specify either a `command` or a `artifact_source` to be executed. Any
`command` is assumed to be present on the running client.

## Client Attributes

The `raw_exec` driver will set the following client attributes:
Expand Down

0 comments on commit ebc9ef6

Please sign in to comment.