Add install_timeout to stop build if step_wait takes too long

Halts the build when the VM does not shutdown within the timeout period
Implemented with interruptible_wait, so step_wait is also interruptible
This commit is contained in:
Cheng Sun 2014-12-08 17:49:07 +00:00
parent 1dd963278f
commit cadf3a5d6a
3 changed files with 35 additions and 14 deletions

View File

@ -35,10 +35,9 @@ type config struct {
HostPortMax uint `mapstructure:"host_port_max"`
BootCommand []string `mapstructure:"boot_command"`
RawBootWait string `mapstructure:"boot_wait"`
BootWait time.Duration ``
SSHWaitTimeout time.Duration ``
RawBootWait string `mapstructure:"boot_wait"`
BootWait time.Duration ``
ISOChecksum string `mapstructure:"iso_checksum"`
ISOChecksumType string `mapstructure:"iso_checksum_type"`
@ -52,7 +51,11 @@ type config struct {
LocalIp string `mapstructure:"local_ip"`
PlatformArgs map[string]string `mapstructure:"platform_args"`
RawSSHWaitTimeout string `mapstructure:"ssh_wait_timeout"`
RawInstallTimeout string `mapstructure:"install_timeout"`
InstallTimeout time.Duration ``
RawSSHWaitTimeout string `mapstructure:"ssh_wait_timeout"`
SSHWaitTimeout time.Duration ``
SSHPassword string `mapstructure:"ssh_password"`
SSHUser string `mapstructure:"ssh_username"`
@ -100,6 +103,10 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, retErr error
self.config.RawBootWait = "5s"
}
if self.config.RawInstallTimeout == "" {
self.config.RawInstallTimeout = "200m"
}
if self.config.HTTPPortMin == 0 {
self.config.HTTPPortMin = 8000
}
@ -133,6 +140,7 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, retErr error
"iso_checksum_type": &self.config.ISOChecksumType,
"http_directory": &self.config.HTTPDir,
"local_ip": &self.config.LocalIp,
"install_timeout": &self.config.RawInstallTimeout,
"ssh_wait_timeout": &self.config.RawSSHWaitTimeout,
"ssh_username": &self.config.SSHUser,
"ssh_password": &self.config.SSHPassword,
@ -167,6 +175,12 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, retErr error
errs, fmt.Errorf("Failed to parse ssh_wait_timeout: %s", err))
}
self.config.InstallTimeout, err = time.ParseDuration(self.config.RawInstallTimeout)
if err != nil {
errs = packer.MultiErrorAppend(
errs, fmt.Errorf("Failed to parse install_timeout: %s", err))
}
for i, command := range self.config.BootCommand {
if err := self.config.tpl.Validate(command); err != nil {
errs = packer.MultiErrorAppend(errs,

View File

@ -9,27 +9,33 @@ import (
type stepWait struct{}
func (self *stepWait) Run(state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(config)
ui := state.Get("ui").(packer.Ui)
client := state.Get("client").(XenAPIClient)
ui.Say("Step: Wait for install to complete.")
//Expect install to be configured to shutdown on completion
instance_id := state.Get("instance_uuid").(string)
instance, _ := client.GetVMByUuid(instance_id)
for {
time.Sleep(30 * time.Second)
ui.Say("Waiting for VM install...")
//Expect install to be configured to shutdown on completion
err := InterruptibleWait{
Predicate: func () (bool, error) {
power_state, err := instance.GetPowerState()
return power_state == "Halted", err
},
PredicateInterval: 30 * time.Second,
Timeout: config.InstallTimeout,
}.Wait(state)
power_state, _ := instance.GetPowerState()
if power_state == "Halted" {
ui.Say("Install has completed. Moving on.")
break
}
if err != nil {
ui.Error(err.Error())
ui.Error("Giving up waiting for installation to complete.")
return multistep.ActionHalt
}
ui.Say("Install has completed. Moving on.")
// Eject ISO from drive
vbds, _ := instance.GetVBDs()
for _, vbd := range vbds {

View File

@ -10,6 +10,7 @@
"iso_name": "CentOS-6.4-x86_64-minimal.iso",
"http_directory": "http",
"local_ip": "10.80.3.223",
"install_timeout": "600",
"ssh_username": "root",
"ssh_password": "vmpassword",
"boot_command":