From 757f8c087e9a5f4c553472209b46232b70a36b55 Mon Sep 17 00:00:00 2001 From: milan Date: Wed, 6 Mar 2013 09:34:29 +0100 Subject: [PATCH 1/4] avoid the instance start--state-fetch race --- ec2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ec2 b/ec2 index 2a239cc2ba7..54f131a3b90 100644 --- a/ec2 +++ b/ec2 @@ -231,6 +231,9 @@ def main(): res_list = res.connection.get_all_instances(instids) this_res = res_list[0] if wait: + # there's a race between start and get an instance state + import time + time.sleep(5) # wait here until the instances are up num_running = 0 while num_running != len(instids): From ae3fb0adf5559bbe5341a5ee4d6108800af0892d Mon Sep 17 00:00:00 2001 From: milan Date: Thu, 7 Mar 2013 18:01:55 +0100 Subject: [PATCH 2/4] waiting enhancements --- ec2 | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/ec2 b/ec2 index 54f131a3b90..9b225637ab9 100644 --- a/ec2 +++ b/ec2 @@ -71,6 +71,11 @@ options: required: false default: false aliases: [] + wait_timeout: + descritption: + - How long before wait gives up. In seconds. + - default: 300 + aliases: [] ec2_url: description: - url to use to connect to EC2 or your Eucalyptus cloud (by default the module will use EC2 endpoints) @@ -134,7 +139,7 @@ import sys import time try: - import boto + import boto except ImportError: print "failed=True msg='boto required for this module'" sys.exit(1) @@ -152,6 +157,7 @@ def main(): monitoring = dict(choices=BOOLEANS, default=False), ramdisk = dict(), wait = dict(choices=BOOLEANS, default=False), + wait_timeout = dict(default=300), ec2_url = dict(aliases=['EC2_URL']), ec2_secret_key = dict(aliases=['EC2_SECRET_KEY'], no_log=True), ec2_access_key = dict(aliases=['EC2_ACCESS_KEY']), @@ -171,6 +177,7 @@ def main(): kernel = module.params.get('kernel') ramdisk = module.params.get('ramdisk') wait = module.params.get('wait') + wait_timeout = int(module.params.get('wait_timeout')) ec2_url = module.params.get('ec2_url') ec2_secret_key = module.params.get('ec2_secret_key') ec2_access_key = module.params.get('ec2_access_key') @@ -221,6 +228,16 @@ def main(): module.fail_json(msg = "%s: %s" % (e.error_code, e.error_message)) instids = [ i.id for i in res.instances ] + while True: + try: + res.connection.get_all_instances(instids) + break + except boto.exception.EC2ResponseError as e: + if "InvalidInstanceID.NotFound" in str(e): + # there's a race between start and get an instance + continue + else: + module.fail_json(msg = str(e)) if instance_tags: try: @@ -228,20 +245,19 @@ def main(): except boto.exception.EC2ResponseError as e: module.fail_json(msg = "%s: %s" % (e.error_code, e.error_message)) + # wait here until the instances are up res_list = res.connection.get_all_instances(instids) this_res = res_list[0] - if wait: - # there's a race between start and get an instance state - import time + num_running = 0 + wait_timeout = time.time() + wait_timeout + while wait and wait_timeout > time.time() and num_running < len(instids): + res_list = res.connection.get_all_instances(instids) + this_res = res_list[0] + num_running = len([ i for i in this_res.instances if i.state=='running' ]) time.sleep(5) - # wait here until the instances are up - num_running = 0 - while num_running != len(instids): - res_list = res.connection.get_all_instances(instids) - this_res = res_list[0] - num_running = len([ i for i in this_res.instances if i.state=='running' ]) - time.sleep(5) - + if wait and wait_timeout <= time.time(): + # waiting took too long + module.fail_json(msg = "wait for instances running timeout on %s" % time.asctime()) instances = [] for inst in this_res.instances: d = { From b5a2882b5e5f9eabfdf1aabe2b9a050391076e6d Mon Sep 17 00:00:00 2001 From: milan Date: Thu, 7 Mar 2013 23:37:25 +0100 Subject: [PATCH 3/4] fix documentation --- ec2 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ec2 b/ec2 index 9b225637ab9..8be4249aaf2 100644 --- a/ec2 +++ b/ec2 @@ -72,10 +72,10 @@ options: default: false aliases: [] wait_timeout: - descritption: + description: - How long before wait gives up. In seconds. - - default: 300 - aliases: [] + default: 300 + aliases: [] ec2_url: description: - url to use to connect to EC2 or your Eucalyptus cloud (by default the module will use EC2 endpoints) From 79f9d9b2a2ecc4c8b1d6f9c82b81271368762236 Mon Sep 17 00:00:00 2001 From: milan Date: Thu, 7 Mar 2013 23:44:22 +0100 Subject: [PATCH 4/4] fixed case and punctuation --- ec2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ec2 b/ec2 index 8be4249aaf2..8e39e350e52 100644 --- a/ec2 +++ b/ec2 @@ -73,7 +73,7 @@ options: aliases: [] wait_timeout: description: - - How long before wait gives up. In seconds. + - how long before wait gives up, in seconds default: 300 aliases: [] ec2_url: