AWS boto - 实例状态/快照状态不会更新Python While循环

时间:2015-02-12 17:15:03

标签: python amazon-web-services boto

所以我用boto创建一个Python脚本,允许用户准备扩展他们的Linux根卷和分区。在脚本的第一部分,我想有一个While循环或类似的东西,使脚本不会继续,直到:

a)实例已完全停止

b)快照已完成创建。


以下是这两个代码段:

实例:

ins_prog = conn.get_all_instances(instance_ids=src_ins, filters={"instance-state":"stopped"})
while ins_prog == "[]":
    print src_ins + " is still shutting down..."
    time.sleep(2) 
        if ins_prog != "[]":
        break

快照:

snap_prog = conn.get_all_snapshots(snapshot_ids=snap_id, filters={"progress":"100"})
while snap_prog == "[]":
    print snap.update
    time.sleep(2) 
        if snap_prog != "[]":
        print "done!"
        break

因此,当调用conn.get_all_instancesconn.get_all_snapshots时,如果过滤器未显示任何内容,则会返回空列表,其格式为[]。问题是While循环甚至没有运行。就好像它不会将[]识别为get_all函数生成的字符串。

如果有更简单的方法可以做到这一点,请告诉我,我现在处于亏损状态):

谢谢!

编辑:根据garnaat的帮助,这是跟进问题。

snap_prog = conn.get_all_snapshots(snapshot_ids=snap.id)[0]
print snap_prog
print snap_prog.id
print snap_prog.volume_id
print snap_prog.status
print snap_prog.progress
print snap_prog.start_time
print snap_prog.owner_id
print snap_prog.owner_alias
print snap_prog.volume_size
print snap_prog.description
print snap_prog.encrypted 

结果:

Snapshot:snap-xxx
snap-xxx
vol-xxx
pending

2015-02-12T21:55:40.000Z
xxxx
None
50
Created by expandDong.py at 2015-02-12 21:55:39
False  

请注意snap_prog.progress如何返回null,但snap_prog.status在置于While循环中时保持为“待定”。

解决:

我的同事和我找到了如何让快照工作的循环。

snap = conn.create_snapshot(src_vol)

while snap.status != 'completed':
    snap.update()
    print snap.status
    time.sleep(5)
        if snap.status == 'completed':
        print snap.id + ' is complete.'
        break

snap.update()调用纯粹更新变量snap以返回最新信息,其中snap.status输出“待定”| “已完成”。我也遇到了snap.status根据控制台没有显示快照正确状态的问题。显然,Console和SDK调用之间存在显着的滞后时间。在控制台中完成快照时,我必须等待~4分钟才能将状态更新为“已完成”。

2 个答案:

答案 0 :(得分:3)

我会首先尝试回答这个问题。所以,您正在查询其状态的资源。如果未满足某个状态,您希望继续查询/询问/轮询资源,直到它处于您希望的状态。显然,这需要您在循环中实际执行查询。也就是说,从抽象意义上讲:

state = resource.query()
while state != desired_state:
    time.sleep(T)
    state = resource.query()

一般来说,想一想这是如何以及为什么会这样。

现在,关于您的代码和问题,您需要了解自己的一些不确定因素。首先,我非常确定conn.get_all_instances()在您的情况下返回一个空列表,而不是实际上是字符串'[]'。也就是说,您的检查应该是空列表而不是某个字符串(*)。在Python中检查空列表就像not l一样简单:

l = give_me_some_list()
if not l:
    print "that list is empty."

您的代码中的另一个问题是您期望在此处使用过多的语言/体系结构。您查询资源并将结果存储在ins_prog中。在那之后,你继续检查ins_prog,好像这样会神奇地"通过后台的一些魔术过程进行更新。不,那不会发生!您需要定期致电conn.get_all_instances()以获取更新信息。

(*)此处记录在案:http://boto.readthedocs.org/en/latest/ref/ec2.html#boto.ec2.connection.EC2Connection.get_all_instances - 文档明确声明"返回类型:列表" 。不是字符串。

答案 1 :(得分:3)

如果我想检查特定实例的状态并等到该实例达到某个状态,我会这样做:

import time    
import boto.ec2
conn = boto.ec2.connect_to_region('us-west-2')  # or whatever region you want
instance = conn.get_all_instances(instance_ids=['i-12345678'])[0].instances[0]
while instance.state != 'stopped':
    time.sleep(2)
    instance.update()

get_all_instances调用的有趣业务是必要的,因为该调用返回一个Reservation对象,而该对象又具有instances属性,该属性是所有匹配实例的列表。因此,我们在列表中选择第一个(也是唯一的)Reservation,然后在预订中获取第一个(也是唯一的)Instance。您可能应该对此进行一些错误检查。

可以用类似的方式处理快照。

snapshot = conn.get_all_snapshots(snapshot_ids=['snap-12345678'])[0]
while snapshot.status != 'completed':
    time.sleep(2)
    snapshot.update()

两个对象上的update()方法查询EC2以获取对象的最新状态,并使用该状态更新本地对象。