2014-10-19 84 views
8

我正在使用AWS,Python和Boto library使用Boto轮询停止或启动EC2实例

我想在Boto EC2实例上调用.start().stop(),然后“轮询”它直到它完成。

import boto.ec2 

credentials = { 
    'aws_access_key_id': 'yadayada', 
    'aws_secret_access_key': 'rigamarole', 
    } 

def toggle_instance_state(): 
    conn = boto.ec2.connect_to_region("us-east-1", **credentials) 
    reservations = conn.get_all_reservations() 
    instance = reservations[0].instances[0] 
    state = instance.state 
    if state == 'stopped': 
     instance.start() 
    elif state == 'running': 
     instance.stop() 
    state = instance.state 
    while state not in ('running', 'stopped'): 
     sleep(5) 
     state = instance.state 
     print " state:", state 

然而,在最后while循环,状态似乎得到“卡”在任“待定”或“停止”。强调“似乎”,从我的AWS控制台,我可以看到实际上确实使它“开始”或“停止”。

我能解决这个问题的唯一办法就是召回在while循环.get_all_reservations(),像这样:

while state not in ('running', 'stopped'): 
     sleep(5) 
     # added this line: 
     instance = conn.get_all_reservations()[0].instances[0] 
     state = instance.state 
     print " state:", state 

是否有打电话让instance将报告的实际状态的方法?

回答

10

实例状态不会自动更新。您必须调用update方法来告诉对象再次往EC2服务的往返调用并获取对象的最新状态。像这样的东西应该工作:

while instance.state not in ('running', 'stopped'): 
    sleep(5) 
    instance.update() 

要在boto3中实现相同的效果,应该这样的工作。

import boto3 
ec2 = boto3.resource('ec2') 
instance = ec2.Instance('i-123456789') 
while instance.state['Name'] not in ('running', 'stopped'): 
    sleep(5) 
    instance.load() 
+0

完美 - 工作恰到好处。不是没有,但我想说:我读了文档,我只是加倍检查...这种方法是不是在写这篇文章的文档!再次感谢。 – 2014-10-21 20:34:05

+0

@garnaat请编辑你的答案并在boto3中添加boto3的指令,而不是'update()'你需要使用'load()' - 供将来的用户看 – bluesummers 2017-06-28 09:52:33

3

这也适用于我。在文档上我们有:

update(validate=False, dry_run=False)
- 通过调用来从服务中获取当前实例属性来更新实例的状态信息。

参数:validate (bool)
- 默认情况下,如果EC2不返回关于该实例的数据,则update方法将悄然返回。但是,如果验证参数为True,则如果EC2中没有数据返回,则会引发ValueError异常。