Commit dd767c9d authored by Mitchell Hashimoto's avatar Mitchell Hashimoto

builder/virtualbox/ovf: StepImport to import an OVF

parent 0de7bb33
...@@ -19,6 +19,12 @@ type Driver interface { ...@@ -19,6 +19,12 @@ type Driver interface {
// Create a SATA controller. // Create a SATA controller.
CreateSATAController(vm string, controller string) error CreateSATAController(vm string, controller string) error
// Delete a VM by name
Delete(string) error
// Import a VM
Import(string, string) error
// Checks if the VM with the given name is running. // Checks if the VM with the given name is running.
IsRunning(string) (bool, error) IsRunning(string) (bool, error)
......
...@@ -36,6 +36,20 @@ func (d *VBox42Driver) CreateSATAController(vmName string, name string) error { ...@@ -36,6 +36,20 @@ func (d *VBox42Driver) CreateSATAController(vmName string, name string) error {
return d.VBoxManage(command...) return d.VBoxManage(command...)
} }
func (d *VBox42Driver) Delete(name string) error {
return d.VBoxManage("unregistervm", name, "--delete")
}
func (d *VBox42Driver) Import(name, path string) error {
args := []string{
"import", path,
"--vsys", "0",
"--vmname", name,
}
return d.VBoxManage(args...)
}
func (d *VBox42Driver) IsRunning(name string) (bool, error) { func (d *VBox42Driver) IsRunning(name string) (bool, error) {
var stdout bytes.Buffer var stdout bytes.Buffer
......
...@@ -9,6 +9,15 @@ type DriverMock struct { ...@@ -9,6 +9,15 @@ type DriverMock struct {
CreateSATAControllerController string CreateSATAControllerController string
CreateSATAControllerErr error CreateSATAControllerErr error
DeleteCalled bool
DeleteName string
DeleteErr error
ImportCalled bool
ImportName string
ImportPath string
ImportErr error
IsRunningName string IsRunningName string
IsRunningReturn bool IsRunningReturn bool
IsRunningErr error IsRunningErr error
...@@ -36,6 +45,19 @@ func (d *DriverMock) CreateSATAController(vm string, controller string) error { ...@@ -36,6 +45,19 @@ func (d *DriverMock) CreateSATAController(vm string, controller string) error {
return d.CreateSATAControllerErr return d.CreateSATAControllerErr
} }
func (d *DriverMock) Delete(name string) error {
d.DeleteCalled = true
d.DeleteName = name
return d.DeleteErr
}
func (d *DriverMock) Import(name, path string) error {
d.ImportCalled = true
d.ImportName = name
d.ImportPath = path
return d.ImportErr
}
func (d *DriverMock) IsRunning(name string) (bool, error) { func (d *DriverMock) IsRunning(name string) (bool, error) {
d.Lock() d.Lock()
defer d.Unlock() defer d.Unlock()
......
...@@ -39,9 +39,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ...@@ -39,9 +39,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
// Build the steps. // Build the steps.
steps := []multistep.Step{ steps := []multistep.Step{
/* &StepImport{
new(stepDownloadGuestAdditions), SourcePath: b.config.SourcePath,
*/ },
&vboxcommon.StepOutputDir{ &vboxcommon.StepOutputDir{
Force: b.config.PackerForce, Force: b.config.PackerForce,
Path: b.config.OutputDir, Path: b.config.OutputDir,
......
...@@ -18,6 +18,8 @@ type Config struct { ...@@ -18,6 +18,8 @@ type Config struct {
vboxcommon.VBoxManageConfig `mapstructure:",squash"` vboxcommon.VBoxManageConfig `mapstructure:",squash"`
vboxcommon.VBoxVersionConfig `mapstructure:",squash"` vboxcommon.VBoxVersionConfig `mapstructure:",squash"`
SourcePath string `mapstructure:"source_path"`
tpl *packer.ConfigTemplate tpl *packer.ConfigTemplate
} }
......
package ovf
import (
"fmt"
"github.com/mitchellh/multistep"
vboxcommon "github.com/mitchellh/packer/builder/virtualbox/common"
"github.com/mitchellh/packer/packer"
)
// This step imports an OVF VM into VirtualBox.
type StepImport struct {
Name string
SourcePath string
vmName string
}
func (s *StepImport) Run(state multistep.StateBag) multistep.StepAction {
driver := state.Get("driver").(vboxcommon.Driver)
ui := state.Get("ui").(packer.Ui)
ui.Say(fmt.Sprintf("Importing VM: %s", s.SourcePath))
if err := driver.Import(s.Name, s.SourcePath); err != nil {
err := fmt.Errorf("Error importing VM: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
s.vmName = s.Name
state.Put("vmName", s.Name)
return multistep.ActionContinue
}
func (s *StepImport) Cleanup(state multistep.StateBag) {
if s.vmName == "" {
return
}
driver := state.Get("driver").(vboxcommon.Driver)
ui := state.Get("ui").(packer.Ui)
ui.Say("Unregistering and deleting imported VM...")
if err := driver.Delete(s.vmName); err != nil {
ui.Error(fmt.Sprintf("Error deleting VM: %s", err))
}
}
package ovf
import (
"github.com/mitchellh/multistep"
vboxcommon "github.com/mitchellh/packer/builder/virtualbox/common"
"testing"
)
func TestStepImport_impl(t *testing.T) {
var _ multistep.Step = new(StepImport)
}
func TestStepImport(t *testing.T) {
state := testState(t)
step := new(StepImport)
step.Name = "bar"
step.SourcePath = "foo"
driver := state.Get("driver").(*vboxcommon.DriverMock)
// Test the run
if action := step.Run(state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
}
if _, ok := state.GetOk("error"); ok {
t.Fatal("should NOT have error")
}
// Test driver
if !driver.ImportCalled {
t.Fatal("import should be called")
}
if driver.ImportName != step.Name {
t.Fatalf("bad: %#v", driver.ImportName)
}
if driver.ImportPath != step.SourcePath {
t.Fatalf("bad: %#v", driver.ImportPath)
}
// Test output state
if name, ok := state.GetOk("vmName"); !ok {
t.Fatal("vmName should be set")
} else if name != "bar" {
t.Fatalf("bad: %#v", name)
}
// Test cleanup
step.Cleanup(state)
if !driver.DeleteCalled {
t.Fatal("delete should be called")
}
if driver.DeleteName != "bar" {
t.Fatalf("bad: %#v", driver.DeleteName)
}
}
package ovf
import (
"bytes"
"github.com/mitchellh/multistep"
vboxcommon "github.com/mitchellh/packer/builder/virtualbox/common"
"github.com/mitchellh/packer/packer"
"testing"
)
func testState(t *testing.T) multistep.StateBag {
state := new(multistep.BasicStateBag)
state.Put("driver", new(vboxcommon.DriverMock))
state.Put("ui", &packer.BasicUi{
Reader: new(bytes.Buffer),
Writer: new(bytes.Buffer),
})
return state
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment