From d132157c9e0b6b990cd989662f5499644508de97 Mon Sep 17 00:00:00 2001 From: Nir Soffer Date: Thu, 28 Nov 2019 20:36:32 +0200 Subject: [PATCH] rhv-upload: Fix waiting for transfer We were not considering failures while initializing the transfer. In this case the transfer phase can change to PAUSED_SYSTEM or FINISHED_FAILURE, and transfer_url will be None, which failed the upload with a misleading error: RuntimeError: direct upload to host not supported, requires ovirt-engine >= 4.2 and only works when virt-v2v is run within the oVirt/RHV environment, eg. on an oVirt node Change the wait loop to consider all cases: - Transfer failed and was removed - Transfer failed and will be removed soon - Transfer paused by the system (cancel required) - Unexpected transfer phase (cancel required) - Timeout waiting for TRANSFERRING state (cancel required) Reported-by: Xiaodai Wang (cherry picked from commit 40e1844827e4d096b1919a2159f9effc41915a73 in virt-v2v) --- v2v/rhv-upload-plugin.py | 41 +++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py index 9b83d1cfa..14d4e37fb 100644 --- a/v2v/rhv-upload-plugin.py +++ b/v2v/rhv-upload-plugin.py @@ -185,20 +185,43 @@ def open(readonly): # Get a reference to the created transfer service. transfer_service = transfers_service.image_transfer_service(transfer.id) - # After adding a new transfer for the disk, the transfer's status - # will be INITIALIZING. Wait until the init phase is over. The - # actual transfer can start when its status is "Transferring". + # Wait until transfer's phase change from INITIALIZING to TRANSFERRING. On + # errors transfer's phase can change to PAUSED_SYSTEM or FINISHED_FAILURE. + # If the transfer was paused, we need to cancel it to remove the disk, + # otherwise the system will remove the disk and transfer shortly after. + endt = time.time() + timeout while True: - transfer = transfer_service.get() - if transfer.phase != types.ImageTransferPhase.INITIALIZING: + time.sleep(1) + try: + transfer = transfer_service.get() + except sdk.NotFoundError: + # The system has removed the disk and the transfer. + raise RuntimeError("transfer %s was removed" % transfer.id) + + if transfer.phase == types.ImageTransferPhase.FINISHED_FAILURE: + # The system will remove the disk and the transfer soon. + raise RuntimeError( + "transfer %s has failed" % transfer.id) + + if transfer.phase == types.ImageTransferPhase.PAUSED_SYSTEM: + transfer_service.cancel() + raise RuntimeError( + "transfer %s was paused by system" % transfer.id) + + if transfer.phase == types.ImageTransferPhase.TRANSFERRING: break - if time.time() > endt: + + if transfer.phase != types.ImageTransferPhase.INITIALIZING: + transfer_service.cancel() raise RuntimeError( - "timed out waiting for transfer %s status != INITIALIZING" - % transfer.id) + "unexpected transfer %s phase %s" + % (transfer.id, transfer.phase)) - time.sleep(1) + if time.time() > endt: + transfer_service.cancel() + raise RuntimeError( + "timed out waiting for transfer %s" % transfer.id) # Now we have permission to start the transfer. if params['rhv_direct']: -- 2.25.4