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  }