From c4c46c349e4860d3b959b2bbe8f306630db55751 Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Tue, 1 Nov 2016 18:10:42 -0700 Subject: [PATCH 1/2] implement security group waiter --- .../amazon/common/step_run_source_instance.go | 52 ++++++++++++++----- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/builder/amazon/common/step_run_source_instance.go b/builder/amazon/common/step_run_source_instance.go index fbac16e77..0e8e980ec 100644 --- a/builder/amazon/common/step_run_source_instance.go +++ b/builder/amazon/common/step_run_source_instance.go @@ -9,6 +9,7 @@ import ( "time" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/private/waiter" "github.com/aws/aws-sdk-go/service/ec2" "github.com/mitchellh/multistep" @@ -45,24 +46,18 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi securityGroupIds := make([]*string, len(tempSecurityGroupIds)) for i, sg := range tempSecurityGroupIds { - found := false - for i := 0; i < 5; i++ { - time.Sleep(time.Duration(i) * 5 * time.Second) - log.Printf("[DEBUG] Describing tempSecurityGroup to ensure it is available: %s", sg) - _, err := ec2conn.DescribeSecurityGroups(&ec2.DescribeSecurityGroupsInput{ + err := WaitUntilSecurityGroupExists(ec2conn, + &ec2.DescribeSecurityGroupsInput{ GroupIds: []*string{aws.String(sg)}, - }) - if err == nil { - log.Printf("[DEBUG] Found security group %s", sg) - found = true - break - } - log.Printf("[DEBUG] Error in querying security group %s", err) - } - if found { + }, + ) + if err != nil { + log.Printf("[DEBUG] Found security group %s", sg) securityGroupIds[i] = aws.String(sg) } else { + log.Printf("[DEBUG] Error in querying security group %s", err) state.Put("error", fmt.Errorf("Timeout waiting for security group %s to become available", sg)) + return multistep.ActionHalt } } @@ -363,3 +358,32 @@ func (s *StepRunSourceInstance) Cleanup(state multistep.StateBag) { WaitForState(&stateChange) } } + +func WaitUntilSecurityGroupExists(c *ec2.EC2, input *ec2.DescribeSecurityGroupsInput) error { + waiterCfg := waiter.Config{ + Operation: "DescribeSecurityGroups", + Delay: 15, + MaxAttempts: 40, + Acceptors: []waiter.WaitAcceptor{ + { + State: "success", + Matcher: "path", + Argument: "lenth(SecurityGroups[]) > `0`", + Expected: "true", + }, + { + State: "failure", + Matcher: "error", + Argument: "", + Expected: "InvalidSecurityGroupID.NotFound", + }, + }, + } + + w := waiter.Waiter{ + Client: c, + Input: input, + Config: waiterCfg, + } + return w.Wait() +} From d47e47cf1f22ef3b24d344ec08e91d863e6a8ba6 Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Tue, 1 Nov 2016 18:29:18 -0700 Subject: [PATCH 2/2] rewrite to not use private aws package --- .../amazon/common/step_run_source_instance.go | 43 ++++++------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/builder/amazon/common/step_run_source_instance.go b/builder/amazon/common/step_run_source_instance.go index 0e8e980ec..4d7df8dd8 100644 --- a/builder/amazon/common/step_run_source_instance.go +++ b/builder/amazon/common/step_run_source_instance.go @@ -9,7 +9,6 @@ import ( "time" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/private/waiter" "github.com/aws/aws-sdk-go/service/ec2" "github.com/mitchellh/multistep" @@ -46,17 +45,19 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi securityGroupIds := make([]*string, len(tempSecurityGroupIds)) for i, sg := range tempSecurityGroupIds { + log.Printf("[DEBUG] Waiting for tempSecurityGroup: %s", sg) err := WaitUntilSecurityGroupExists(ec2conn, &ec2.DescribeSecurityGroupsInput{ GroupIds: []*string{aws.String(sg)}, }, ) - if err != nil { + if err == nil { log.Printf("[DEBUG] Found security group %s", sg) securityGroupIds[i] = aws.String(sg) } else { - log.Printf("[DEBUG] Error in querying security group %s", err) - state.Put("error", fmt.Errorf("Timeout waiting for security group %s to become available", sg)) + err := fmt.Errorf("Timed out waiting for security group %s", sg) + log.Printf("[DEBUG] %s", err.Error()) + state.Put("error", err) return multistep.ActionHalt } } @@ -360,30 +361,14 @@ func (s *StepRunSourceInstance) Cleanup(state multistep.StateBag) { } func WaitUntilSecurityGroupExists(c *ec2.EC2, input *ec2.DescribeSecurityGroupsInput) error { - waiterCfg := waiter.Config{ - Operation: "DescribeSecurityGroups", - Delay: 15, - MaxAttempts: 40, - Acceptors: []waiter.WaitAcceptor{ - { - State: "success", - Matcher: "path", - Argument: "lenth(SecurityGroups[]) > `0`", - Expected: "true", - }, - { - State: "failure", - Matcher: "error", - Argument: "", - Expected: "InvalidSecurityGroupID.NotFound", - }, - }, - } - - w := waiter.Waiter{ - Client: c, - Input: input, - Config: waiterCfg, + for i := 0; i < 40; i++ { + _, err := c.DescribeSecurityGroups(input) + if err != nil { + log.Printf("[DEBUG] Error querying security group %s: %s", input.GroupIds, err) + time.Sleep(15 * time.Second) + continue + } + return nil } - return w.Wait() + return fmt.Errorf("timed out") }