builder/virtualbox: support generic hash types [GH-175]
This commit is contained in:
parent
c62d7e2a3d
commit
3007498282
@ -2,6 +2,7 @@ package common
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/md5"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -46,6 +47,17 @@ type DownloadClient struct {
|
|||||||
downloader Downloader
|
downloader Downloader
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HashForType returns the Hash implementation for the given string
|
||||||
|
// type, or nil if the type is not supported.
|
||||||
|
func HashForType(t string) hash.Hash {
|
||||||
|
switch t {
|
||||||
|
case "md5":
|
||||||
|
return md5.New()
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NewDownloadClient returns a new DownloadClient for the given
|
// NewDownloadClient returns a new DownloadClient for the given
|
||||||
// configuration.
|
// configuration.
|
||||||
func NewDownloadClient(c *DownloadConfig) *DownloadClient {
|
func NewDownloadClient(c *DownloadConfig) *DownloadClient {
|
||||||
|
@ -40,3 +40,22 @@ func TestDownloadClient_VerifyChecksum(t *testing.T) {
|
|||||||
t.Fatal("didn't verify")
|
t.Fatal("didn't verify")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHashForType(t *testing.T) {
|
||||||
|
if h := HashForType("md5"); h == nil {
|
||||||
|
t.Fatalf("md5 hash is nil")
|
||||||
|
} else {
|
||||||
|
h.Write([]byte("foo"))
|
||||||
|
result := h.Sum(nil)
|
||||||
|
|
||||||
|
expected := "acbd18db4cc2f85cedef654fccc4a4d8"
|
||||||
|
actual := hex.EncodeToString(result)
|
||||||
|
if actual != expected {
|
||||||
|
t.Fatalf("bad hash: %s", actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if HashForType("fake") != nil {
|
||||||
|
t.Fatalf("fake hash is not nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -38,7 +38,8 @@ type config struct {
|
|||||||
HTTPDir string `mapstructure:"http_directory"`
|
HTTPDir string `mapstructure:"http_directory"`
|
||||||
HTTPPortMin uint `mapstructure:"http_port_min"`
|
HTTPPortMin uint `mapstructure:"http_port_min"`
|
||||||
HTTPPortMax uint `mapstructure:"http_port_max"`
|
HTTPPortMax uint `mapstructure:"http_port_max"`
|
||||||
ISOMD5 string `mapstructure:"iso_md5"`
|
ISOChecksum string `mapstructure:"iso_checksum"`
|
||||||
|
ISOChecksumType string `mapstructure:"iso_checksum_type"`
|
||||||
ISOUrl string `mapstructure:"iso_url"`
|
ISOUrl string `mapstructure:"iso_url"`
|
||||||
OutputDir string `mapstructure:"output_directory"`
|
OutputDir string `mapstructure:"output_directory"`
|
||||||
ShutdownCommand string `mapstructure:"shutdown_command"`
|
ShutdownCommand string `mapstructure:"shutdown_command"`
|
||||||
@ -155,10 +156,21 @@ func (b *Builder) Prepare(raws ...interface{}) error {
|
|||||||
errs = append(errs, errors.New("http_port_min must be less than http_port_max"))
|
errs = append(errs, errors.New("http_port_min must be less than http_port_max"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.config.ISOMD5 == "" {
|
if b.config.ISOChecksum == "" {
|
||||||
errs = append(errs, errors.New("Due to large file sizes, an iso_md5 is required"))
|
errs = append(errs, errors.New("Due to large file sizes, an iso_checksum is required"))
|
||||||
} else {
|
} else {
|
||||||
b.config.ISOMD5 = strings.ToLower(b.config.ISOMD5)
|
b.config.ISOChecksum = strings.ToLower(b.config.ISOChecksum)
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.config.ISOChecksumType == "" {
|
||||||
|
errs = append(errs, errors.New("The iso_checksum_type must be specified."))
|
||||||
|
} else {
|
||||||
|
b.config.ISOChecksumType = strings.ToLower(b.config.ISOChecksumType)
|
||||||
|
if h := common.HashForType(b.config.ISOChecksumType); h == nil {
|
||||||
|
errs = append(
|
||||||
|
errs,
|
||||||
|
fmt.Errorf("Unsupported checksum type: %s", b.config.ISOChecksumType))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.config.ISOUrl == "" {
|
if b.config.ISOUrl == "" {
|
||||||
|
@ -10,9 +10,10 @@ import (
|
|||||||
|
|
||||||
func testConfig() map[string]interface{} {
|
func testConfig() map[string]interface{} {
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
"iso_md5": "foo",
|
"iso_checksum": "foo",
|
||||||
"iso_url": "http://www.google.com/",
|
"iso_checksum_type": "md5",
|
||||||
"ssh_username": "foo",
|
"iso_url": "http://www.google.com/",
|
||||||
|
"ssh_username": "foo",
|
||||||
|
|
||||||
packer.BuildNameConfigKey: "foo",
|
packer.BuildNameConfigKey: "foo",
|
||||||
}
|
}
|
||||||
@ -283,26 +284,56 @@ func TestBuilderPrepare_InvalidKey(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuilderPrepare_ISOMD5(t *testing.T) {
|
func TestBuilderPrepare_ISOChecksum(t *testing.T) {
|
||||||
var b Builder
|
var b Builder
|
||||||
config := testConfig()
|
config := testConfig()
|
||||||
|
|
||||||
// Test bad
|
// Test bad
|
||||||
config["iso_md5"] = ""
|
config["iso_checksum"] = ""
|
||||||
err := b.Prepare(config)
|
err := b.Prepare(config)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("should have error")
|
t.Fatal("should have error")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test good
|
// Test good
|
||||||
config["iso_md5"] = "FOo"
|
config["iso_checksum"] = "FOo"
|
||||||
err = b.Prepare(config)
|
err = b.Prepare(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("should not have error: %s", err)
|
t.Fatalf("should not have error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.config.ISOMD5 != "foo" {
|
if b.config.ISOChecksum != "foo" {
|
||||||
t.Fatalf("should've lowercased: %s", b.config.ISOMD5)
|
t.Fatalf("should've lowercased: %s", b.config.ISOChecksum)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBuilderPrepare_ISOChecksumType(t *testing.T) {
|
||||||
|
var b Builder
|
||||||
|
config := testConfig()
|
||||||
|
|
||||||
|
// Test bad
|
||||||
|
config["iso_checksum_type"] = ""
|
||||||
|
err := b.Prepare(config)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("should have error")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test good
|
||||||
|
config["iso_checksum_type"] = "mD5"
|
||||||
|
err = b.Prepare(config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("should not have error: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.config.ISOChecksumType != "md5" {
|
||||||
|
t.Fatalf("should've lowercased: %s", b.config.ISOChecksumType)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test unknown
|
||||||
|
config["iso_checksum_type"] = "fake"
|
||||||
|
err = b.Prepare(config)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("should have error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package virtualbox
|
package virtualbox
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/md5"
|
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
@ -33,7 +32,7 @@ func (s *stepDownloadISO) Run(state map[string]interface{}) multistep.StepAction
|
|||||||
config := state["config"].(*config)
|
config := state["config"].(*config)
|
||||||
ui := state["ui"].(packer.Ui)
|
ui := state["ui"].(packer.Ui)
|
||||||
|
|
||||||
checksum, err := hex.DecodeString(config.ISOMD5)
|
checksum, err := hex.DecodeString(config.ISOChecksum)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
state["error"] = fmt.Errorf("Error parsing checksum: %s", err)
|
state["error"] = fmt.Errorf("Error parsing checksum: %s", err)
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
@ -47,7 +46,7 @@ func (s *stepDownloadISO) Run(state map[string]interface{}) multistep.StepAction
|
|||||||
Url: config.ISOUrl,
|
Url: config.ISOUrl,
|
||||||
TargetPath: cachePath,
|
TargetPath: cachePath,
|
||||||
CopyFile: false,
|
CopyFile: false,
|
||||||
Hash: md5.New(),
|
Hash: common.HashForType(config.ISOChecksumType),
|
||||||
Checksum: checksum,
|
Checksum: checksum,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user