2014-10-19 110 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異常。