diff --git a/builder/virtualbox/builder.go b/builder/virtualbox/builder.go index b53e4bb73..051d0cfe3 100644 --- a/builder/virtualbox/builder.go +++ b/builder/virtualbox/builder.go @@ -20,6 +20,7 @@ type Builder struct { type config struct { GuestOSType string `mapstructure:"guest_os_type"` OutputDir string `mapstructure:"output_directory"` + VMName string `mapstructure:"vm_name"` } func (b *Builder) Prepare(raw interface{}) error { @@ -36,6 +37,10 @@ func (b *Builder) Prepare(raw interface{}) error { b.config.OutputDir = "virtualbox" } + if b.config.VMName == "" { + b.config.VMName = "packer" + } + errs := make([]error, 0) b.driver, err = b.newDriver() @@ -54,6 +59,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) packer steps := []multistep.Step{ new(stepPrepareOutputDir), new(stepSuppressMessages), + new(stepCreateVM), } // Setup the state bag diff --git a/builder/virtualbox/builder_test.go b/builder/virtualbox/builder_test.go index 904e8f847..143490e09 100644 --- a/builder/virtualbox/builder_test.go +++ b/builder/virtualbox/builder_test.go @@ -32,4 +32,8 @@ func TestBuilderPrepare_Defaults(t *testing.T) { if b.config.OutputDir != "virtualbox" { t.Errorf("bad output dir: %s", b.config.OutputDir) } + + if b.config.VMName != "packer" { + t.Errorf("bad vm name: %s", b.config.VMName) + } } diff --git a/builder/virtualbox/driver.go b/builder/virtualbox/driver.go index 70a893d66..b6abd3473 100644 --- a/builder/virtualbox/driver.go +++ b/builder/virtualbox/driver.go @@ -14,6 +14,9 @@ type Driver interface { // suppress any annoying popups from VirtualBox. SuppressMessages() error + // VBoxManage executes the given VBoxManage command + VBoxManage(...string) error + // Verify checks to make sure that this driver should function // properly. If there is any indication the driver can't function, // this will return an error. @@ -34,7 +37,7 @@ func (d *VBox42Driver) SuppressMessages() error { } for k, v := range extraData { - if err := d.vboxmanage("setextradata", "global", k, v); err != nil { + if err := d.VBoxManage("setextradata", "global", k, v); err != nil { return err } } @@ -42,11 +45,7 @@ func (d *VBox42Driver) SuppressMessages() error { return nil } -func (d *VBox42Driver) Verify() error { - return nil -} - -func (d *VBox42Driver) vboxmanage(args ...string) error { +func (d *VBox42Driver) VBoxManage(args ...string) error { log.Printf("Executing VBoxManage: %#v", args) cmd := exec.Command(d.VBoxManagePath, args...) if err := cmd.Run(); err != nil { @@ -55,3 +54,7 @@ func (d *VBox42Driver) vboxmanage(args ...string) error { return nil } + +func (d *VBox42Driver) Verify() error { + return nil +} diff --git a/builder/virtualbox/step_create_vm.go b/builder/virtualbox/step_create_vm.go new file mode 100644 index 000000000..a27dbd087 --- /dev/null +++ b/builder/virtualbox/step_create_vm.go @@ -0,0 +1,61 @@ +package virtualbox + +import ( + "fmt" + "github.com/mitchellh/multistep" + "github.com/mitchellh/packer/packer" + "time" +) + +// This step creates the actual virtual machine. +type stepCreateVM struct{ + vmName string +} + +func (s *stepCreateVM) Run(state map[string]interface{}) multistep.StepAction { + config := state["config"].(*config) + driver := state["driver"].(Driver) + ui := state["ui"].(packer.Ui) + + name := config.VMName + + commands := make([][]string, 4) + commands[0] = []string{"createvm", "--name", name, "--ostype", config.GuestOSType, "--register"} + commands[1] = []string{ + "modifyvm", name, + "--boot1", "disk", "--boot2", "dvd", "--boot3", "none", "--boot4", "none", + } + commands[2] = []string{"modifyvm", name, "--cpus", "1"} + commands[3] = []string{"modifyvm", name, "--memory", "512"} + + ui.Say("Creating virtual machine...") + for _, command := range commands { + err := driver.VBoxManage(command...) + if err != nil { + ui.Error(fmt.Sprintf("Error creating VM: %s", err)) + return multistep.ActionHalt + } + + // Set the VM name propery on the first command + if s.vmName == "" { + s.vmName = name + } + } + + time.Sleep(15 * time.Second) + return multistep.ActionContinue +} + +func (s *stepCreateVM) Cleanup(state map[string]interface{}) { + if s.vmName == "" { + return + } + + driver := state["driver"].(Driver) + ui := state["ui"].(packer.Ui) + + ui.Say("Unregistering and deleting virtual machine...") + if err := driver.VBoxManage("unregistervm", s.vmName, "--delete"); err != nil { + ui.Error(fmt.Sprintf("Error deleting virtual machine: %s", err)) + } +}