Commit 1d0adbf2 authored by Mitchell Hashimoto's avatar Mitchell Hashimoto

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

parent 6d658ac9
...@@ -8,12 +8,13 @@ FEATURES: ...@@ -8,12 +8,13 @@ FEATURES:
IMPROVEMENTS: IMPROVEMENTS:
* amazon-ebs: Can now launch instances into a VPC for added protection [GH-210] * builder/amazon/all: Ctrl-C while waiting for state change works
* virtualbox, vmware: Add backspace, delete, and F1-F12 keys to the boot * 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. 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] 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: BUG FIXES:
......
package common package common
import ( import (
"errors"
"fmt" "fmt"
"github.com/mitchellh/goamz/ec2" "github.com/mitchellh/goamz/ec2"
"github.com/mitchellh/multistep"
"log" "log"
"time" "time"
) )
func WaitForState(ec2conn *ec2.EC2, originalInstance *ec2.Instance, pending []string, target string) (i *ec2.Instance, err error) { type StateChangeConf struct {
log.Printf("Waiting for instance state to become: %s", target) 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 found := false
for _, allowed := range pending { for _, allowed := range conf.Pending {
if i.State.Name == allowed { if i.State.Name == allowed {
found = true found = true
break break
...@@ -21,12 +37,12 @@ func WaitForState(ec2conn *ec2.EC2, originalInstance *ec2.Instance, pending []st ...@@ -21,12 +37,12 @@ func WaitForState(ec2conn *ec2.EC2, originalInstance *ec2.Instance, pending []st
} }
if !found { 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 return
} }
var resp *ec2.InstancesResp 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 { if err != nil {
return return
} }
......
...@@ -60,7 +60,14 @@ func (s *StepRunSourceInstance) Run(state map[string]interface{}) multistep.Step ...@@ -60,7 +60,14 @@ func (s *StepRunSourceInstance) Run(state map[string]interface{}) multistep.Step
log.Printf("instance id: %s", s.instance.InstanceId) log.Printf("instance id: %s", s.instance.InstanceId)
ui.Say(fmt.Sprintf("Waiting for instance (%s) to become ready...", 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 { if err != nil {
err := fmt.Errorf("Error waiting for instance (%s) to become ready: %s", s.instance.InstanceId, err) err := fmt.Errorf("Error waiting for instance (%s) to become ready: %s", s.instance.InstanceId, err)
state["error"] = err state["error"] = err
...@@ -87,6 +94,12 @@ func (s *StepRunSourceInstance) Cleanup(state map[string]interface{}) { ...@@ -87,6 +94,12 @@ func (s *StepRunSourceInstance) Cleanup(state map[string]interface{}) {
return return
} }
pending := []string{"pending", "running", "shutting-down", "stopped", "stopping"} stateChange := StateChangeConf{
WaitForState(ec2conn, s.instance, pending, "terminated") Conn: ec2conn,
Instance: s.instance,
Pending: []string{"pending", "running", "shutting-down", "stopped", "stopping"},
Target: "running",
}
WaitForState(&stateChange)
} }
...@@ -27,7 +27,14 @@ func (s *stepStopInstance) Run(state map[string]interface{}) multistep.StepActio ...@@ -27,7 +27,14 @@ func (s *stepStopInstance) Run(state map[string]interface{}) multistep.StepActio
// Wait for the instance to actual stop // Wait for the instance to actual stop
ui.Say("Waiting for the instance to 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 { if err != nil {
err := fmt.Errorf("Error waiting for instance to stop: %s", err) err := fmt.Errorf("Error waiting for instance to stop: %s", err)
state["error"] = err state["error"] = err
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment