2015-11-03 21:15:40 +00:00
|
|
|
package getter
|
|
|
|
|
|
|
|
import (
|
2015-11-03 21:16:17 +00:00
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"log"
|
2016-03-15 02:55:30 +00:00
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
2015-11-03 21:16:17 +00:00
|
|
|
"os"
|
2016-03-15 02:55:30 +00:00
|
|
|
"path/filepath"
|
|
|
|
"reflect"
|
2015-11-03 21:16:17 +00:00
|
|
|
"strings"
|
|
|
|
"testing"
|
2016-03-15 02:55:30 +00:00
|
|
|
|
2016-04-12 01:46:16 +00:00
|
|
|
"github.com/hashicorp/nomad/client/driver/env"
|
|
|
|
"github.com/hashicorp/nomad/nomad/mock"
|
2016-03-15 02:55:30 +00:00
|
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
2015-11-03 21:15:40 +00:00
|
|
|
)
|
|
|
|
|
2016-03-15 02:55:30 +00:00
|
|
|
func TestGetArtifact_FileAndChecksum(t *testing.T) {
|
|
|
|
// Create the test server hosting the file to download
|
|
|
|
ts := httptest.NewServer(http.FileServer(http.Dir(filepath.Dir("./test-fixtures/"))))
|
|
|
|
defer ts.Close()
|
2015-11-03 21:15:40 +00:00
|
|
|
|
2016-03-15 02:55:30 +00:00
|
|
|
// Create a temp directory to download into
|
2016-03-18 22:33:01 +00:00
|
|
|
taskDir, err := ioutil.TempDir("", "nomad-test")
|
2016-03-15 02:55:30 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("failed to make temp directory: %v", err)
|
|
|
|
}
|
2016-03-18 22:33:01 +00:00
|
|
|
defer os.RemoveAll(taskDir)
|
2015-11-03 21:15:40 +00:00
|
|
|
|
2016-03-15 02:55:30 +00:00
|
|
|
// Create the artifact
|
|
|
|
file := "test.sh"
|
|
|
|
artifact := &structs.TaskArtifact{
|
|
|
|
GetterSource: fmt.Sprintf("%s/%s", ts.URL, file),
|
|
|
|
GetterOptions: map[string]string{
|
|
|
|
"checksum": "md5:bce963762aa2dbfed13caf492a45fb72",
|
2015-11-03 21:16:17 +00:00
|
|
|
},
|
2016-03-15 02:55:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Download the artifact
|
2016-04-12 01:46:16 +00:00
|
|
|
taskEnv := env.NewTaskEnvironment(mock.Node())
|
2016-03-15 02:55:30 +00:00
|
|
|
logger := log.New(os.Stderr, "", log.LstdFlags)
|
2016-04-12 01:46:16 +00:00
|
|
|
if err := GetArtifact(taskEnv, artifact, taskDir, logger); err != nil {
|
2016-03-15 02:55:30 +00:00
|
|
|
t.Fatalf("GetArtifact failed: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify artifact exists
|
2016-03-18 22:33:01 +00:00
|
|
|
if _, err := os.Stat(filepath.Join(taskDir, file)); err != nil {
|
|
|
|
t.Fatalf("file not found: %s", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetArtifact_File_RelativeDest(t *testing.T) {
|
|
|
|
// Create the test server hosting the file to download
|
|
|
|
ts := httptest.NewServer(http.FileServer(http.Dir(filepath.Dir("./test-fixtures/"))))
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
// Create a temp directory to download into
|
|
|
|
taskDir, err := ioutil.TempDir("", "nomad-test")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("failed to make temp directory: %v", err)
|
|
|
|
}
|
|
|
|
defer os.RemoveAll(taskDir)
|
|
|
|
|
|
|
|
// Create the artifact
|
|
|
|
file := "test.sh"
|
|
|
|
relative := "foo/"
|
|
|
|
artifact := &structs.TaskArtifact{
|
|
|
|
GetterSource: fmt.Sprintf("%s/%s", ts.URL, file),
|
|
|
|
GetterOptions: map[string]string{
|
|
|
|
"checksum": "md5:bce963762aa2dbfed13caf492a45fb72",
|
|
|
|
},
|
|
|
|
RelativeDest: relative,
|
|
|
|
}
|
|
|
|
|
|
|
|
// Download the artifact
|
2016-04-12 01:46:16 +00:00
|
|
|
taskEnv := env.NewTaskEnvironment(mock.Node())
|
2016-03-18 22:33:01 +00:00
|
|
|
logger := log.New(os.Stderr, "", log.LstdFlags)
|
2016-04-12 01:46:16 +00:00
|
|
|
if err := GetArtifact(taskEnv, artifact, taskDir, logger); err != nil {
|
2016-03-18 22:33:01 +00:00
|
|
|
t.Fatalf("GetArtifact failed: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify artifact was downloaded to the correct path
|
|
|
|
if _, err := os.Stat(filepath.Join(taskDir, relative, file)); err != nil {
|
|
|
|
t.Fatalf("file not found: %s", err)
|
2016-03-15 02:55:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-12 01:46:16 +00:00
|
|
|
func TestGetGetterUrl_Interprolation(t *testing.T) {
|
|
|
|
// Create the artifact
|
|
|
|
artifact := &structs.TaskArtifact{
|
|
|
|
GetterSource: "${NOMAD_META_ARTIFACT}",
|
|
|
|
}
|
|
|
|
|
|
|
|
url := "foo.com"
|
|
|
|
taskEnv := env.NewTaskEnvironment(mock.Node()).SetTaskMeta(map[string]string{"artifact": url})
|
|
|
|
act, err := getGetterUrl(taskEnv, artifact)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("getGetterUrl() failed: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if act != url {
|
|
|
|
t.Fatalf("getGetterUrl() returned %q; want %q", act, url)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-15 02:55:30 +00:00
|
|
|
func TestGetArtifact_InvalidChecksum(t *testing.T) {
|
|
|
|
// Create the test server hosting the file to download
|
|
|
|
ts := httptest.NewServer(http.FileServer(http.Dir(filepath.Dir("./test-fixtures/"))))
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
// Create a temp directory to download into
|
2016-03-18 22:33:01 +00:00
|
|
|
taskDir, err := ioutil.TempDir("", "nomad-test")
|
2016-03-15 02:55:30 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("failed to make temp directory: %v", err)
|
|
|
|
}
|
2016-03-18 22:33:01 +00:00
|
|
|
defer os.RemoveAll(taskDir)
|
2016-03-15 02:55:30 +00:00
|
|
|
|
|
|
|
// Create the artifact with an incorrect checksum
|
|
|
|
file := "test.sh"
|
|
|
|
artifact := &structs.TaskArtifact{
|
|
|
|
GetterSource: fmt.Sprintf("%s/%s", ts.URL, file),
|
|
|
|
GetterOptions: map[string]string{
|
|
|
|
"checksum": "md5:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
2015-11-03 21:16:17 +00:00
|
|
|
},
|
|
|
|
}
|
2015-11-03 21:15:40 +00:00
|
|
|
|
2016-03-15 02:55:30 +00:00
|
|
|
// Download the artifact and expect an error
|
2016-04-12 01:46:16 +00:00
|
|
|
taskEnv := env.NewTaskEnvironment(mock.Node())
|
2016-03-15 02:55:30 +00:00
|
|
|
logger := log.New(os.Stderr, "", log.LstdFlags)
|
2016-04-12 01:46:16 +00:00
|
|
|
if err := GetArtifact(taskEnv, artifact, taskDir, logger); err == nil {
|
2016-03-15 02:55:30 +00:00
|
|
|
t.Fatalf("GetArtifact should have failed")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func createContents(basedir string, fileContents map[string]string, t *testing.T) {
|
|
|
|
for relPath, content := range fileContents {
|
|
|
|
folder := basedir
|
|
|
|
if strings.Index(relPath, "/") != -1 {
|
|
|
|
// Create the folder.
|
|
|
|
folder = filepath.Join(basedir, filepath.Dir(relPath))
|
|
|
|
if err := os.Mkdir(folder, 0777); err != nil {
|
|
|
|
t.Fatalf("failed to make directory: %v", err)
|
|
|
|
}
|
2015-11-03 21:16:17 +00:00
|
|
|
}
|
2015-11-03 21:15:40 +00:00
|
|
|
|
2016-03-15 02:55:30 +00:00
|
|
|
// Create a file in the existing folder.
|
|
|
|
file := filepath.Join(folder, filepath.Base(relPath))
|
|
|
|
if err := ioutil.WriteFile(file, []byte(content), 0777); err != nil {
|
|
|
|
t.Fatalf("failed to write data to file %v: %v", file, err)
|
2015-11-03 21:16:17 +00:00
|
|
|
}
|
2016-03-15 02:55:30 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-03 21:15:40 +00:00
|
|
|
|
2016-03-15 02:55:30 +00:00
|
|
|
func checkContents(basedir string, fileContents map[string]string, t *testing.T) {
|
|
|
|
for relPath, content := range fileContents {
|
|
|
|
path := filepath.Join(basedir, relPath)
|
|
|
|
actual, err := ioutil.ReadFile(path)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("failed to read file %q: %v", path, err)
|
2015-11-03 21:16:17 +00:00
|
|
|
}
|
2015-11-03 21:15:40 +00:00
|
|
|
|
2016-03-15 02:55:30 +00:00
|
|
|
if !reflect.DeepEqual(actual, []byte(content)) {
|
|
|
|
t.Fatalf("%q: expected %q; got %q", path, content, string(actual))
|
2015-11-03 21:16:17 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-03 21:15:40 +00:00
|
|
|
}
|
|
|
|
|
2016-03-15 02:55:30 +00:00
|
|
|
func TestGetArtifact_Archive(t *testing.T) {
|
|
|
|
// Create the test server hosting the file to download
|
|
|
|
ts := httptest.NewServer(http.FileServer(http.Dir(filepath.Dir("./test-fixtures/"))))
|
|
|
|
defer ts.Close()
|
2015-11-03 21:15:40 +00:00
|
|
|
|
2016-03-15 02:55:30 +00:00
|
|
|
// Create a temp directory to download into and create some of the same
|
2016-05-15 16:41:34 +00:00
|
|
|
// files that exist in the artifact to ensure they are overridden
|
2016-03-18 22:33:01 +00:00
|
|
|
taskDir, err := ioutil.TempDir("", "nomad-test")
|
2016-03-15 02:55:30 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("failed to make temp directory: %v", err)
|
|
|
|
}
|
2016-03-18 22:33:01 +00:00
|
|
|
defer os.RemoveAll(taskDir)
|
2015-11-03 21:15:40 +00:00
|
|
|
|
2016-03-15 02:55:30 +00:00
|
|
|
create := map[string]string{
|
|
|
|
"exist/my.config": "to be replaced",
|
|
|
|
"untouched": "existing top-level",
|
|
|
|
}
|
2016-03-18 22:33:01 +00:00
|
|
|
createContents(taskDir, create, t)
|
2016-03-15 02:55:30 +00:00
|
|
|
|
|
|
|
file := "archive.tar.gz"
|
|
|
|
artifact := &structs.TaskArtifact{
|
|
|
|
GetterSource: fmt.Sprintf("%s/%s", ts.URL, file),
|
|
|
|
GetterOptions: map[string]string{
|
|
|
|
"checksum": "sha1:20bab73c72c56490856f913cf594bad9a4d730f6",
|
2015-11-03 21:16:17 +00:00
|
|
|
},
|
|
|
|
}
|
2015-11-03 21:15:40 +00:00
|
|
|
|
2016-04-12 01:46:16 +00:00
|
|
|
taskEnv := env.NewTaskEnvironment(mock.Node())
|
2016-03-15 02:55:30 +00:00
|
|
|
logger := log.New(os.Stderr, "", log.LstdFlags)
|
2016-04-12 01:46:16 +00:00
|
|
|
if err := GetArtifact(taskEnv, artifact, taskDir, logger); err != nil {
|
2016-03-15 02:55:30 +00:00
|
|
|
t.Fatalf("GetArtifact failed: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify the unarchiving overrode files properly.
|
|
|
|
expected := map[string]string{
|
|
|
|
"untouched": "existing top-level",
|
|
|
|
"exist/my.config": "hello world\n",
|
|
|
|
"new/my.config": "hello world\n",
|
|
|
|
"test.sh": "sleep 1\n",
|
2015-11-03 21:16:17 +00:00
|
|
|
}
|
2016-03-18 22:33:01 +00:00
|
|
|
checkContents(taskDir, expected, t)
|
2015-11-03 21:15:40 +00:00
|
|
|
}
|