github.com/paultyng/terraform@v0.6.11-0.20180227224804-66ff8f8bed40/configs/configload/getter.go (about) 1 package configload 2 3 import ( 4 "log" 5 "path/filepath" 6 7 cleanhttp "github.com/hashicorp/go-cleanhttp" 8 getter "github.com/hashicorp/go-getter" 9 ) 10 11 // We configure our own go-getter detector and getter sets here, because 12 // the set of sources we support is part of Terraform's documentation and 13 // so we don't want any new sources introduced in go-getter to sneak in here 14 // and work even though they aren't documented. This also insulates us from 15 // any meddling that might be done by other go-getter callers linked into our 16 // executable. 17 18 var goGetterDetectors = []getter.Detector{ 19 new(getter.GitHubDetector), 20 new(getter.BitBucketDetector), 21 new(getter.S3Detector), 22 new(getter.FileDetector), 23 } 24 25 var goGetterNoDetectors = []getter.Detector{} 26 27 var goGetterDecompressors = map[string]getter.Decompressor{ 28 "bz2": new(getter.Bzip2Decompressor), 29 "gz": new(getter.GzipDecompressor), 30 "xz": new(getter.XzDecompressor), 31 "zip": new(getter.ZipDecompressor), 32 33 "tar.bz2": new(getter.TarBzip2Decompressor), 34 "tar.tbz2": new(getter.TarBzip2Decompressor), 35 36 "tar.gz": new(getter.TarGzipDecompressor), 37 "tgz": new(getter.TarGzipDecompressor), 38 39 "tar.xz": new(getter.TarXzDecompressor), 40 "txz": new(getter.TarXzDecompressor), 41 } 42 43 var goGetterGetters = map[string]getter.Getter{ 44 "file": new(getter.FileGetter), 45 "git": new(getter.GitGetter), 46 "hg": new(getter.HgGetter), 47 "s3": new(getter.S3Getter), 48 "http": getterHTTPGetter, 49 "https": getterHTTPGetter, 50 } 51 52 var getterHTTPClient = cleanhttp.DefaultClient() 53 54 var getterHTTPGetter = &getter.HttpGetter{ 55 Client: getterHTTPClient, 56 Netrc: true, 57 } 58 59 // getWithGoGetter retrieves the package referenced in the given address 60 // into the installation path and then returns the full path to any subdir 61 // indicated in the address. 62 // 63 // The errors returned by this function are those surfaced by the underlying 64 // go-getter library, which have very inconsistent quality as 65 // end-user-actionable error messages. At this time we do not have any 66 // reasonable way to improve these error messages at this layer because 67 // the underlying errors are not separatelyr recognizable. 68 func getWithGoGetter(instPath, addr string) (string, error) { 69 packageAddr, subDir := splitAddrSubdir(addr) 70 71 log.Printf("[DEBUG] will download %q to %s", packageAddr, instPath) 72 73 realAddr, err := getter.Detect(packageAddr, instPath, getter.Detectors) 74 if err != nil { 75 return "", err 76 } 77 78 var realSubDir string 79 realAddr, realSubDir = splitAddrSubdir(realAddr) 80 if realSubDir != "" { 81 subDir = filepath.Join(realSubDir, subDir) 82 } 83 84 if realAddr != packageAddr { 85 log.Printf("[TRACE] go-getter detectors rewrote %q to %q", packageAddr, realAddr) 86 } 87 88 client := getter.Client{ 89 Src: realAddr, 90 Dst: instPath, 91 Pwd: instPath, 92 93 Mode: getter.ClientModeDir, 94 95 Detectors: goGetterNoDetectors, // we already did detection above 96 Decompressors: goGetterDecompressors, 97 Getters: goGetterGetters, 98 } 99 err = client.Get() 100 if err != nil { 101 return "", err 102 } 103 104 // Our subDir string can contain wildcards until this point, so that 105 // e.g. a subDir of * can expand to one top-level directory in a .tar.gz 106 // archive. Now that we've expanded the archive successfully we must 107 // resolve that into a concrete path. 108 var finalDir string 109 if subDir != "" { 110 finalDir, err = getter.SubdirGlob(instPath, subDir) 111 log.Printf("[TRACE] expanded %q to %q", subDir, finalDir) 112 if err != nil { 113 return "", err 114 } 115 } else { 116 finalDir = instPath 117 } 118 119 // If we got this far then we have apparently succeeded in downloading 120 // the requested object! 121 return filepath.Clean(finalDir), nil 122 }