github.com/mattyr/nomad@v0.3.3-0.20160919021406-3485a065154a/client/getter/getter.go (about)

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