Merge pull request #381 from hashicorp/f-getter-refactor

client/drivers: Refactor to use Getter wrapper
This commit is contained in:
Clint 2015-11-05 13:47:42 -06:00
commit e494a24335
14 changed files with 260 additions and 113 deletions

View File

@ -2,17 +2,15 @@ package driver
import ( import (
"fmt" "fmt"
"log"
"path"
"path/filepath" "path/filepath"
"runtime" "runtime"
"syscall" "syscall"
"time" "time"
"github.com/hashicorp/go-getter"
"github.com/hashicorp/nomad/client/allocdir" "github.com/hashicorp/nomad/client/allocdir"
"github.com/hashicorp/nomad/client/config" "github.com/hashicorp/nomad/client/config"
"github.com/hashicorp/nomad/client/driver/executor" "github.com/hashicorp/nomad/client/driver/executor"
"github.com/hashicorp/nomad/client/getter"
"github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/nomad/structs"
) )
@ -55,29 +53,24 @@ func (d *ExecDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle,
return nil, fmt.Errorf("missing command for exec driver") return nil, fmt.Errorf("missing command for exec driver")
} }
// Check if an artificat is specified and attempt to download it
source, ok := task.Config["artifact_source"]
if ok && source != "" {
// 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
// Create a location to download the artifact. // Create a location to download the artifact.
taskDir, ok := ctx.AllocDir.TaskDirs[d.DriverContext.taskName] taskDir, ok := ctx.AllocDir.TaskDirs[d.DriverContext.taskName]
if !ok { if !ok {
return nil, fmt.Errorf("Could not find task directory for task: %v", d.DriverContext.taskName) return nil, fmt.Errorf("Could not find task directory for task: %v", d.DriverContext.taskName)
} }
destDir := filepath.Join(taskDir, allocdir.TaskLocal)
artifactName := path.Base(source) // Check if an artificat is specified and attempt to download it
artifactFile := filepath.Join(destDir, artifactName) source, ok := task.Config["artifact_source"]
if err := getter.GetFile(artifactFile, source); err != nil { if ok && source != "" {
return nil, fmt.Errorf("Error downloading artifact for Exec driver: %s", err) // Proceed to download an artifact to be executed.
} _, err := getter.GetArtifact(
filepath.Join(taskDir, allocdir.TaskLocal),
// Add execution permissions to the newly downloaded artifact task.Config["artifact_source"],
if err := syscall.Chmod(artifactFile, 0755); err != nil { task.Config["checksum"],
log.Printf("[ERR] driver.exec: Error making artifact executable: %s", err) d.logger,
)
if err != nil {
return nil, err
} }
} }

View File

@ -123,11 +123,12 @@ func TestExecDriver_Start_Wait(t *testing.T) {
func TestExecDriver_Start_Artifact_basic(t *testing.T) { func TestExecDriver_Start_Artifact_basic(t *testing.T) {
ctestutils.ExecCompatible(t) ctestutils.ExecCompatible(t)
file := "hi_linux_amd64" file := "hi_linux_amd64"
checksum := "sha256:6f99b4c5184726e601ecb062500aeb9537862434dfe1898dbe5c68d9f50c179c"
task := &structs.Task{ task := &structs.Task{
Name: "sleep", Name: "sleep",
Config: map[string]string{ Config: map[string]string{
"artifact_source": fmt.Sprintf("https://dl.dropboxusercontent.com/u/47675/jar_thing/%s", file), "artifact_source": fmt.Sprintf("https://dl.dropboxusercontent.com/u/47675/jar_thing/%s?checksum=%s", file, checksum),
"command": filepath.Join("$NOMAD_TASK_DIR", file), "command": filepath.Join("$NOMAD_TASK_DIR", file),
}, },
Resources: basicResources, Resources: basicResources,

View File

@ -4,17 +4,16 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"os/exec" "os/exec"
"path"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strings" "strings"
"syscall" "syscall"
"time" "time"
"github.com/hashicorp/go-getter"
"github.com/hashicorp/nomad/client/allocdir" "github.com/hashicorp/nomad/client/allocdir"
"github.com/hashicorp/nomad/client/config" "github.com/hashicorp/nomad/client/config"
"github.com/hashicorp/nomad/client/driver/executor" "github.com/hashicorp/nomad/client/driver/executor"
"github.com/hashicorp/nomad/client/getter"
"github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/nomad/structs"
) )
@ -89,26 +88,24 @@ func (d *JavaDriver) Fingerprint(cfg *config.Config, node *structs.Node) (bool,
} }
func (d *JavaDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle, error) { func (d *JavaDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle, error) {
// Get the jar source
source, ok := task.Config["jar_source"]
if !ok || source == "" {
return nil, fmt.Errorf("missing jar source for Java Jar driver")
}
taskDir, ok := ctx.AllocDir.TaskDirs[d.DriverContext.taskName] taskDir, ok := ctx.AllocDir.TaskDirs[d.DriverContext.taskName]
if !ok { if !ok {
return nil, fmt.Errorf("Could not find task directory for task: %v", d.DriverContext.taskName) return nil, fmt.Errorf("Could not find task directory for task: %v", d.DriverContext.taskName)
} }
destDir := filepath.Join(taskDir, allocdir.TaskLocal) // Proceed to download an artifact to be executed.
path, err := getter.GetArtifact(
// Create a location to download the binary. filepath.Join(taskDir, allocdir.TaskLocal),
jarName := path.Base(source) task.Config["artifact_source"],
jarPath := filepath.Join(destDir, jarName) task.Config["checksum"],
if err := getter.GetFile(jarPath, source); err != nil { d.logger,
return nil, fmt.Errorf("Error downloading source for Java driver: %s", err) )
if err != nil {
return nil, err
} }
jarName := filepath.Base(path)
// Get the environment variables. // Get the environment variables.
envVars := TaskEnvironmentVariables(ctx, task) envVars := TaskEnvironmentVariables(ctx, task)

View File

@ -97,10 +97,9 @@ func TestJavaDriver_Start_Wait(t *testing.T) {
task := &structs.Task{ task := &structs.Task{
Name: "demo-app", Name: "demo-app",
Config: map[string]string{ Config: map[string]string{
"jar_source": "https://dl.dropboxusercontent.com/u/47675/jar_thing/demoapp.jar", "artifact_source": "https://dl.dropboxusercontent.com/u/47675/jar_thing/demoapp.jar",
// "jar_source": "https://s3-us-west-2.amazonaws.com/java-jar-thing/demoapp.jar",
// "args": "-d64",
"jvm_options": "-Xmx2048m -Xms256m", "jvm_options": "-Xmx2048m -Xms256m",
"checksum": "sha256:58d6e8130308d32e197c5108edd4f56ddf1417408f743097c2e662df0f0b17c8",
}, },
Resources: basicResources, Resources: basicResources,
} }
@ -145,9 +144,7 @@ func TestJavaDriver_Start_Kill_Wait(t *testing.T) {
task := &structs.Task{ task := &structs.Task{
Name: "demo-app", Name: "demo-app",
Config: map[string]string{ Config: map[string]string{
"jar_source": "https://dl.dropboxusercontent.com/u/47675/jar_thing/demoapp.jar", "artifact_source": "https://dl.dropboxusercontent.com/u/47675/jar_thing/demoapp.jar",
// "jar_source": "https://s3-us-west-2.amazonaws.com/java-jar-thing/demoapp.jar",
// "args": "-d64",
}, },
Resources: basicResources, Resources: basicResources,
} }

View File

@ -2,11 +2,8 @@ package driver
import ( import (
"bytes" "bytes"
"crypto/sha256"
"encoding/hex"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"log" "log"
"os" "os"
"os/exec" "os/exec"
@ -17,9 +14,9 @@ import (
"strings" "strings"
"time" "time"
"github.com/hashicorp/go-getter"
"github.com/hashicorp/nomad/client/allocdir" "github.com/hashicorp/nomad/client/allocdir"
"github.com/hashicorp/nomad/client/config" "github.com/hashicorp/nomad/client/config"
"github.com/hashicorp/nomad/client/getter"
"github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/nomad/structs"
) )
@ -82,7 +79,7 @@ func (d *QemuDriver) Fingerprint(cfg *config.Config, node *structs.Node) (bool,
// image and save it to the Drivers Allocation Dir // image and save it to the Drivers Allocation Dir
func (d *QemuDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle, error) { func (d *QemuDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle, error) {
// Get the image source // Get the image source
source, ok := task.Config["image_source"] source, ok := task.Config["artifact_source"]
if !ok || source == "" { if !ok || source == "" {
return nil, fmt.Errorf("Missing source image Qemu driver") return nil, fmt.Errorf("Missing source image Qemu driver")
} }
@ -99,34 +96,18 @@ func (d *QemuDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle,
return nil, fmt.Errorf("Could not find task directory for task: %v", d.DriverContext.taskName) return nil, fmt.Errorf("Could not find task directory for task: %v", d.DriverContext.taskName)
} }
// Create a location to download the binary. // Proceed to download an artifact to be executed.
destDir := filepath.Join(taskDir, allocdir.TaskLocal) vmPath, err := getter.GetArtifact(
vmID := fmt.Sprintf("qemu-vm-%s-%s", structs.GenerateUUID(), filepath.Base(source)) filepath.Join(taskDir, allocdir.TaskLocal),
vmPath := filepath.Join(destDir, vmID) task.Config["artifact_source"],
if err := getter.GetFile(vmPath, source); err != nil { task.Config["checksum"],
return nil, fmt.Errorf("Error downloading artifact for Qemu driver: %s", err) d.logger,
} )
// compute and check checksum
if check, ok := task.Config["checksum"]; ok {
d.logger.Printf("[DEBUG] Running checksum on (%s)", vmID)
hasher := sha256.New()
file, err := os.Open(vmPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("Failed to open file for checksum") return nil, err
} }
defer file.Close() vmID := filepath.Base(vmPath)
io.Copy(hasher, file)
sum := hex.EncodeToString(hasher.Sum(nil))
if sum != check {
return nil, fmt.Errorf(
"Error in Qemu: checksums did not match.\nExpected (%s), got (%s)",
check,
sum)
}
}
// Parse configuration arguments // Parse configuration arguments
// Create the base arguments // Create the base arguments

View File

@ -54,8 +54,8 @@ func TestQemuDriver_Start(t *testing.T) {
task := &structs.Task{ task := &structs.Task{
Name: "linux", Name: "linux",
Config: map[string]string{ Config: map[string]string{
"image_source": "https://dl.dropboxusercontent.com/u/47675/jar_thing/linux-0.2.img", "artifact_source": "https://dl.dropboxusercontent.com/u/47675/jar_thing/linux-0.2.img",
"checksum": "a5e836985934c3392cbbd9b26db55a7d35a8d7ae1deb7ca559dd9c0159572544", "checksum": "sha256:a5e836985934c3392cbbd9b26db55a7d35a8d7ae1deb7ca559dd9c0159572544",
"accelerator": "tcg", "accelerator": "tcg",
"guest_ports": "22,8080", "guest_ports": "22,8080",
}, },
@ -103,11 +103,11 @@ func TestQemuDriver_RequiresMemory(t *testing.T) {
task := &structs.Task{ task := &structs.Task{
Name: "linux", Name: "linux",
Config: map[string]string{ Config: map[string]string{
"image_source": "https://dl.dropboxusercontent.com/u/47675/jar_thing/linux-0.2.img", "artifact_source": "https://dl.dropboxusercontent.com/u/47675/jar_thing/linux-0.2.img",
"accelerator": "tcg", "accelerator": "tcg",
"host_port": "8080", "host_port": "8080",
"guest_port": "8081", "guest_port": "8081",
"checksum": "a5e836985934c3392cbbd9b26db55a7d35a8d7ae1deb7ca559dd9c0159572544", "checksum": "sha256:a5e836985934c3392cbbd9b26db55a7d35a8d7ae1deb7ca559dd9c0159572544",
// ssh u/p would be here // ssh u/p would be here
}, },
} }

View File

@ -2,21 +2,18 @@ package driver
import ( import (
"fmt" "fmt"
"log"
"os" "os"
"os/exec" "os/exec"
"path"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
"syscall"
"time" "time"
"github.com/hashicorp/go-getter"
"github.com/hashicorp/nomad/client/allocdir" "github.com/hashicorp/nomad/client/allocdir"
"github.com/hashicorp/nomad/client/config" "github.com/hashicorp/nomad/client/config"
"github.com/hashicorp/nomad/client/driver/args" "github.com/hashicorp/nomad/client/driver/args"
"github.com/hashicorp/nomad/client/getter"
"github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/nomad/structs"
) )
@ -83,23 +80,14 @@ func (d *RawExecDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandl
source, ok := task.Config["artifact_source"] source, ok := task.Config["artifact_source"]
if ok && source != "" { if ok && source != "" {
// Proceed to download an artifact to be executed. // Proceed to download an artifact to be executed.
// We use go-getter to support a variety of protocols, but need to change _, err := getter.GetArtifact(
// file permissions of the resulted download to be executable filepath.Join(taskDir, allocdir.TaskLocal),
task.Config["artifact_source"],
// Create a location to download the artifact. task.Config["checksum"],
destDir := filepath.Join(taskDir, allocdir.TaskLocal) d.logger,
)
artifactName := path.Base(source) if err != nil {
artifactFile := filepath.Join(destDir, artifactName) return nil, err
if err := getter.GetFile(artifactFile, source); err != nil {
return nil, fmt.Errorf("Error downloading artifact for Raw Exec driver: %s", err)
}
// Add execution permissions to the newly downloaded artifact
if runtime.GOOS != "windows" {
if err := syscall.Chmod(artifactFile, 0755); err != nil {
log.Printf("[ERR] driver.raw_exec: Error making artifact executable: %s", err)
}
} }
} }

View File

@ -94,12 +94,14 @@ func TestRawExecDriver_StartOpen_Wait(t *testing.T) {
} }
func TestRawExecDriver_Start_Artifact_basic(t *testing.T) { func TestRawExecDriver_Start_Artifact_basic(t *testing.T) {
var file string var file, checksum string
switch runtime.GOOS { switch runtime.GOOS {
case "darwin": case "darwin":
file = "hi_darwin_amd64" file = "hi_darwin_amd64"
checksum = "md5:d7f2fdb13b36dcb7407721d78926b335"
default: default:
file = "hi_linux_amd64" file = "hi_linux_amd64"
checksum = "md5:a9b14903a8942748e4f8474e11f795d3"
} }
task := &structs.Task{ task := &structs.Task{
@ -107,6 +109,7 @@ func TestRawExecDriver_Start_Artifact_basic(t *testing.T) {
Config: map[string]string{ Config: map[string]string{
"artifact_source": fmt.Sprintf("https://dl.dropboxusercontent.com/u/47675/jar_thing/%s", file), "artifact_source": fmt.Sprintf("https://dl.dropboxusercontent.com/u/47675/jar_thing/%s", file),
"command": filepath.Join("$NOMAD_TASK_DIR", file), "command": filepath.Join("$NOMAD_TASK_DIR", file),
"checksum": checksum,
}, },
} }
driverCtx := testDriverContext(task.Name) driverCtx := testDriverContext(task.Name)

43
client/getter/getter.go Normal file
View File

@ -0,0 +1,43 @@
package getter
import (
"fmt"
"log"
"net/url"
"path"
"path/filepath"
"runtime"
"strings"
"syscall"
gg "github.com/hashicorp/go-getter"
)
func GetArtifact(destDir, source, checksum string, logger *log.Logger) (string, error) {
if source == "" {
return "", fmt.Errorf("Source url is empty in Artifact Getter")
}
u, err := url.Parse(source)
if err != nil {
return "", err
}
// if checksum is seperate, apply to source
if checksum != "" {
source = strings.Join([]string{source, fmt.Sprintf("checksum=%s", checksum)}, "?")
logger.Printf("[DEBUG] client.getter: Applying checksum to Artifact Source URL, new url: %s", source)
}
artifactFile := filepath.Join(destDir, path.Base(u.Path))
if err := gg.GetFile(artifactFile, source); err != nil {
return "", fmt.Errorf("Error downloading artifact: %s", err)
}
// Add execution permissions to the newly downloaded artifact
if runtime.GOOS != "windows" {
if err := syscall.Chmod(artifactFile, 0755); err != nil {
logger.Printf("[ERR] driver.raw_exec: Error making artifact executable: %s", err)
}
}
return artifactFile, nil
}

View File

@ -0,0 +1,111 @@
package getter
import (
"fmt"
"io/ioutil"
"log"
"os"
"strings"
"testing"
)
func TestGetArtifact_basic(t *testing.T) {
logger := log.New(os.Stderr, "", log.LstdFlags)
// TODO: Use http.TestServer to serve these files from fixtures dir
passing := []struct {
Source, Checksum string
}{
{
"https://dl.dropboxusercontent.com/u/47675/jar_thing/hi_darwin_amd64",
"sha256:66aa0f05fc0cfcf1e5ed8cc5307b5df51e33871d6b295a60e0f9f6dd573da977",
},
{
"https://dl.dropboxusercontent.com/u/47675/jar_thing/hi_linux_amd64",
"sha256:6f99b4c5184726e601ecb062500aeb9537862434dfe1898dbe5c68d9f50c179c",
},
{
"https://dl.dropboxusercontent.com/u/47675/jar_thing/hi_linux_amd64",
"md5:a9b14903a8942748e4f8474e11f795d3",
},
{
"https://dl.dropboxusercontent.com/u/47675/jar_thing/hi_linux_amd64?checksum=sha256:6f99b4c5184726e601ecb062500aeb9537862434dfe1898dbe5c68d9f50c179c",
"",
},
{
"https://dl.dropboxusercontent.com/u/47675/jar_thing/hi_linux_amd64",
"",
},
}
for i, p := range passing {
destDir, err := ioutil.TempDir("", fmt.Sprintf("nomad-test-%d", i))
if err != nil {
t.Fatalf("Error in TestGetArtifact_basic makeing TempDir: %s", err)
}
path, err := GetArtifact(destDir, p.Source, p.Checksum, logger)
if err != nil {
t.Fatalf("TestGetArtifact_basic unexpected failure here: %s", err)
}
if p.Checksum != "" {
if ok := strings.Contains(path, p.Checksum); ok {
t.Fatalf("path result should not contain the checksum, got: %s", path)
}
}
// verify artifact exists
if _, err := os.Stat(path); err != nil {
t.Fatalf("source path error: %s", err)
}
}
}
func TestGetArtifact_fails(t *testing.T) {
logger := log.New(os.Stderr, "", log.LstdFlags)
failing := []struct {
Source, Checksum string
}{
{
"",
"sha256:66aa0f05fc0cfcf1e5ed8cc5307b5d",
},
{
"/u/47675/jar_thing/hi_darwin_amd64",
"sha256:66aa0f05fc0cfcf1e5ed8cc5307b5d",
},
{
"https://dl.dropboxusercontent.com/u/47675/jar_thing/hi_darwin_amd64",
"sha256:66aa0f05fc0cfcf1e5ed8cc5307b5d",
},
{
"https://dl.dropboxusercontent.com/u/47675/jar_thing/hi_linux_amd64",
"sha257:6f99b4c5184726e601ecb062500aeb9537862434dfe1898dbe5c68d9f50c179c",
},
// malformed checksum
{
"https://dl.dropboxusercontent.com/u/47675/jar_thing/hi_linux_amd64",
"6f99b4c5184726e601ecb062500aeb9537862434dfe1898dbe5c68d9f50c179c",
},
// 404
{
"https://dl.dropboxusercontent.com/u/47675/jar_thing/hi_linux_amd86",
"",
},
}
for i, p := range failing {
destDir, err := ioutil.TempDir("", fmt.Sprintf("nomad-test-%d", i))
if err != nil {
t.Fatalf("Error in TestGetArtifact_basic makeing TempDir: %s", err)
}
_, err = GetArtifact(destDir, p.Source, p.Checksum, logger)
if err == nil {
t.Fatalf("TestGetArtifact_basic expected failure, but got none")
}
}
}

View File

@ -24,6 +24,10 @@ The `exec` driver supports the following configuration in the job spec:
* `artifact_source` (Optional) Source location of an executable artifact. Must be accessible * `artifact_source` (Optional) Source location of an executable artifact. Must be accessible
from the Nomad client. If you specify an `artifact_source` to be executed, you from the Nomad client. If you specify an `artifact_source` to be executed, you
must reference it in the `command` as show in the examples below must reference it in the `command` as show in the examples below
* `checksum` - **(Optional)** The checksum type and value for the `artifact_source` image.
The format is `type:value`, where type is any of `md5`, `sha1`, `sha256`, or `sha512`,
and the value is the computed checksum. If a checksum is supplied and does not
match the downloaded artifact, the driver will fail to start
* `args` - The argument list to the command, space seperated. Optional. * `args` - The argument list to the command, space seperated. Optional.
## Client Requirements ## Client Requirements
@ -53,6 +57,7 @@ To execute a binary specified by `artifact_source`:
``` ```
config { config {
artifact_source = "https://dl.dropboxusercontent.com/u/1234/binary.bin" artifact_source = "https://dl.dropboxusercontent.com/u/1234/binary.bin"
checksum = "sha256:abd123445ds4555555555"
command = "$NOMAD_TASK_DIR/binary.bin" command = "$NOMAD_TASK_DIR/binary.bin"
} }
``` ```

View File

@ -18,8 +18,12 @@ HTTP from the Nomad client.
The `java` driver supports the following configuration in the job spec: The `java` driver supports the following configuration in the job spec:
* `jar_source` - **(Required)** The hosted location of the source Jar file. Must be accessible * `artifact_source` - **(Required)** The hosted location of the source Jar file. Must be accessible
from the Nomad client from the Nomad client
* `checksum` - **(Optional)** The checksum type and value for the `artifact_source` image.
The format is `type:value`, where type is any of `md5`, `sha1`, `sha256`, or `sha512`,
and the value is the computed checksum. If a checksum is supplied and does not
match the downloaded artifact, the driver will fail to start
* `args` - **(Optional)** The argument list for the `java` command, space separated. * `args` - **(Optional)** The argument list for the `java` command, space separated.
@ -29,10 +33,27 @@ from the Nomad client
## Client Requirements ## Client Requirements
The `java` driver requires Java to be installed and in your systems `$PATH`. The `java` driver requires Java to be installed and in your systems `$PATH`.
The `jar_source` must be accessible by the node running Nomad. This can be an The `artifact_source` must be accessible by the node running Nomad. This can be an
internal source, private to your cluster, but it must be reachable by the client internal source, private to your cluster, but it must be reachable by the client
over HTTP. over HTTP.
## Examples
A simple config block to run a Java Jar:
```json
# Define a task to run
task "web" {
# Run a Java Jar
driver = "java"
config {
artifact_source = "https://dl.dropboxusercontent.com/u/1234/hello.jar"
checksum = "md5:123445555555555"
jvm_options = "-Xmx2048m -Xms256m"
}
```
## Client Attributes ## Client Attributes
The `java` driver will set the following client attributes: The `java` driver will set the following client attributes:

View File

@ -23,10 +23,12 @@ The `Qemu` driver can execute any regular `qemu` image (e.g. `qcow`, `img`,
The `Qemu` driver supports the following configuration in the job spec: The `Qemu` driver supports the following configuration in the job spec:
* `image_source` - **(Required)** The hosted location of the source Qemu image. Must be accessible * `artifact_source` - **(Required)** The hosted location of the source Qemu image. Must be accessible
from the Nomad client, via HTTP. from the Nomad client, via HTTP.
* `checksum` - **(Required)** The SHA256 checksum of the `qemu` image. If the * `checksum` - **(Optional)** The checksum type and value for the `artifact_source` image.
checksums do not match, the `Qemu` driver will fail to start the image The format is `type:value`, where type is any of `md5`, `sha1`, `sha256`, or `sha512`,
and the value is the computed checksum. If a checksum is supplied and does not
match the downloaded artifact, the driver will fail to start
* `accelerator` - (Optional) The type of accelerator to use in the invocation. * `accelerator` - (Optional) The type of accelerator to use in the invocation.
If the host machine has `Qemu` installed with KVM support, users can specify `kvm` for the `accelerator`. Default is `tcg` If the host machine has `Qemu` installed with KVM support, users can specify `kvm` for the `accelerator`. Default is `tcg`
* `host_port` - **(Required)** Port on the host machine to forward to the guest * `host_port` - **(Required)** Port on the host machine to forward to the guest
@ -38,7 +40,7 @@ in the `Task` specification
## Client Requirements ## Client Requirements
The `Qemu` driver requires Qemu to be installed and in your system's `$PATH`. The `Qemu` driver requires Qemu to be installed and in your system's `$PATH`.
The `image_source` must be accessible by the node running Nomad. This can be an The `artifact_source` must be accessible by the node running Nomad. This can be an
internal source, private to your cluster, but it must be reachable by the client internal source, private to your cluster, but it must be reachable by the client
over HTTP. over HTTP.

View File

@ -22,6 +22,10 @@ The `raw_exec` driver supports the following configuration in the job spec:
* `artifact_source` (Optional) Source location of an executable artifact. Must be accessible * `artifact_source` (Optional) Source location of an executable artifact. Must be accessible
from the Nomad client. If you specify an `artifact_source` to be executed, you from the Nomad client. If you specify an `artifact_source` to be executed, you
must reference it in the `command` as show in the examples below must reference it in the `command` as show in the examples below
* `checksum` - **(Optional)** The checksum type and value for the `artifact_source` image.
The format is `type:value`, where type is any of `md5`, `sha1`, `sha256`, or `sha512`,
and the value is the computed checksum. If a checksum is supplied and does not
match the downloaded artifact, the driver will fail to start
* `args` - The argument list to the command, space seperated. Optional. * `args` - The argument list to the command, space seperated. Optional.
## Client Requirements ## Client Requirements
@ -57,6 +61,7 @@ To execute a binary specified by `artifact_source`:
``` ```
config { config {
artifact_source = "https://dl.dropboxusercontent.com/u/1234/binary.bin" artifact_source = "https://dl.dropboxusercontent.com/u/1234/binary.bin"
checksum = "sha256:133jifjiofu9090fsadjofsdjlk"
command = "$NOMAD_TASK_DIR/binary.bin" command = "$NOMAD_TASK_DIR/binary.bin"
} }
``` ```