2013-08-15 14:05:36 -04:00
|
|
|
package common
|
|
|
|
|
|
|
|
import (
|
2018-01-22 18:32:33 -05:00
|
|
|
"context"
|
2015-06-08 23:41:39 -04:00
|
|
|
"crypto/sha1"
|
2013-08-15 14:05:36 -04:00
|
|
|
"encoding/hex"
|
|
|
|
"fmt"
|
|
|
|
"log"
|
Use the hashicorp/go-getter to download files
* removed packer.Cache and references since packer.Cache is never used except in the download step. The download step now uses the new func packer.CachePath(targetPath) for this, the behavior is the same.
* removed download code from packer that was reimplemented into the go-getter library: progress bar, http download restart, checksuming from file, skip already downloaded files, symlinking, make a download cancellable by context.
* on windows if packer is running without symlinking rights and we are getting a local file, the file will be copied instead to avoid errors.
* added unit tests for step_download that are now CI tested on windows, mac & linux.
* files are now downloaded under cache dir `sha1(filename + "?checksum=" + checksum) + file_extension`
* since the output dir is based on the source url and the checksum, when the checksum fails, the file is auto deleted.
* a download file is protected and locked by a file lock,
* updated docs
* updated go modules and vendors
2019-03-13 07:11:58 -04:00
|
|
|
"os"
|
2014-10-27 23:51:34 -04:00
|
|
|
|
Use the hashicorp/go-getter to download files
* removed packer.Cache and references since packer.Cache is never used except in the download step. The download step now uses the new func packer.CachePath(targetPath) for this, the behavior is the same.
* removed download code from packer that was reimplemented into the go-getter library: progress bar, http download restart, checksuming from file, skip already downloaded files, symlinking, make a download cancellable by context.
* on windows if packer is running without symlinking rights and we are getting a local file, the file will be copied instead to avoid errors.
* added unit tests for step_download that are now CI tested on windows, mac & linux.
* files are now downloaded under cache dir `sha1(filename + "?checksum=" + checksum) + file_extension`
* since the output dir is based on the source url and the checksum, when the checksum fails, the file is auto deleted.
* a download file is protected and locked by a file lock,
* updated docs
* updated go modules and vendors
2019-03-13 07:11:58 -04:00
|
|
|
"github.com/gofrs/flock"
|
|
|
|
getter "github.com/hashicorp/go-getter"
|
|
|
|
urlhelper "github.com/hashicorp/go-getter/helper/url"
|
2018-01-19 19:18:44 -05:00
|
|
|
"github.com/hashicorp/packer/helper/multistep"
|
2017-04-04 16:39:01 -04:00
|
|
|
"github.com/hashicorp/packer/packer"
|
2013-08-15 14:05:36 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
// StepDownload downloads a remote file using the download client within
|
|
|
|
// this package. This step handles setting up the download configuration,
|
|
|
|
// progress reporting, interrupt handling, etc.
|
|
|
|
//
|
|
|
|
// Uses:
|
|
|
|
// cache packer.Cache
|
|
|
|
// ui packer.Ui
|
|
|
|
type StepDownload struct {
|
|
|
|
// The checksum and the type of the checksum for the download
|
|
|
|
Checksum string
|
|
|
|
ChecksumType string
|
|
|
|
|
|
|
|
// A short description of the type of download being done. Example:
|
|
|
|
// "ISO" or "Guest Additions"
|
|
|
|
Description string
|
|
|
|
|
|
|
|
// The name of the key where the final path of the ISO will be put
|
|
|
|
// into the state.
|
|
|
|
ResultKey string
|
|
|
|
|
2013-08-15 14:15:32 -04:00
|
|
|
// The path where the result should go, otherwise it goes to the
|
|
|
|
// cache directory.
|
|
|
|
TargetPath string
|
|
|
|
|
2013-08-15 14:05:36 -04:00
|
|
|
// A list of URLs to attempt to download this thing.
|
|
|
|
Url []string
|
2015-06-08 23:41:39 -04:00
|
|
|
|
|
|
|
// Extension is the extension to force for the file that is downloaded.
|
|
|
|
// Some systems require a certain extension. If this isn't set, the
|
|
|
|
// extension on the URL is used. Otherwise, this will be forced
|
|
|
|
// on the downloaded file for every URL.
|
|
|
|
Extension string
|
2013-08-15 14:05:36 -04:00
|
|
|
}
|
|
|
|
|
Use the hashicorp/go-getter to download files
* removed packer.Cache and references since packer.Cache is never used except in the download step. The download step now uses the new func packer.CachePath(targetPath) for this, the behavior is the same.
* removed download code from packer that was reimplemented into the go-getter library: progress bar, http download restart, checksuming from file, skip already downloaded files, symlinking, make a download cancellable by context.
* on windows if packer is running without symlinking rights and we are getting a local file, the file will be copied instead to avoid errors.
* added unit tests for step_download that are now CI tested on windows, mac & linux.
* files are now downloaded under cache dir `sha1(filename + "?checksum=" + checksum) + file_extension`
* since the output dir is based on the source url and the checksum, when the checksum fails, the file is auto deleted.
* a download file is protected and locked by a file lock,
* updated docs
* updated go modules and vendors
2019-03-13 07:11:58 -04:00
|
|
|
func (s *StepDownload) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
2013-08-31 15:17:59 -04:00
|
|
|
ui := state.Get("ui").(packer.Ui)
|
Use the hashicorp/go-getter to download files
* removed packer.Cache and references since packer.Cache is never used except in the download step. The download step now uses the new func packer.CachePath(targetPath) for this, the behavior is the same.
* removed download code from packer that was reimplemented into the go-getter library: progress bar, http download restart, checksuming from file, skip already downloaded files, symlinking, make a download cancellable by context.
* on windows if packer is running without symlinking rights and we are getting a local file, the file will be copied instead to avoid errors.
* added unit tests for step_download that are now CI tested on windows, mac & linux.
* files are now downloaded under cache dir `sha1(filename + "?checksum=" + checksum) + file_extension`
* since the output dir is based on the source url and the checksum, when the checksum fails, the file is auto deleted.
* a download file is protected and locked by a file lock,
* updated docs
* updated go modules and vendors
2019-03-13 07:11:58 -04:00
|
|
|
defer ui.Say(fmt.Sprintf("leaving retrieve loop for %s", s.Description))
|
2013-08-15 14:05:36 -04:00
|
|
|
|
2018-08-20 05:38:41 -04:00
|
|
|
ui.Say(fmt.Sprintf("Retrieving %s", s.Description))
|
2013-08-15 14:05:36 -04:00
|
|
|
|
Use the hashicorp/go-getter to download files
* removed packer.Cache and references since packer.Cache is never used except in the download step. The download step now uses the new func packer.CachePath(targetPath) for this, the behavior is the same.
* removed download code from packer that was reimplemented into the go-getter library: progress bar, http download restart, checksuming from file, skip already downloaded files, symlinking, make a download cancellable by context.
* on windows if packer is running without symlinking rights and we are getting a local file, the file will be copied instead to avoid errors.
* added unit tests for step_download that are now CI tested on windows, mac & linux.
* files are now downloaded under cache dir `sha1(filename + "?checksum=" + checksum) + file_extension`
* since the output dir is based on the source url and the checksum, when the checksum fails, the file is auto deleted.
* a download file is protected and locked by a file lock,
* updated docs
* updated go modules and vendors
2019-03-13 07:11:58 -04:00
|
|
|
var errs []error
|
|
|
|
for _, source := range s.Url {
|
|
|
|
if ctx.Err() != nil {
|
|
|
|
state.Put("error", fmt.Errorf("Download cancelled: %v", errs))
|
|
|
|
return multistep.ActionHalt
|
2013-08-15 14:05:36 -04:00
|
|
|
}
|
Use the hashicorp/go-getter to download files
* removed packer.Cache and references since packer.Cache is never used except in the download step. The download step now uses the new func packer.CachePath(targetPath) for this, the behavior is the same.
* removed download code from packer that was reimplemented into the go-getter library: progress bar, http download restart, checksuming from file, skip already downloaded files, symlinking, make a download cancellable by context.
* on windows if packer is running without symlinking rights and we are getting a local file, the file will be copied instead to avoid errors.
* added unit tests for step_download that are now CI tested on windows, mac & linux.
* files are now downloaded under cache dir `sha1(filename + "?checksum=" + checksum) + file_extension`
* since the output dir is based on the source url and the checksum, when the checksum fails, the file is auto deleted.
* a download file is protected and locked by a file lock,
* updated docs
* updated go modules and vendors
2019-03-13 07:11:58 -04:00
|
|
|
ui.Say(fmt.Sprintf("Trying %s", source))
|
|
|
|
dst, err := s.download(ctx, ui, source)
|
|
|
|
if err == nil {
|
|
|
|
state.Put(s.ResultKey, dst)
|
|
|
|
return multistep.ActionContinue
|
2013-08-15 14:05:36 -04:00
|
|
|
}
|
Use the hashicorp/go-getter to download files
* removed packer.Cache and references since packer.Cache is never used except in the download step. The download step now uses the new func packer.CachePath(targetPath) for this, the behavior is the same.
* removed download code from packer that was reimplemented into the go-getter library: progress bar, http download restart, checksuming from file, skip already downloaded files, symlinking, make a download cancellable by context.
* on windows if packer is running without symlinking rights and we are getting a local file, the file will be copied instead to avoid errors.
* added unit tests for step_download that are now CI tested on windows, mac & linux.
* files are now downloaded under cache dir `sha1(filename + "?checksum=" + checksum) + file_extension`
* since the output dir is based on the source url and the checksum, when the checksum fails, the file is auto deleted.
* a download file is protected and locked by a file lock,
* updated docs
* updated go modules and vendors
2019-03-13 07:11:58 -04:00
|
|
|
// may be another url will work
|
|
|
|
errs = append(errs, err)
|
2017-11-25 16:02:54 -05:00
|
|
|
}
|
2013-08-15 14:05:36 -04:00
|
|
|
|
Use the hashicorp/go-getter to download files
* removed packer.Cache and references since packer.Cache is never used except in the download step. The download step now uses the new func packer.CachePath(targetPath) for this, the behavior is the same.
* removed download code from packer that was reimplemented into the go-getter library: progress bar, http download restart, checksuming from file, skip already downloaded files, symlinking, make a download cancellable by context.
* on windows if packer is running without symlinking rights and we are getting a local file, the file will be copied instead to avoid errors.
* added unit tests for step_download that are now CI tested on windows, mac & linux.
* files are now downloaded under cache dir `sha1(filename + "?checksum=" + checksum) + file_extension`
* since the output dir is based on the source url and the checksum, when the checksum fails, the file is auto deleted.
* a download file is protected and locked by a file lock,
* updated docs
* updated go modules and vendors
2019-03-13 07:11:58 -04:00
|
|
|
state.Put("error", fmt.Errorf("Downloading file: %v", errs))
|
|
|
|
return multistep.ActionHalt
|
|
|
|
}
|
2017-11-25 16:02:54 -05:00
|
|
|
|
Use the hashicorp/go-getter to download files
* removed packer.Cache and references since packer.Cache is never used except in the download step. The download step now uses the new func packer.CachePath(targetPath) for this, the behavior is the same.
* removed download code from packer that was reimplemented into the go-getter library: progress bar, http download restart, checksuming from file, skip already downloaded files, symlinking, make a download cancellable by context.
* on windows if packer is running without symlinking rights and we are getting a local file, the file will be copied instead to avoid errors.
* added unit tests for step_download that are now CI tested on windows, mac & linux.
* files are now downloaded under cache dir `sha1(filename + "?checksum=" + checksum) + file_extension`
* since the output dir is based on the source url and the checksum, when the checksum fails, the file is auto deleted.
* a download file is protected and locked by a file lock,
* updated docs
* updated go modules and vendors
2019-03-13 07:11:58 -04:00
|
|
|
func (s *StepDownload) download(ctx context.Context, ui packer.Ui, source string) (string, error) {
|
|
|
|
u, err := urlhelper.Parse(source)
|
|
|
|
if err != nil {
|
|
|
|
return "", fmt.Errorf("url parse: %s", err)
|
|
|
|
}
|
|
|
|
if checksum := u.Query().Get("checksum"); checksum != "" {
|
|
|
|
s.Checksum = checksum
|
|
|
|
}
|
|
|
|
if s.ChecksumType != "" && s.ChecksumType != "none" {
|
|
|
|
// add checksum to url query params as go getter will checksum for us
|
|
|
|
q := u.Query()
|
|
|
|
q.Set("checksum", s.ChecksumType+":"+s.Checksum)
|
|
|
|
u.RawQuery = q.Encode()
|
|
|
|
} else if s.Checksum != "" {
|
|
|
|
q := u.Query()
|
|
|
|
q.Set("checksum", s.Checksum)
|
|
|
|
u.RawQuery = q.Encode()
|
|
|
|
} else if s.ChecksumType != "none" {
|
|
|
|
return "", fmt.Errorf("Empty checksum")
|
|
|
|
}
|
2017-11-25 16:02:54 -05:00
|
|
|
|
Use the hashicorp/go-getter to download files
* removed packer.Cache and references since packer.Cache is never used except in the download step. The download step now uses the new func packer.CachePath(targetPath) for this, the behavior is the same.
* removed download code from packer that was reimplemented into the go-getter library: progress bar, http download restart, checksuming from file, skip already downloaded files, symlinking, make a download cancellable by context.
* on windows if packer is running without symlinking rights and we are getting a local file, the file will be copied instead to avoid errors.
* added unit tests for step_download that are now CI tested on windows, mac & linux.
* files are now downloaded under cache dir `sha1(filename + "?checksum=" + checksum) + file_extension`
* since the output dir is based on the source url and the checksum, when the checksum fails, the file is auto deleted.
* a download file is protected and locked by a file lock,
* updated docs
* updated go modules and vendors
2019-03-13 07:11:58 -04:00
|
|
|
targetPath := s.TargetPath
|
|
|
|
if targetPath == "" {
|
|
|
|
// store file under sha1(hash) if set
|
|
|
|
// hash can sometimes be a checksum url
|
|
|
|
// otherwise, use sha1(source_url)
|
|
|
|
var shaSum [20]byte
|
|
|
|
if s.Checksum != "" {
|
|
|
|
shaSum = sha1.Sum([]byte(s.Checksum))
|
|
|
|
} else {
|
|
|
|
shaSum = sha1.Sum([]byte(u.String()))
|
|
|
|
}
|
|
|
|
targetPath = hex.EncodeToString(shaSum[:])
|
|
|
|
if s.Extension != "" {
|
|
|
|
targetPath += "." + s.Extension
|
2013-08-15 14:05:36 -04:00
|
|
|
}
|
|
|
|
}
|
Use the hashicorp/go-getter to download files
* removed packer.Cache and references since packer.Cache is never used except in the download step. The download step now uses the new func packer.CachePath(targetPath) for this, the behavior is the same.
* removed download code from packer that was reimplemented into the go-getter library: progress bar, http download restart, checksuming from file, skip already downloaded files, symlinking, make a download cancellable by context.
* on windows if packer is running without symlinking rights and we are getting a local file, the file will be copied instead to avoid errors.
* added unit tests for step_download that are now CI tested on windows, mac & linux.
* files are now downloaded under cache dir `sha1(filename + "?checksum=" + checksum) + file_extension`
* since the output dir is based on the source url and the checksum, when the checksum fails, the file is auto deleted.
* a download file is protected and locked by a file lock,
* updated docs
* updated go modules and vendors
2019-03-13 07:11:58 -04:00
|
|
|
targetPath, err = packer.CachePath(targetPath)
|
|
|
|
if err != nil {
|
|
|
|
return "", fmt.Errorf("CachePath: %s", err)
|
|
|
|
}
|
|
|
|
lockFile := targetPath + ".lock"
|
|
|
|
|
|
|
|
log.Printf("Acquiring lock for: %s (%s)", u.String(), lockFile)
|
|
|
|
lock := flock.New(lockFile)
|
|
|
|
lock.Lock()
|
|
|
|
defer lock.Unlock()
|
|
|
|
|
|
|
|
wd, err := os.Getwd()
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("get working directory: %v", err)
|
|
|
|
// here we ignore the error in case the
|
|
|
|
// working directory is not needed.
|
|
|
|
// It would be better if the go-getter
|
|
|
|
// could guess it only in cases it is
|
|
|
|
// necessary.
|
2013-08-15 14:05:36 -04:00
|
|
|
}
|
|
|
|
|
Use the hashicorp/go-getter to download files
* removed packer.Cache and references since packer.Cache is never used except in the download step. The download step now uses the new func packer.CachePath(targetPath) for this, the behavior is the same.
* removed download code from packer that was reimplemented into the go-getter library: progress bar, http download restart, checksuming from file, skip already downloaded files, symlinking, make a download cancellable by context.
* on windows if packer is running without symlinking rights and we are getting a local file, the file will be copied instead to avoid errors.
* added unit tests for step_download that are now CI tested on windows, mac & linux.
* files are now downloaded under cache dir `sha1(filename + "?checksum=" + checksum) + file_extension`
* since the output dir is based on the source url and the checksum, when the checksum fails, the file is auto deleted.
* a download file is protected and locked by a file lock,
* updated docs
* updated go modules and vendors
2019-03-13 07:11:58 -04:00
|
|
|
ui.Say(fmt.Sprintf("Trying %s", u.String()))
|
|
|
|
gc := getter.Client{
|
|
|
|
Ctx: ctx,
|
|
|
|
Dst: targetPath,
|
|
|
|
Src: u.String(),
|
|
|
|
ProgressListener: ui,
|
|
|
|
Pwd: wd,
|
|
|
|
Dir: false,
|
|
|
|
}
|
2018-02-05 16:13:06 -05:00
|
|
|
|
Use the hashicorp/go-getter to download files
* removed packer.Cache and references since packer.Cache is never used except in the download step. The download step now uses the new func packer.CachePath(targetPath) for this, the behavior is the same.
* removed download code from packer that was reimplemented into the go-getter library: progress bar, http download restart, checksuming from file, skip already downloaded files, symlinking, make a download cancellable by context.
* on windows if packer is running without symlinking rights and we are getting a local file, the file will be copied instead to avoid errors.
* added unit tests for step_download that are now CI tested on windows, mac & linux.
* files are now downloaded under cache dir `sha1(filename + "?checksum=" + checksum) + file_extension`
* since the output dir is based on the source url and the checksum, when the checksum fails, the file is auto deleted.
* a download file is protected and locked by a file lock,
* updated docs
* updated go modules and vendors
2019-03-13 07:11:58 -04:00
|
|
|
switch err := gc.Get(); err.(type) {
|
|
|
|
case nil: // success !
|
|
|
|
ui.Say(fmt.Sprintf("%s => %s", u.String(), targetPath))
|
|
|
|
return targetPath, nil
|
|
|
|
case *getter.ChecksumError:
|
|
|
|
ui.Say(fmt.Sprintf("Checksum did not match, removing %s", targetPath))
|
|
|
|
if err := os.Remove(targetPath); err != nil {
|
|
|
|
ui.Error(fmt.Sprintf("Failed to remove cache file. Please remove manually: %s", targetPath))
|
2013-08-15 14:05:36 -04:00
|
|
|
}
|
Use the hashicorp/go-getter to download files
* removed packer.Cache and references since packer.Cache is never used except in the download step. The download step now uses the new func packer.CachePath(targetPath) for this, the behavior is the same.
* removed download code from packer that was reimplemented into the go-getter library: progress bar, http download restart, checksuming from file, skip already downloaded files, symlinking, make a download cancellable by context.
* on windows if packer is running without symlinking rights and we are getting a local file, the file will be copied instead to avoid errors.
* added unit tests for step_download that are now CI tested on windows, mac & linux.
* files are now downloaded under cache dir `sha1(filename + "?checksum=" + checksum) + file_extension`
* since the output dir is based on the source url and the checksum, when the checksum fails, the file is auto deleted.
* a download file is protected and locked by a file lock,
* updated docs
* updated go modules and vendors
2019-03-13 07:11:58 -04:00
|
|
|
return "", err
|
|
|
|
default:
|
|
|
|
ui.Say(fmt.Sprintf("Download failed %s", err))
|
|
|
|
return "", err
|
2013-08-15 14:05:36 -04:00
|
|
|
}
|
|
|
|
}
|
Use the hashicorp/go-getter to download files
* removed packer.Cache and references since packer.Cache is never used except in the download step. The download step now uses the new func packer.CachePath(targetPath) for this, the behavior is the same.
* removed download code from packer that was reimplemented into the go-getter library: progress bar, http download restart, checksuming from file, skip already downloaded files, symlinking, make a download cancellable by context.
* on windows if packer is running without symlinking rights and we are getting a local file, the file will be copied instead to avoid errors.
* added unit tests for step_download that are now CI tested on windows, mac & linux.
* files are now downloaded under cache dir `sha1(filename + "?checksum=" + checksum) + file_extension`
* since the output dir is based on the source url and the checksum, when the checksum fails, the file is auto deleted.
* a download file is protected and locked by a file lock,
* updated docs
* updated go modules and vendors
2019-03-13 07:11:58 -04:00
|
|
|
|
|
|
|
func (s *StepDownload) Cleanup(multistep.StateBag) {}
|