Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python boto ec2 - How do I wait till an image is created or failed

I am writing a code to iterate through all available instances and create an AMI for them as below:

for reservation in reservations:
    ......
    ami_id = ec2_conn.create_image(instance.id, ami_name, description=ami_desc, no_reboot=True)

But how do I wait till an image is created before proceeding with the creation of next image? Because I need to track the status of each ami created.

I know that I can retrieve the state using:

image_status = get_image(ami_id).state

So, do I iterate through the list of ami_ids created and then fetch the state for each of them? If so, then what if the image is still pending when I read the state of the image? How will I find out if the image creation has failed eventually?

Thanks.

like image 346
drunkenfist Avatar asked Oct 03 '14 07:10

drunkenfist


4 Answers

If I understand correctly, you want to initiate the create_image call and then wait until the server-side operation completes before moving on. To do this, you have to poll the EC2 service periodically until the state of the image is either available (meaning it succeeded) or failed (meaning it failed). The code would look something like this:

import time
...
image_id = ec2_conn.create_image(instance.id, ...)
image = ec2_conn.get_all_images(image_ids=[image_id])[0]
while image.state == 'pending':
    time.sleep(5)
    image.update()
if image.state == 'available':
    # success, do something here
else:
    # handle failure here
like image 154
garnaat Avatar answered Oct 06 '22 01:10

garnaat


I think the best thing to do is use a waiter, none of the answers above do that:

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Waiter.ImageAvailable

like image 28
piotr Avatar answered Oct 06 '22 01:10

piotr


For someone who is using boto3, the following would work:

import boto3
import time
region = 'us-west-1'
client = boto3.client('ec2', region_name=region)
def is_image_available(image_id):
    try:
        available = 0
        while available == 0:
            print "Not created yet.. Gonna sleep for 10 seconds"
            time.sleep(10)
            image = client.describe_images(ImageIds=[image_id])
            if image['Images'][0]['State'] == 'available':
                available = 1
        if available == 1:
            print "Image is now available for use."
            return True
    except Exception, e:
        print e

Using this function you should be able to pass the image_id and get the status as true if its available. You can use it in an if condition as follows:

if is_image_available(image_id):
# Do something if image is available

Hope it helps.

like image 38
user3228188 Avatar answered Oct 06 '22 01:10

user3228188


Boto now has the wait_until_running method which saves rolling your own polling code:

http://boto3.readthedocs.io/en/latest/reference/services/ec2.html#EC2.Instance.wait_until_running

like image 24
Snowcrash Avatar answered Oct 05 '22 23:10

Snowcrash