@@ -248,7 +248,8 @@ def do_cloudpipe_create(cs, args):
248248
249249
250250def _poll_for_status (poll_fn , obj_id , action , final_ok_states ,
251- poll_period = 5 , show_progress = True ):
251+ poll_period = 5 , show_progress = True ,
252+ status_field = "status" , silent = False ):
252253 """Block while an action is being performed, periodically printing
253254 progress.
254255 """
@@ -262,21 +263,32 @@ def print_progress(progress):
262263 sys .stdout .write (msg )
263264 sys .stdout .flush ()
264265
265- print
266+ if not silent :
267+ print
268+
266269 while True :
267270 obj = poll_fn (obj_id )
268- status = obj .status .lower ()
271+
272+ status = getattr (obj , status_field )
273+
274+ if status :
275+ status = status .lower ()
276+
269277 progress = getattr (obj , 'progress' , None ) or 0
270278 if status in final_ok_states :
271- print_progress (100 )
272- print "\n Finished"
279+ if not silent :
280+ print_progress (100 )
281+ print "\n Finished"
273282 break
274283 elif status == "error" :
275- print "\n Error %(action)s instance" % locals ()
284+ if not silent :
285+ print "\n Error %(action)s instance" % locals ()
276286 break
277- else :
287+
288+ if not silent :
278289 print_progress (progress )
279- time .sleep (poll_period )
290+
291+ time .sleep (poll_period )
280292
281293
282294def _translate_flavor_keys (collection ):
@@ -753,6 +765,21 @@ def do_image_create(cs, args):
753765 _poll_for_status (cs .images .get , image_uuid , 'snapshotting' ,
754766 ['active' ])
755767
768+ # NOTE(sirp): A race-condition exists between when the image finishes
769+ # uploading and when the servers's `task_state` is cleared. To account
770+ # for this, we need to poll a second time to ensure the `task_state` is
771+ # cleared before returning, ensuring that a snapshot taken immediately
772+ # after this function returns will succeed.
773+ #
774+ # A better long-term solution will be to separate 'snapshotting' and
775+ # 'image-uploading' in Nova and clear the task-state once the VM
776+ # snapshot is complete but before the upload begins.
777+ task_state_field = "OS-EXT-STS:task_state"
778+ if hasattr (server , task_state_field ):
779+ _poll_for_status (cs .servers .get , server .id , 'image_snapshot' ,
780+ [None ], status_field = task_state_field ,
781+ show_progress = False , silent = True )
782+
756783
757784@utils .arg ('server' ,
758785 metavar = '<server>' ,
0 commit comments