shutdown step uses vSphere driver

This commit is contained in:
Michael Kuzmin 2017-07-02 15:27:52 +03:00
parent 0e20a77e1c
commit ee4665c12c
2 changed files with 41 additions and 35 deletions

View File

@ -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

View File

@ -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")