shutdown step uses vSphere driver
This commit is contained in:
parent
0e20a77e1c
commit
ee4665c12c
35
driver.go
35
driver.go
@ -10,6 +10,7 @@ import (
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Driver struct {
|
||||
@ -184,14 +185,40 @@ func (d *Driver) powerOff(vm *object.VirtualMachine) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if state != types.VirtualMachinePowerStatePoweredOff {
|
||||
task, err := vm.PowerOff(d.ctx)
|
||||
if state == types.VirtualMachinePowerStatePoweredOff {
|
||||
return nil
|
||||
}
|
||||
|
||||
task, err := vm.PowerOff(d.ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = task.WaitForResult(d.ctx, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Driver) StartShutdown(vm *object.VirtualMachine) error {
|
||||
err := vm.ShutdownGuest(d.ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Driver) WaitForShutdown(vm *object.VirtualMachine, timeout time.Duration) error {
|
||||
shutdownTimer := time.After(timeout)
|
||||
for {
|
||||
powerState, err := vm.PowerState(d.ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = task.WaitForResult(d.ctx, nil)
|
||||
if err != nil {
|
||||
if powerState == "poweredOff" {
|
||||
break
|
||||
}
|
||||
|
||||
select {
|
||||
case <-shutdownTimer:
|
||||
err := errors.New("Timeout while waiting for machine to shut down.")
|
||||
return err
|
||||
default:
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"log"
|
||||
"time"
|
||||
"bytes"
|
||||
"errors"
|
||||
)
|
||||
|
||||
type ShutdownConfig struct {
|
||||
@ -39,17 +38,14 @@ type StepShutdown struct {
|
||||
}
|
||||
|
||||
func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
|
||||
// is set during the communicator.StepConnect
|
||||
comm := state.Get("communicator").(packer.Communicator)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
vm := state.Get("vm").(*object.VirtualMachine)
|
||||
comm := state.Get("communicator").(packer.Communicator)
|
||||
d := state.Get("driver").(Driver)
|
||||
|
||||
ui.Say("Shut down VM...")
|
||||
vm := state.Get("vm").(*object.VirtualMachine)
|
||||
|
||||
if s.config.Command != "" {
|
||||
ui.Say("Gracefully halting virtual machine...")
|
||||
log.Printf("Executing shutdown command: %s", s.config.Command)
|
||||
ui.Say("Executing shutdown command...")
|
||||
log.Printf("Shutdown command: %s", s.config.Command)
|
||||
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd := &packer.RemoteCmd{
|
||||
@ -62,37 +58,20 @@ func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
} else {
|
||||
ui.Say("Forcibly halting virtual machine...")
|
||||
ui.Say("Shut down VM...")
|
||||
|
||||
err := vm.ShutdownGuest(d.ctx)
|
||||
err := d.StartShutdown(vm)
|
||||
if err != nil {
|
||||
state.Put("error", fmt.Errorf("Cannot shut down VM: %v", err))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for the machine to actually shut down
|
||||
log.Printf("Waiting max %s for shutdown to complete", s.config.Timeout)
|
||||
shutdownTimer := time.After(s.config.Timeout)
|
||||
for {
|
||||
powerState, err := vm.PowerState(d.ctx)
|
||||
if err != nil {
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
if powerState == "poweredOff" {
|
||||
break
|
||||
}
|
||||
|
||||
select {
|
||||
case <-shutdownTimer:
|
||||
err := errors.New("Timeout while waiting for machine to shut down.")
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
default:
|
||||
time.Sleep(150 * time.Millisecond)
|
||||
}
|
||||
err := d.WaitForShutdown(vm, s.config.Timeout)
|
||||
if err != nil {
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
ui.Say("VM stopped")
|
||||
|
Loading…
x
Reference in New Issue
Block a user