builder/amazon/*: sigint while waiting for state change works

This commit is contained in:
Mitchell Hashimoto 2013-07-25 20:49:15 -05:00
parent 6d658ac923
commit 1d0adbf2c2
4 changed files with 52 additions and 15 deletions

View File

@ -8,12 +8,13 @@ FEATURES:
IMPROVEMENTS:
* amazon-ebs: Can now launch instances into a VPC for added protection [GH-210]
* virtualbox, vmware: Add backspace, delete, and F1-F12 keys to the boot
* builder/amazon/all: Ctrl-C while waiting for state change works
* builder/amazon/ebs: Can now launch instances into a VPC for added protection [GH-210]
* builder/virtualbox,vmware: Add backspace, delete, and F1-F12 keys to the boot
command.
* virtualbox: massive performance improvements with big ISO files because
* builder/virtualbox: massive performance improvements with big ISO files because
an expensive copy is avoided. [GH-202]
* vmware: CD is removed prior to exporting final machine. [GH-198]
* builder/vmware: CD is removed prior to exporting final machine. [GH-198]
BUG FIXES:

View File

@ -1,19 +1,35 @@
package common
import (
"errors"
"fmt"
"github.com/mitchellh/goamz/ec2"
"github.com/mitchellh/multistep"
"log"
"time"
)
func WaitForState(ec2conn *ec2.EC2, originalInstance *ec2.Instance, pending []string, target string) (i *ec2.Instance, err error) {
log.Printf("Waiting for instance state to become: %s", target)
type StateChangeConf struct {
Conn *ec2.EC2
Instance *ec2.Instance
Pending []string
StepState map[string]interface{}
Target string
}
func WaitForState(conf *StateChangeConf) (i *ec2.Instance, err error) {
log.Printf("Waiting for instance state to become: %s", conf.Target)
i = conf.Instance
for i.State.Name != conf.Target {
if conf.StepState != nil {
if _, ok := conf.StepState[multistep.StateCancelled]; ok {
return nil, errors.New("interrupted")
}
}
i = originalInstance
for i.State.Name != target {
found := false
for _, allowed := range pending {
for _, allowed := range conf.Pending {
if i.State.Name == allowed {
found = true
break
@ -21,12 +37,12 @@ func WaitForState(ec2conn *ec2.EC2, originalInstance *ec2.Instance, pending []st
}
if !found {
fmt.Errorf("unexpected state '%s', wanted target '%s'", i.State.Name, target)
fmt.Errorf("unexpected state '%s', wanted target '%s'", i.State.Name, conf.Target)
return
}
var resp *ec2.InstancesResp
resp, err = ec2conn.Instances([]string{i.InstanceId}, ec2.NewFilter())
resp, err = conf.Conn.Instances([]string{i.InstanceId}, ec2.NewFilter())
if err != nil {
return
}

View File

@ -60,7 +60,14 @@ func (s *StepRunSourceInstance) Run(state map[string]interface{}) multistep.Step
log.Printf("instance id: %s", s.instance.InstanceId)
ui.Say(fmt.Sprintf("Waiting for instance (%s) to become ready...", s.instance.InstanceId))
s.instance, err = WaitForState(ec2conn, s.instance, []string{"pending"}, "running")
stateChange := StateChangeConf{
Conn: ec2conn,
Instance: s.instance,
Pending: []string{"pending"},
Target: "running",
StepState: state,
}
s.instance, err = WaitForState(&stateChange)
if err != nil {
err := fmt.Errorf("Error waiting for instance (%s) to become ready: %s", s.instance.InstanceId, err)
state["error"] = err
@ -87,6 +94,12 @@ func (s *StepRunSourceInstance) Cleanup(state map[string]interface{}) {
return
}
pending := []string{"pending", "running", "shutting-down", "stopped", "stopping"}
WaitForState(ec2conn, s.instance, pending, "terminated")
stateChange := StateChangeConf{
Conn: ec2conn,
Instance: s.instance,
Pending: []string{"pending", "running", "shutting-down", "stopped", "stopping"},
Target: "running",
}
WaitForState(&stateChange)
}

View File

@ -27,7 +27,14 @@ func (s *stepStopInstance) Run(state map[string]interface{}) multistep.StepActio
// Wait for the instance to actual stop
ui.Say("Waiting for the instance to stop...")
instance, err = awscommon.WaitForState(ec2conn, instance, []string{"running", "stopping"}, "stopped")
stateChange := awscommon.StateChangeConf{
Conn: ec2conn,
Instance: instance,
Pending: []string{"running", "stopping"},
Target: "stopped",
StepState: state,
}
instance, err = awscommon.WaitForState(&stateChange)
if err != nil {
err := fmt.Errorf("Error waiting for instance to stop: %s", err)
state["error"] = err