diff --git a/builder/virtualbox/iso/step_vboxmanage.go b/builder/virtualbox/common/step_vboxmanage.go similarity index 69% rename from builder/virtualbox/iso/step_vboxmanage.go rename to builder/virtualbox/common/step_vboxmanage.go index 62b8c0340..beb55da03 100644 --- a/builder/virtualbox/iso/step_vboxmanage.go +++ b/builder/virtualbox/common/step_vboxmanage.go @@ -1,9 +1,8 @@ -package iso +package common import ( "fmt" "github.com/mitchellh/multistep" - vboxcommon "github.com/mitchellh/packer/builder/virtualbox/common" "github.com/mitchellh/packer/packer" "strings" ) @@ -16,17 +15,22 @@ type commandTemplate struct { // template. // // Uses: +// driver Driver +// ui packer.Ui +// vmName string // // Produces: -type stepVBoxManage struct{} +type StepVBoxManage struct { + Commands [][]string + Tpl *packer.ConfigTemplate +} -func (s *stepVBoxManage) Run(state multistep.StateBag) multistep.StepAction { - config := state.Get("config").(*config) - driver := state.Get("driver").(vboxcommon.Driver) +func (s *StepVBoxManage) Run(state multistep.StateBag) multistep.StepAction { + driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) - if len(config.VBoxManage) > 0 { + if len(s.Commands) > 0 { ui.Say("Executing custom VBoxManage commands...") } @@ -34,13 +38,13 @@ func (s *stepVBoxManage) Run(state multistep.StateBag) multistep.StepAction { Name: vmName, } - for _, originalCommand := range config.VBoxManage { + for _, originalCommand := range s.Commands { command := make([]string, len(originalCommand)) copy(command, originalCommand) for i, arg := range command { var err error - command[i], err = config.tpl.Process(arg, tplData) + command[i], err = s.Tpl.Process(arg, tplData) if err != nil { err := fmt.Errorf("Error preparing vboxmanage command: %s", err) state.Put("error", err) @@ -61,4 +65,4 @@ func (s *stepVBoxManage) Run(state multistep.StateBag) multistep.StepAction { return multistep.ActionContinue } -func (s *stepVBoxManage) Cleanup(state multistep.StateBag) {} +func (s *StepVBoxManage) Cleanup(state multistep.StateBag) {} diff --git a/builder/virtualbox/common/vboxmanage_config.go b/builder/virtualbox/common/vboxmanage_config.go new file mode 100644 index 000000000..b864a0422 --- /dev/null +++ b/builder/virtualbox/common/vboxmanage_config.go @@ -0,0 +1,28 @@ +package common + +import ( + "fmt" + "github.com/mitchellh/packer/packer" +) + +type VBoxManageConfig struct { + VBoxManage [][]string `mapstructure:"vboxmanage"` +} + +func (c *VBoxManageConfig) Prepare(t *packer.ConfigTemplate) []error { + if c.VBoxManage == nil { + c.VBoxManage = make([][]string, 0) + } + + errs := make([]error, 0) + for i, args := range c.VBoxManage { + for j, arg := range args { + if err := t.Validate(arg); err != nil { + errs = append(errs, + fmt.Errorf("Error processing vboxmanage[%d][%d]: %s", i, j, err)) + } + } + } + + return errs +} diff --git a/builder/virtualbox/common/vboxmanage_config_test.go b/builder/virtualbox/common/vboxmanage_config_test.go new file mode 100644 index 000000000..d089b977a --- /dev/null +++ b/builder/virtualbox/common/vboxmanage_config_test.go @@ -0,0 +1,37 @@ +package common + +import ( + "reflect" + "testing" +) + +func TestVBoxManageConfigPrepare_VBoxManage(t *testing.T) { + // Test with empty + c := new(VBoxManageConfig) + errs := c.Prepare(testConfigTemplate(t)) + if len(errs) > 0 { + t.Fatalf("err: %#v", errs) + } + + if !reflect.DeepEqual(c.VBoxManage, [][]string{}) { + t.Fatalf("bad: %#v", c.VBoxManage) + } + + // Test with a good one + c = new(VBoxManageConfig) + c.VBoxManage = [][]string{ + {"foo", "bar", "baz"}, + } + errs = c.Prepare(testConfigTemplate(t)) + if len(errs) > 0 { + t.Fatalf("err: %#v", errs) + } + + expected := [][]string{ + []string{"foo", "bar", "baz"}, + } + + if !reflect.DeepEqual(c.VBoxManage, expected) { + t.Fatalf("bad: %#v", c.VBoxManage) + } +} diff --git a/builder/virtualbox/iso/builder.go b/builder/virtualbox/iso/builder.go index 0a7a21426..e5430bc1c 100644 --- a/builder/virtualbox/iso/builder.go +++ b/builder/virtualbox/iso/builder.go @@ -28,31 +28,31 @@ type Builder struct { } type config struct { - common.PackerConfig `mapstructure:",squash"` - vboxcommon.FloppyConfig `mapstructure:",squash"` - vboxcommon.OutputConfig `mapstructure:",squash"` - vboxcommon.SSHConfig `mapstructure:",squash"` + common.PackerConfig `mapstructure:",squash"` + vboxcommon.FloppyConfig `mapstructure:",squash"` + vboxcommon.OutputConfig `mapstructure:",squash"` + vboxcommon.SSHConfig `mapstructure:",squash"` + vboxcommon.VBoxManageConfig `mapstructure:",squash"` - BootCommand []string `mapstructure:"boot_command"` - DiskSize uint `mapstructure:"disk_size"` - Format string `mapstructure:"format"` - GuestAdditionsMode string `mapstructure:"guest_additions_mode"` - GuestAdditionsPath string `mapstructure:"guest_additions_path"` - GuestAdditionsURL string `mapstructure:"guest_additions_url"` - GuestAdditionsSHA256 string `mapstructure:"guest_additions_sha256"` - GuestOSType string `mapstructure:"guest_os_type"` - HardDriveInterface string `mapstructure:"hard_drive_interface"` - Headless bool `mapstructure:"headless"` - HTTPDir string `mapstructure:"http_directory"` - HTTPPortMin uint `mapstructure:"http_port_min"` - HTTPPortMax uint `mapstructure:"http_port_max"` - ISOChecksum string `mapstructure:"iso_checksum"` - ISOChecksumType string `mapstructure:"iso_checksum_type"` - ISOUrls []string `mapstructure:"iso_urls"` - ShutdownCommand string `mapstructure:"shutdown_command"` - VBoxVersionFile string `mapstructure:"virtualbox_version_file"` - VBoxManage [][]string `mapstructure:"vboxmanage"` - VMName string `mapstructure:"vm_name"` + BootCommand []string `mapstructure:"boot_command"` + DiskSize uint `mapstructure:"disk_size"` + Format string `mapstructure:"format"` + GuestAdditionsMode string `mapstructure:"guest_additions_mode"` + GuestAdditionsPath string `mapstructure:"guest_additions_path"` + GuestAdditionsURL string `mapstructure:"guest_additions_url"` + GuestAdditionsSHA256 string `mapstructure:"guest_additions_sha256"` + GuestOSType string `mapstructure:"guest_os_type"` + HardDriveInterface string `mapstructure:"hard_drive_interface"` + Headless bool `mapstructure:"headless"` + HTTPDir string `mapstructure:"http_directory"` + HTTPPortMin uint `mapstructure:"http_port_min"` + HTTPPortMax uint `mapstructure:"http_port_max"` + ISOChecksum string `mapstructure:"iso_checksum"` + ISOChecksumType string `mapstructure:"iso_checksum_type"` + ISOUrls []string `mapstructure:"iso_urls"` + ShutdownCommand string `mapstructure:"shutdown_command"` + VBoxVersionFile string `mapstructure:"virtualbox_version_file"` + VMName string `mapstructure:"vm_name"` RawBootWait string `mapstructure:"boot_wait"` RawSingleISOUrl string `mapstructure:"iso_url"` @@ -81,6 +81,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend( errs, b.config.OutputConfig.Prepare(b.config.tpl, &b.config.PackerConfig)...) errs = packer.MultiErrorAppend(errs, b.config.SSHConfig.Prepare(b.config.tpl)...) + errs = packer.MultiErrorAppend(errs, b.config.VBoxManageConfig.Prepare(b.config.tpl)...) warnings := make([]string, 0) if b.config.DiskSize == 0 { @@ -115,10 +116,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { b.config.RawBootWait = "10s" } - if b.config.VBoxManage == nil { - b.config.VBoxManage = make([][]string, 0) - } - if b.config.VBoxVersionFile == "" { b.config.VBoxVersionFile = ".vbox_version" } @@ -277,15 +274,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs, fmt.Errorf("Failed parsing shutdown_timeout: %s", err)) } - for i, args := range b.config.VBoxManage { - for j, arg := range args { - if err := b.config.tpl.Validate(arg); err != nil { - errs = packer.MultiErrorAppend(errs, - fmt.Errorf("Error processing vboxmanage[%d][%d]: %s", i, j, err)) - } - } - } - // Warnings if b.config.ShutdownCommand == "" { warnings = append(warnings, @@ -335,7 +323,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe HostPortMin: b.config.SSHHostPortMin, HostPortMax: b.config.SSHHostPortMax, }, - new(stepVBoxManage), + &vboxcommon.StepVBoxManage{ + Commands: b.config.VBoxManage, + }, new(stepRun), new(stepTypeBootCommand), &common.StepConnectSSH{ diff --git a/builder/virtualbox/iso/builder_test.go b/builder/virtualbox/iso/builder_test.go index 80e7754eb..b8e2469a8 100644 --- a/builder/virtualbox/iso/builder_test.go +++ b/builder/virtualbox/iso/builder_test.go @@ -2,8 +2,6 @@ package iso import ( "github.com/mitchellh/packer/packer" - "io/ioutil" - "os" "reflect" "testing" ) @@ -575,47 +573,6 @@ func TestBuilderPrepare_ShutdownTimeout(t *testing.T) { } } -func TestBuilderPrepare_VBoxManage(t *testing.T) { - var b Builder - config := testConfig() - - // Test with empty - delete(config, "vboxmanage") - warns, err := b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err != nil { - t.Fatalf("err: %s", err) - } - - if !reflect.DeepEqual(b.config.VBoxManage, [][]string{}) { - t.Fatalf("bad: %#v", b.config.VBoxManage) - } - - // Test with a good one - config["vboxmanage"] = [][]interface{}{ - []interface{}{"foo", "bar", "baz"}, - } - - b = Builder{} - warns, err = b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err != nil { - t.Fatalf("should not have error: %s", err) - } - - expected := [][]string{ - []string{"foo", "bar", "baz"}, - } - - if !reflect.DeepEqual(b.config.VBoxManage, expected) { - t.Fatalf("bad: %#v", b.config.VBoxManage) - } -} - func TestBuilderPrepare_VBoxVersionFile(t *testing.T) { var b Builder config := testConfig() diff --git a/builder/virtualbox/ovf/builder.go b/builder/virtualbox/ovf/builder.go index 2484248f4..1afcdc1c5 100644 --- a/builder/virtualbox/ovf/builder.go +++ b/builder/virtualbox/ovf/builder.go @@ -59,8 +59,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe HostPortMin: b.config.SSHHostPortMin, HostPortMax: b.config.SSHHostPortMax, }, + &vboxcommon.StepVBoxManage{ + Commands: b.config.VBoxManage, + }, /* - new(stepVBoxManage), new(stepRun), */ &common.StepConnectSSH{ @@ -71,7 +73,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe /* new(stepUploadVersion), new(stepUploadGuestAdditions), - new(common.StepProvision), + */ + new(common.StepProvision), + /* new(stepShutdown), new(stepRemoveDevices), new(stepExport), diff --git a/builder/virtualbox/ovf/config.go b/builder/virtualbox/ovf/config.go index 614c56cf9..3ac1c80e0 100644 --- a/builder/virtualbox/ovf/config.go +++ b/builder/virtualbox/ovf/config.go @@ -8,10 +8,11 @@ import ( // Config is the configuration structure for the builder. type Config struct { - common.PackerConfig `mapstructure:",squash"` - vboxcommon.FloppyConfig `mapstructure:",squash"` - vboxcommon.OutputConfig `mapstructure:",squash"` - vboxcommon.SSHConfig `mapstructure:",squash"` + common.PackerConfig `mapstructure:",squash"` + vboxcommon.FloppyConfig `mapstructure:",squash"` + vboxcommon.OutputConfig `mapstructure:",squash"` + vboxcommon.SSHConfig `mapstructure:",squash"` + vboxcommon.VBoxManageConfig `mapstructure:",squash"` tpl *packer.ConfigTemplate } @@ -34,6 +35,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { errs = packer.MultiErrorAppend(errs, c.FloppyConfig.Prepare(c.tpl)...) errs = packer.MultiErrorAppend(errs, c.OutputConfig.Prepare(c.tpl, &c.PackerConfig)...) errs = packer.MultiErrorAppend(errs, c.SSHConfig.Prepare(c.tpl)...) + errs = packer.MultiErrorAppend(errs, c.VBoxManageConfig.Prepare(c.tpl)...) // Check for any errors. if errs != nil && len(errs.Errors) > 0 {