diff --git a/builder/virtualbox/common/config_test.go b/builder/virtualbox/common/config_test.go new file mode 100644 index 000000000..a84c51bc1 --- /dev/null +++ b/builder/virtualbox/common/config_test.go @@ -0,0 +1,15 @@ +package common + +import ( + "github.com/mitchellh/packer/packer" + "testing" +) + +func testConfigTemplate(t *testing.T) *packer.ConfigTemplate { + result, err := packer.NewConfigTemplate() + if err != nil { + t.Fatalf("err: %s", err) + } + + return result +} diff --git a/builder/virtualbox/common/output_config.go b/builder/virtualbox/common/output_config.go new file mode 100644 index 000000000..19be1ba00 --- /dev/null +++ b/builder/virtualbox/common/output_config.go @@ -0,0 +1,40 @@ +package common + +import ( + "fmt" + "github.com/mitchellh/packer/common" + "github.com/mitchellh/packer/packer" + "os" +) + +type OutputConfig struct { + OutputDir string `mapstructure:"output_directory"` +} + +func (c *OutputConfig) Prepare(t *packer.ConfigTemplate, pc *common.PackerConfig) []error { + if c.OutputDir == "" { + c.OutputDir = fmt.Sprintf("output-%s", pc.PackerBuildName) + } + + templates := map[string]*string{ + "output_directory": &c.OutputDir, + } + + errs := make([]error, 0) + for n, ptr := range templates { + var err error + *ptr, err = t.Process(*ptr, nil) + if err != nil { + errs = append(errs, fmt.Errorf("Error processing %s: %s", n, err)) + } + } + + if !pc.PackerForce { + if _, err := os.Stat(c.OutputDir); err == nil { + errs = append(errs, fmt.Errorf( + "Output directory '%s' already exists. It must not exist.", c.OutputDir)) + } + } + + return errs +} diff --git a/builder/virtualbox/common/output_config_test.go b/builder/virtualbox/common/output_config_test.go new file mode 100644 index 000000000..7fa039a16 --- /dev/null +++ b/builder/virtualbox/common/output_config_test.go @@ -0,0 +1,65 @@ +package common + +import ( + "github.com/mitchellh/packer/common" + "io/ioutil" + "os" + "testing" +) + +func TestOutputConfigPrepare(t *testing.T) { + c := new(OutputConfig) + if c.OutputDir != "" { + t.Fatalf("what: %s", c.OutputDir) + } + + pc := &common.PackerConfig{PackerBuildName: "foo"} + errs := c.Prepare(testConfigTemplate(t), pc) + if len(errs) > 0 { + t.Fatalf("err: %#v", errs) + } + + if c.OutputDir == "" { + t.Fatal("should have output dir") + } +} + +func TestOutputConfigPrepare_exists(t *testing.T) { + td, err := ioutil.TempDir("", "packer") + if err != nil { + t.Fatalf("err: %s", err) + } + defer os.RemoveAll(td) + + c := new(OutputConfig) + c.OutputDir = td + + pc := &common.PackerConfig{ + PackerBuildName: "foo", + PackerForce: false, + } + errs := c.Prepare(testConfigTemplate(t), pc) + if len(errs) == 0 { + t.Fatal("should have errors") + } +} + +func TestOutputConfigPrepare_forceExists(t *testing.T) { + td, err := ioutil.TempDir("", "packer") + if err != nil { + t.Fatalf("err: %s", err) + } + defer os.RemoveAll(td) + + c := new(OutputConfig) + c.OutputDir = td + + pc := &common.PackerConfig{ + PackerBuildName: "foo", + PackerForce: true, + } + errs := c.Prepare(testConfigTemplate(t), pc) + if len(errs) > 0 { + t.Fatal("should not have errors") + } +} diff --git a/builder/virtualbox/iso/builder.go b/builder/virtualbox/iso/builder.go index 11a275c90..fddd36b6d 100644 --- a/builder/virtualbox/iso/builder.go +++ b/builder/virtualbox/iso/builder.go @@ -29,7 +29,8 @@ type Builder struct { } type config struct { - common.PackerConfig `mapstructure:",squash"` + common.PackerConfig `mapstructure:",squash"` + vboxcommon.OutputConfig `mapstructure:",squash"` BootCommand []string `mapstructure:"boot_command"` DiskSize uint `mapstructure:"disk_size"` @@ -48,7 +49,6 @@ type config struct { ISOChecksum string `mapstructure:"iso_checksum"` ISOChecksumType string `mapstructure:"iso_checksum_type"` ISOUrls []string `mapstructure:"iso_urls"` - OutputDir string `mapstructure:"output_directory"` ShutdownCommand string `mapstructure:"shutdown_command"` SSHHostPortMin uint `mapstructure:"ssh_host_port_min"` SSHHostPortMax uint `mapstructure:"ssh_host_port_max"` @@ -85,6 +85,8 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { // Accumulate any errors and warnings errs := common.CheckUnusedConfig(md) + errs = packer.MultiErrorAppend( + errs, b.config.OutputConfig.Prepare(b.config.tpl, &b.config.PackerConfig)...) warnings := make([]string, 0) if b.config.DiskSize == 0 { @@ -119,10 +121,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { b.config.HTTPPortMax = 9000 } - if b.config.OutputDir == "" { - b.config.OutputDir = fmt.Sprintf("output-%s", b.config.PackerBuildName) - } - if b.config.RawBootWait == "" { b.config.RawBootWait = "10s" } @@ -165,7 +163,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { "iso_checksum": &b.config.ISOChecksum, "iso_checksum_type": &b.config.ISOChecksumType, "iso_url": &b.config.RawSingleISOUrl, - "output_directory": &b.config.OutputDir, "shutdown_command": &b.config.ShutdownCommand, "ssh_key_path": &b.config.SSHKeyPath, "ssh_password": &b.config.SSHPassword, @@ -300,14 +297,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { b.config.GuestAdditionsSHA256 = strings.ToLower(b.config.GuestAdditionsSHA256) } - if !b.config.PackerForce { - if _, err := os.Stat(b.config.OutputDir); err == nil { - errs = packer.MultiErrorAppend( - errs, - fmt.Errorf("Output directory '%s' already exists. It must not exist.", b.config.OutputDir)) - } - } - b.config.bootWait, err = time.ParseDuration(b.config.RawBootWait) if err != nil { errs = packer.MultiErrorAppend( diff --git a/builder/virtualbox/ovf/builder.go b/builder/virtualbox/ovf/builder.go index 5126ef1a9..18195644a 100644 --- a/builder/virtualbox/ovf/builder.go +++ b/builder/virtualbox/ovf/builder.go @@ -1,7 +1,13 @@ package ovf import ( - "github.com/mitchellh/packer/builder/virtualbox/common" + "errors" + "log" + + "github.com/mitchellh/multistep" + vboxcommon "github.com/mitchellh/packer/builder/virtualbox/common" + "github.com/mitchellh/packer/common" + "github.com/mitchellh/packer/packer" ) // Builder implements packer.Builder and builds the actual VirtualBox @@ -33,38 +39,36 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // Build the steps. steps := []multistep.Step{ - /* - new(stepDownloadGuestAdditions), - */ - /* + /* + new(stepDownloadGuestAdditions), + */ &vboxcommon.StepOutputDir{ Force: b.config.PackerForce, Path: b.config.OutputDir, }, - */ - /* - &common.StepCreateFloppy{ - Files: b.config.FloppyFiles, - }, - new(stepSuppressMessages), - new(stepAttachGuestAdditions), - new(stepAttachFloppy), - new(stepForwardSSH), - new(stepVBoxManage), - new(stepRun), - new(stepTypeBootCommand), - &common.StepConnectSSH{ - SSHAddress: sshAddress, - SSHConfig: sshConfig, - SSHWaitTimeout: b.config.sshWaitTimeout, - }, - new(stepUploadVersion), - new(stepUploadGuestAdditions), - new(common.StepProvision), - new(stepShutdown), - new(stepRemoveDevices), - new(stepExport), - */ + new(vboxcommon.StepSuppressMessages), + /* + &common.StepCreateFloppy{ + Files: b.config.FloppyFiles, + }, + new(stepAttachGuestAdditions), + new(stepAttachFloppy), + new(stepForwardSSH), + new(stepVBoxManage), + new(stepRun), + new(stepTypeBootCommand), + &common.StepConnectSSH{ + SSHAddress: sshAddress, + SSHConfig: sshConfig, + SSHWaitTimeout: b.config.sshWaitTimeout, + }, + new(stepUploadVersion), + new(stepUploadGuestAdditions), + new(common.StepProvision), + new(stepShutdown), + new(stepRemoveDevices), + new(stepExport), + */ } // Run the steps. @@ -92,11 +96,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe return nil, errors.New("Build was halted.") } - artifact := &Artifact{ - imageName: state.Get("image_name").(string), - driver: driver, - } - return artifact, nil + return vboxcommon.NewArtifact(b.config.OutputDir) } // Cancel. diff --git a/builder/virtualbox/ovf/config.go b/builder/virtualbox/ovf/config.go new file mode 100644 index 000000000..3064365e6 --- /dev/null +++ b/builder/virtualbox/ovf/config.go @@ -0,0 +1,40 @@ +package ovf + +import ( + vboxcommon "github.com/mitchellh/packer/builder/virtualbox/common" + "github.com/mitchellh/packer/common" + "github.com/mitchellh/packer/packer" +) + +// Config is the configuration structure for the builder. +type Config struct { + common.PackerConfig `mapstructure:",squash"` + vboxcommon.OutputConfig `mapstructure:",squash"` + + tpl *packer.ConfigTemplate +} + +func NewConfig(raws ...interface{}) (*Config, []string, error) { + c := new(Config) + md, err := common.DecodeConfig(c, raws...) + if err != nil { + return nil, nil, err + } + + c.tpl, err = packer.NewConfigTemplate() + if err != nil { + return nil, nil, err + } + c.tpl.UserVars = c.PackerUserVars + + // Prepare the errors + errs := common.CheckUnusedConfig(md) + errs = packer.MultiErrorAppend(errs, c.OutputConfig.Prepare(c.tpl, &c.PackerConfig)...) + + // Check for any errors. + if errs != nil && len(errs.Errors) > 0 { + return nil, nil, errs + } + + return c, nil, nil +} diff --git a/builder/virtualbox/ovf/config_test.go b/builder/virtualbox/ovf/config_test.go new file mode 100644 index 000000000..0981344e0 --- /dev/null +++ b/builder/virtualbox/ovf/config_test.go @@ -0,0 +1,9 @@ +package ovf + +import ( + "testing" +) + +func testConfig(t *testing.T) map[string]interface{} { + return map[string]interface{}{} +}