diff --git a/builder/virtualbox/step_download_guest_additions.go b/builder/virtualbox/step_download_guest_additions.go index 2ff2b5d31..2da7d63ed 100644 --- a/builder/virtualbox/step_download_guest_additions.go +++ b/builder/virtualbox/step_download_guest_additions.go @@ -2,8 +2,6 @@ package virtualbox import ( "bytes" - "crypto/sha256" - "encoding/hex" "fmt" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/common" @@ -34,7 +32,6 @@ type stepDownloadGuestAdditions struct{} func (s *stepDownloadGuestAdditions) Run(state map[string]interface{}) multistep.StepAction { var action multistep.StepAction - cache := state["cache"].(packer.Cache) driver := state["driver"].(Driver) ui := state["ui"].(packer.Ui) config := state["config"].(*config) @@ -65,12 +62,6 @@ func (s *stepDownloadGuestAdditions) Run(state map[string]interface{}) multistep } } - checksumBytes, err := hex.DecodeString(checksum) - if err != nil { - state["error"] = fmt.Errorf("Couldn't decode checksum into bytes: %s", checksum) - return multistep.ActionHalt - } - // Use the provided source (URL or file path) or generate it url := config.GuestAdditionsURL if url != "" { @@ -102,21 +93,15 @@ func (s *stepDownloadGuestAdditions) Run(state map[string]interface{}) multistep log.Printf("Guest additions URL: %s", url) - log.Printf("Acquiring lock to download the guest additions ISO.") - cachePath := cache.Lock(url) - defer cache.Unlock(url) - - downloadConfig := &common.DownloadConfig{ - Url: url, - TargetPath: cachePath, - Hash: sha256.New(), - Checksum: checksumBytes, + downStep := &common.StepDownload{ + Checksum: checksum, + ChecksumType: "sha256", + Description: "Guest additions", + ResultKey: "guest_additions_path", + Url: []string{url}, } - download := common.NewDownloadClient(downloadConfig) - ui.Say("Downloading VirtualBox guest additions. Progress will be shown periodically.") - state["guest_additions_path"], action = s.progressDownload(download, state) - return action + return downStep.Run(state) } func (s *stepDownloadGuestAdditions) Cleanup(state map[string]interface{}) {} @@ -165,7 +150,9 @@ DownloadWaitLoop: func (s *stepDownloadGuestAdditions) downloadAdditionsSHA256(state map[string]interface{}, additionsVersion string, additionsName string) (string, multistep.StepAction) { // First things first, we get the list of checksums for the files available // for this version. - checksumsUrl := fmt.Sprintf("http://download.virtualbox.org/virtualbox/%s/SHA256SUMS", additionsVersion) + checksumsUrl := fmt.Sprintf( + "http://download.virtualbox.org/virtualbox/%s/SHA256SUMS", + additionsVersion) checksumsFile, err := ioutil.TempFile("", "packer") if err != nil { @@ -175,25 +162,23 @@ func (s *stepDownloadGuestAdditions) downloadAdditionsSHA256(state map[string]in return "", multistep.ActionHalt } defer os.Remove(checksumsFile.Name()) - checksumsFile.Close() - downloadConfig := &common.DownloadConfig{ - Url: checksumsUrl, - TargetPath: checksumsFile.Name(), - Hash: nil, + downStep := &common.StepDownload{ + Description: "Guest additions checksums", + ResultKey: "guest_additions_checksums_path", + TargetPath: checksumsFile.Name(), + Url: []string{checksumsUrl}, } - log.Printf("Downloading guest addition checksums: %s", checksumsUrl) - download := common.NewDownloadClient(downloadConfig) - checksumsPath, action := s.progressDownload(download, state) - if action != multistep.ActionContinue { + action := downStep.Run(state) + if action == multistep.ActionHalt { return "", action } // Next, we find the checksum for the file we're looking to download. // It is an error if the checksum cannot be found. - checksumsF, err := os.Open(checksumsPath) + checksumsF, err := os.Open(state["guest_additions_checksums_path"].(string)) if err != nil { state["error"] = fmt.Errorf("Error opening guest addition checksums: %s", err) return "", multistep.ActionHalt @@ -223,7 +208,8 @@ func (s *stepDownloadGuestAdditions) downloadAdditionsSHA256(state map[string]in } if checksum == "" { - state["error"] = fmt.Errorf("The checksum for the file '%s' could not be found.", additionsName) + state["error"] = fmt.Errorf( + "The checksum for the file '%s' could not be found.", additionsName) return "", multistep.ActionHalt } diff --git a/common/step_download.go b/common/step_download.go index 9f97a8eac..f5aff21a6 100644 --- a/common/step_download.go +++ b/common/step_download.go @@ -29,6 +29,10 @@ type StepDownload struct { // into the state. ResultKey string + // The path where the result should go, otherwise it goes to the + // cache directory. + TargetPath string + // A list of URLs to attempt to download this thing. Url []string } @@ -37,10 +41,14 @@ func (s *StepDownload) Run(state map[string]interface{}) multistep.StepAction { cache := state["cache"].(packer.Cache) ui := state["ui"].(packer.Ui) - checksum, err := hex.DecodeString(s.Checksum) - if err != nil { - state["error"] = fmt.Errorf("Error parsing checksum: %s", err) - return multistep.ActionHalt + var checksum []byte + if s.Checksum != "" { + var err error + checksum, err = hex.DecodeString(s.Checksum) + if err != nil { + state["error"] = fmt.Errorf("Error parsing checksum: %s", err) + return multistep.ActionHalt + } } ui.Say(fmt.Sprintf("Downloading or copying %s", s.Description)) @@ -48,13 +56,17 @@ func (s *StepDownload) Run(state map[string]interface{}) multistep.StepAction { var finalPath string for _, url := range s.Url { ui.Message(fmt.Sprintf("Downloading or copying: %s", url)) - log.Printf("Acquiring lock to download: %s", url) - cachePath := cache.Lock(url) - defer cache.Unlock(url) + + targetPath := s.TargetPath + if targetPath == "" { + log.Printf("Acquiring lock to download: %s", url) + targetPath = cache.Lock(url) + defer cache.Unlock(url) + } config := &DownloadConfig{ Url: url, - TargetPath: cachePath, + TargetPath: targetPath, CopyFile: false, Hash: HashForType(s.ChecksumType), Checksum: checksum,