github.com/dkerwin/nomad@v0.3.3-0.20160525181927-74554135514b/client/getter/getter.go (about)

     1  package getter
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"net/url"
     7  	"path/filepath"
     8  	"sync"
     9  
    10  	gg "github.com/hashicorp/go-getter"
    11  	"github.com/hashicorp/nomad/client/driver/env"
    12  	"github.com/hashicorp/nomad/nomad/structs"
    13  )
    14  
    15  var (
    16  	// getters is the map of getters suitable for Nomad. It is initialized once
    17  	// and the lock is used to guard access to it.
    18  	getters map[string]gg.Getter
    19  	lock    sync.Mutex
    20  
    21  	// supported is the set of download schemes supported by Nomad
    22  	supported = []string{"http", "https", "s3"}
    23  )
    24  
    25  // getClient returns a client that is suitable for Nomad downloading artifacts.
    26  func getClient(src, dst string) *gg.Client {
    27  	lock.Lock()
    28  	defer lock.Unlock()
    29  
    30  	// Return the pre-initialized client
    31  	if getters == nil {
    32  		getters = make(map[string]gg.Getter, len(supported))
    33  		for _, getter := range supported {
    34  			if impl, ok := gg.Getters[getter]; ok {
    35  				getters[getter] = impl
    36  			}
    37  		}
    38  	}
    39  
    40  	return &gg.Client{
    41  		Src:     src,
    42  		Dst:     dst,
    43  		Mode:    gg.ClientModeAny,
    44  		Getters: getters,
    45  	}
    46  }
    47  
    48  // getGetterUrl returns the go-getter URL to download the artifact.
    49  func getGetterUrl(taskEnv *env.TaskEnvironment, artifact *structs.TaskArtifact) (string, error) {
    50  	taskEnv.Build()
    51  	u, err := url.Parse(taskEnv.ReplaceEnv(artifact.GetterSource))
    52  	if err != nil {
    53  		return "", fmt.Errorf("failed to parse source URL %q: %v", artifact.GetterSource, err)
    54  	}
    55  
    56  	// Build the url
    57  	q := u.Query()
    58  	for k, v := range artifact.GetterOptions {
    59  		q.Add(k, taskEnv.ReplaceEnv(v))
    60  	}
    61  	u.RawQuery = q.Encode()
    62  	return u.String(), nil
    63  }
    64  
    65  // GetArtifact downloads an artifact into the specified task directory.
    66  func GetArtifact(taskEnv *env.TaskEnvironment, artifact *structs.TaskArtifact,
    67  	taskDir string, logger *log.Logger) error {
    68  
    69  	url, err := getGetterUrl(taskEnv, artifact)
    70  	if err != nil {
    71  		return err
    72  	}
    73  
    74  	// Download the artifact
    75  	dest := filepath.Join(taskDir, artifact.RelativeDest)
    76  	if err := getClient(url, dest).Get(); err != nil {
    77  		return fmt.Errorf("GET error: %v", err)
    78  	}
    79  
    80  	return nil
    81  }