Commit 95e0e465 authored by Mitchell Hashimoto's avatar Mitchell Hashimoto

builder/vmware: move StepRun to common

parent 7f86fa5f
package iso package common
import ( import (
"fmt" "fmt"
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
vmwcommon "github.com/mitchellh/packer/builder/vmware/common"
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"time" "time"
) )
...@@ -11,39 +10,51 @@ import ( ...@@ -11,39 +10,51 @@ import (
// This step runs the created virtual machine. // This step runs the created virtual machine.
// //
// Uses: // Uses:
// config *config
// driver Driver // driver Driver
// ui packer.Ui // ui packer.Ui
// vmx_path string // vmx_path string
// //
// Produces: // Produces:
// <nothing> // <nothing>
type stepRun struct { type StepRun struct {
BootWait time.Duration
DurationBeforeStop time.Duration
Headless bool
bootTime time.Time bootTime time.Time
vmxPath string vmxPath string
} }
func (s *stepRun) Run(state multistep.StateBag) multistep.StepAction { func (s *StepRun) Run(state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*config) driver := state.Get("driver").(Driver)
driver := state.Get("driver").(vmwcommon.Driver)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
vmxPath := state.Get("vmx_path").(string) vmxPath := state.Get("vmx_path").(string)
vncIp := state.Get("vnc_ip").(string)
vncPort := state.Get("vnc_port").(uint)
// Set the VMX path so that we know we started the machine // Set the VMX path so that we know we started the machine
s.bootTime = time.Now() s.bootTime = time.Now()
s.vmxPath = vmxPath s.vmxPath = vmxPath
ui.Say("Starting virtual machine...") ui.Say("Starting virtual machine...")
if config.Headless { if s.Headless {
ui.Message(fmt.Sprintf( vncIpRaw, vncIpOk := state.GetOk("vnc_ip")
"The VM will be run headless, without a GUI. If you want to\n"+ vncPortRaw, vncPortOk := state.GetOk("vnc_port")
"view the screen of the VM, connect via VNC without a password to\n"+
"%s:%d", vncIp, vncPort)) if vncIpOk && vncPortOk {
vncIp := vncIpRaw.(string)
vncPort := vncPortRaw.(uint)
ui.Message(fmt.Sprintf(
"The VM will be run headless, without a GUI. If you want to\n"+
"view the screen of the VM, connect via VNC without a password to\n"+
"%s:%d", vncIp, vncPort))
} else {
ui.Message("The VM will be run headless, without a GUI, as configured.\n" +
"If the run isn't succeeding as you expect, please enable the GUI\n" +
"to inspect the progress of the build.")
}
} }
if err := driver.Start(vmxPath, config.Headless); err != nil { if err := driver.Start(vmxPath, s.Headless); err != nil {
err := fmt.Errorf("Error starting VM: %s", err) err := fmt.Errorf("Error starting VM: %s", err)
state.Put("error", err) state.Put("error", err)
ui.Error(err.Error()) ui.Error(err.Error())
...@@ -51,9 +62,9 @@ func (s *stepRun) Run(state multistep.StateBag) multistep.StepAction { ...@@ -51,9 +62,9 @@ func (s *stepRun) Run(state multistep.StateBag) multistep.StepAction {
} }
// Wait the wait amount // Wait the wait amount
if int64(config.bootWait) > 0 { if int64(s.BootWait) > 0 {
ui.Say(fmt.Sprintf("Waiting %s for boot...", config.bootWait.String())) ui.Say(fmt.Sprintf("Waiting %s for boot...", s.BootWait.String()))
wait := time.After(config.bootWait) wait := time.After(s.BootWait)
WAITLOOP: WAITLOOP:
for { for {
select { select {
...@@ -71,18 +82,19 @@ func (s *stepRun) Run(state multistep.StateBag) multistep.StepAction { ...@@ -71,18 +82,19 @@ func (s *stepRun) Run(state multistep.StateBag) multistep.StepAction {
return multistep.ActionContinue return multistep.ActionContinue
} }
func (s *stepRun) Cleanup(state multistep.StateBag) { func (s *StepRun) Cleanup(state multistep.StateBag) {
driver := state.Get("driver").(vmwcommon.Driver) driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
// If we started the machine... stop it. // If we started the machine... stop it.
if s.vmxPath != "" { if s.vmxPath != "" {
// If we started it less than 5 seconds ago... wait. // If we started it less than 5 seconds ago... wait.
sinceBootTime := time.Since(s.bootTime) sinceBootTime := time.Since(s.bootTime)
waitBootTime := 5 * time.Second waitBootTime := s.DurationBeforeStop
if sinceBootTime < waitBootTime { if sinceBootTime < waitBootTime {
sleepTime := waitBootTime - sinceBootTime sleepTime := waitBootTime - sinceBootTime
ui.Say(fmt.Sprintf("Waiting %s to give VMware time to clean up...", sleepTime.String())) ui.Say(fmt.Sprintf(
"Waiting %s to give VMware time to clean up...", sleepTime.String()))
time.Sleep(sleepTime) time.Sleep(sleepTime)
} }
......
package common
import (
"testing"
"github.com/mitchellh/multistep"
)
func TestStepRun_impl(t *testing.T) {
var _ multistep.Step = new(StepRun)
}
func TestStepRun(t *testing.T) {
state := testState(t)
step := new(StepRun)
state.Put("vmx_path", "foo")
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.StartCalled {
t.Fatal("start should be called")
}
if driver.StartPath != "foo" {
t.Fatalf("bad: %#v", driver.StartPath)
}
if driver.StartHeadless {
t.Fatal("bad")
}
// Test cleanup
step.Cleanup(state)
if driver.StopCalled {
t.Fatal("stop should not be called if not running")
}
}
func TestStepRun_cleanupRunning(t *testing.T) {
state := testState(t)
step := new(StepRun)
state.Put("vmx_path", "foo")
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.StartCalled {
t.Fatal("start should be called")
}
if driver.StartPath != "foo" {
t.Fatalf("bad: %#v", driver.StartPath)
}
if driver.StartHeadless {
t.Fatal("bad")
}
// Mark that it is running
driver.IsRunningResult = true
// Test cleanup
step.Cleanup(state)
if !driver.StopCalled {
t.Fatal("stop should be called")
}
}
...@@ -396,7 +396,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ...@@ -396,7 +396,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
&stepHTTPServer{}, &stepHTTPServer{},
&stepConfigureVNC{}, &stepConfigureVNC{},
&StepRegister{}, &StepRegister{},
&stepRun{}, &vmwcommon.StepRun{
BootWait: b.config.bootWait,
DurationBeforeStop: 5 * time.Second,
Headless: b.config.Headless,
},
&stepTypeBootCommand{}, &stepTypeBootCommand{},
&common.StepConnectSSH{ &common.StepConnectSSH{
SSHAddress: driver.SSHAddress, SSHAddress: driver.SSHAddress,
......
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