diff --git a/builder/parallels/common/step_prepare_parallels_tools.go b/builder/parallels/common/step_prepare_parallels_tools.go new file mode 100644 index 000000000..752268fd7 --- /dev/null +++ b/builder/parallels/common/step_prepare_parallels_tools.go @@ -0,0 +1,47 @@ +package common + +import ( + "fmt" + "github.com/mitchellh/multistep" + "os" +) + +// This step prepares parameters related to Parallels Tools. +// +// Uses: +// driver Driver +// +// Produces: +// parallels_tools_path string +type StepPrepareParallelsTools struct { + ParallelsToolsFlavor string + ParallelsToolsMode string +} + +func (s *StepPrepareParallelsTools) Run(state multistep.StateBag) multistep.StepAction { + driver := state.Get("driver").(Driver) + + if s.ParallelsToolsMode == ParallelsToolsModeDisable { + return multistep.ActionContinue + } + + path, err := driver.ToolsIsoPath(s.ParallelsToolsFlavor) + + if err != nil { + state.Put("error", err) + return multistep.ActionHalt + } + + if _, err := os.Stat(path); err != nil { + state.Put("error", fmt.Errorf( + "Couldn't find Parallels Tools for the '%s' flavor! Please, check the\n"+ + "value of 'parallels_tools_flavor'. Valid flavors are: 'win', 'lin',\n"+ + "'mac', 'os2' and 'other'", s.ParallelsToolsFlavor)) + return multistep.ActionHalt + } + + state.Put("parallels_tools_path", path) + return multistep.ActionContinue +} + +func (s *StepPrepareParallelsTools) Cleanup(multistep.StateBag) {} diff --git a/builder/parallels/common/step_prepare_parallels_tools_test.go b/builder/parallels/common/step_prepare_parallels_tools_test.go new file mode 100644 index 000000000..931ecb972 --- /dev/null +++ b/builder/parallels/common/step_prepare_parallels_tools_test.go @@ -0,0 +1,115 @@ +package common + +import ( + "io/ioutil" + "os" + "testing" + + "github.com/mitchellh/multistep" +) + +func TestStepPrepareParallelsTools_impl(t *testing.T) { + var _ multistep.Step = new(StepPrepareParallelsTools) +} + +func TestStepPrepareParallelsTools(t *testing.T) { + tf, err := ioutil.TempFile("", "packer") + if err != nil { + t.Fatalf("err: %s", err) + } + tf.Close() + defer os.Remove(tf.Name()) + + state := testState(t) + step := &StepPrepareParallelsTools{ + ParallelsToolsMode: "", + ParallelsToolsFlavor: "foo", + } + + driver := state.Get("driver").(*DriverMock) + + // Mock results + driver.ToolsIsoPathResult = tf.Name() + + // 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 the driver + if !driver.ToolsIsoPathCalled { + t.Fatal("tools iso path should be called") + } + if driver.ToolsIsoPathFlavor != "foo" { + t.Fatalf("bad: %#v", driver.ToolsIsoPathFlavor) + } + + // Test the resulting state + path, ok := state.GetOk("parallels_tools_path") + if !ok { + t.Fatal("should have parallels_tools_path") + } + if path != tf.Name() { + t.Fatalf("bad: %#v", path) + } +} + +func TestStepPrepareParallelsTools_disabled(t *testing.T) { + state := testState(t) + step := &StepPrepareParallelsTools{ + ParallelsToolsFlavor: "foo", + ParallelsToolsMode: ParallelsToolsModeDisable, + } + + driver := state.Get("driver").(*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 the driver + if driver.ToolsIsoPathCalled { + t.Fatal("tools iso path should NOT be called") + } +} + +func TestStepPrepareParallelsTools_nonExist(t *testing.T) { + state := testState(t) + step := &StepPrepareParallelsTools{ + ParallelsToolsFlavor: "foo", + ParallelsToolsMode: "", + } + + driver := state.Get("driver").(*DriverMock) + + // Mock results + driver.ToolsIsoPathResult = "foo" + + // Test the run + if action := step.Run(state); action != multistep.ActionHalt { + t.Fatalf("bad action: %#v", action) + } + if _, ok := state.GetOk("error"); !ok { + t.Fatal("should have error") + } + + // Test the driver + if !driver.ToolsIsoPathCalled { + t.Fatal("tools iso path should be called") + } + if driver.ToolsIsoPathFlavor != "foo" { + t.Fatalf("bad: %#v", driver.ToolsIsoPathFlavor) + } + + // Test the resulting state + if _, ok := state.GetOk("parallels_tools_path"); ok { + t.Fatal("should NOT have parallels_tools_path") + } +} diff --git a/builder/parallels/iso/builder.go b/builder/parallels/iso/builder.go index 79022a0a7..5fa8eca1f 100644 --- a/builder/parallels/iso/builder.go +++ b/builder/parallels/iso/builder.go @@ -225,6 +225,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe } steps := []multistep.Step{ + ¶llelscommon.StepPrepareParallelsTools{ + ParallelsToolsFlavor: b.config.ParallelsToolsFlavor, + ParallelsToolsMode: b.config.ParallelsToolsMode, + }, &common.StepDownload{ Checksum: b.config.ISOChecksum, ChecksumType: b.config.ISOChecksumType, diff --git a/builder/parallels/pvm/builder.go b/builder/parallels/pvm/builder.go index aabdc8d30..a7931024c 100644 --- a/builder/parallels/pvm/builder.go +++ b/builder/parallels/pvm/builder.go @@ -47,6 +47,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // Build the steps. steps := []multistep.Step{ + ¶llelscommon.StepPrepareParallelsTools{ + ParallelsToolsMode: b.config.ParallelsToolsMode, + ParallelsToolsFlavor: b.config.ParallelsToolsFlavor, + }, ¶llelscommon.StepOutputDir{ Force: b.config.PackerForce, Path: b.config.OutputDir,