From 67c71aa8360b186be229feb98967a61355f2bf9a Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 5 Sep 2013 17:19:23 -0700 Subject: [PATCH] builder/amazon/common: if instance query returns none, ignore --- CHANGELOG.md | 2 ++ builder/amazon/common/instance.go | 44 +++++++++++++++++++------------ 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 523e0c544..8a7ec358e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ BUG FIXES: * builder/amazon/all: When copying AMI to multiple regions, copy the metadata (tags and attributes) as well. [GH-388] +* builder/amazon/all: Fix panic case where eventually consistent + instance state caused an index out of bounds. * builder/vmware: Autoanswer VMware dialogs. [GH-393] * command/inspect: Fix weird output for default values for optional vars. diff --git a/builder/amazon/common/instance.go b/builder/amazon/common/instance.go index 6f8f78cd4..462bb58e7 100644 --- a/builder/amazon/common/instance.go +++ b/builder/amazon/common/instance.go @@ -40,6 +40,12 @@ func InstanceStateRefreshFunc(conn *ec2.EC2, i *ec2.Instance) StateRefreshFunc { return nil, "", err } + if len(resp.Reservations) == 0 || len(resp.Reservations[0].Instances) == 0 { + // Sometimes AWS just has consistency issues and doesn't see + // our instance yet. Return an empty state. + return nil, "", nil + } + i = &resp.Reservations[0].Instances[0] return i, i.State.Name, nil } @@ -57,27 +63,31 @@ func WaitForState(conf *StateChangeConf) (i interface{}, err error) { return } - if currentState == conf.Target { - return - } - - if conf.StepState != nil { - if _, ok := conf.StepState.GetOk(multistep.StateCancelled); ok { - return nil, errors.New("interrupted") + // Check states only if we were able to refresh to an instance + // that exists. + if i != nil { + if currentState == conf.Target { + return } - } - found := false - for _, allowed := range conf.Pending { - if currentState == allowed { - found = true - break + if conf.StepState != nil { + if _, ok := conf.StepState.GetOk(multistep.StateCancelled); ok { + return nil, errors.New("interrupted") + } } - } - if !found { - fmt.Errorf("unexpected state '%s', wanted target '%s'", currentState, conf.Target) - return + found := false + for _, allowed := range conf.Pending { + if currentState == allowed { + found = true + break + } + } + + if !found { + fmt.Errorf("unexpected state '%s', wanted target '%s'", currentState, conf.Target) + return + } } time.Sleep(2 * time.Second)