Add optional shutdown_command parameter
Allow graceful shutdown on VMs that don't support it
This commit is contained in:
parent
6df01a0f40
commit
c27e845d1a
@ -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,
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user