Add optional shutdown_command parameter

Allow graceful shutdown on VMs that don't support it
This commit is contained in:
Cheng Sun 2014-12-12 10:32:46 +00:00
parent 6df01a0f40
commit c27e845d1a
2 changed files with 52 additions and 6 deletions

View File

@ -34,7 +34,8 @@ type config struct {
HostPortMin uint `mapstructure:"host_port_min"`
HostPortMax uint `mapstructure:"host_port_max"`
BootCommand []string `mapstructure:"boot_command"`
BootCommand []string `mapstructure:"boot_command"`
ShutdownCommand string `mapstructure:"shutdown_command"`
RawBootWait string `mapstructure:"boot_wait"`
BootWait time.Duration ``
@ -167,6 +168,7 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, retErr error
"iso_name": &self.config.IsoName,
"sr_name": &self.config.SrName,
"network_name": &self.config.NetworkName,
"shutdown_command": &self.config.ShutdownCommand,
"boot_wait": &self.config.RawBootWait,
"iso_checksum": &self.config.ISOChecksum,
"iso_checksum_type": &self.config.ISOChecksumType,

View File

@ -10,6 +10,7 @@ import (
"io"
"net/http"
"os"
"time"
)
type stepShutdownAndExport struct{}
@ -58,13 +59,56 @@ func (stepShutdownAndExport) Run(state multistep.StateBag) multistep.StepAction
ui.Say("Step: Shutdown and export VPX")
// Shutdown the VM
ui.Say("Shutting down the VM...")
err = instance.CleanShutdown()
if err != nil {
ui.Error(fmt.Sprintf("Could not shut down VM: %s", err.Error()))
return multistep.ActionHalt
success := func() bool {
if config.ShutdownCommand != "" {
ui.Say("Executing shutdown command...")
_, err := execute_ssh_cmd(config.ShutdownCommand, config.HostIp, "22", config.Username, config.Password)
if err != nil {
ui.Error(fmt.Sprintf("Shutdown command failed: %s", err.Error()))
return false
}
ui.Say("Waiting for VM to enter Halted state...")
err = InterruptibleWait{
Predicate: func() (bool, error) {
power_state, err := instance.GetPowerState()
return power_state == "Halted", err
},
PredicateInterval: 5 * time.Second,
Timeout: 300 * time.Second,
}.Wait(state)
if err != nil {
ui.Error(fmt.Sprintf("Error waiting for VM to halt: %s", err.Error()))
return false
}
} else {
ui.Say("Attempting to cleanly shutdown the VM...")
err = instance.CleanShutdown()
if err != nil {
ui.Error(fmt.Sprintf("Could not shut down VM: %s", err.Error()))
return false
}
}
return true
}()
if !success {
ui.Say("Forcing hard shutdown of the VM...")
err = instance.HardShutdown()
if err != nil {
ui.Error(fmt.Sprintf("Could not hard shut down VM -- giving up: %s", err.Error()))
return multistep.ActionHalt
}
}
ui.Say("Successfully shut down VM")
switch config.ExportFormat {
case "xva":
// export the VM