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 }