Validation of VMDK upload completion

Validate the completion of VMDK upload in ImportVApp. Otherwise, an
incomplete upload is falsely marked as successful which results in
corrupted VM.

Change-Id: I0608afd31daf95b564d3fc32028401d4aa526055
This commit is contained in:
Ivaylo Mitev 2020-05-08 10:59:10 -07:00
parent af6d26cee1
commit 20bc961a4c
3 changed files with 45 additions and 2 deletions

View File

@ -353,7 +353,13 @@ class VmdkHandle(FileHandle):
LOG.debug("Lease for %(url)s is in state: %(state)s.",
{'url': self._url,
'state': state})
if state == 'ready':
if self._get_progress() < 100:
LOG.error("Aborting lease for %s due to incomplete transfer.",
self._url)
self._session.invoke_api(self._session.vim,
'HttpNfcLeaseAbort',
self._lease)
elif state == 'ready':
LOG.debug("Releasing lease for %s.", self._url)
self._session.invoke_api(self._session.vim,
'HttpNfcLeaseComplete',
@ -506,7 +512,14 @@ class VmdkWriteHandle(VmdkHandle):
super(VmdkWriteHandle, self).__init__(session, lease, url, self._conn)
def get_imported_vm(self):
""""Get managed object reference of the VM created for import."""
""""Get managed object reference of the VM created for import.
:raises: VimException
"""
if self._get_progress() < 100:
excep_msg = _("Incomplete VMDK upload to %s.") % self._url
LOG.exception(excep_msg)
raise exceptions.ImageTransferException(excep_msg)
return self._vm_ref
def tell(self):

View File

@ -171,6 +171,18 @@ class VmdkHandleTest(base.TestCase):
self.assertRaises(IOError, handle.fileno)
def test_release_lease_incomplete_transfer(self):
session = mock.Mock()
handle = rw_handles.VmdkHandle(session, None, 'fake-url', None)
handle._get_progress = mock.Mock(return_value=99)
session.invoke_api = mock.Mock()
handle._release_lease()
session.invoke_api.assert_called_with(handle._session.vim,
'HttpNfcLeaseAbort',
handle._lease)
class VmdkWriteHandleTest(base.TestCase):
"""Tests for VmdkWriteHandle."""
@ -276,9 +288,21 @@ class VmdkWriteHandleTest(base.TestCase):
session.invoke_api = mock.Mock(
side_effect=session_invoke_api_side_effect)
handle._get_progress = mock.Mock(return_value=100)
handle.close()
self.assertEqual(2, session.invoke_api.call_count)
def test_get_vm_incomplete_transfer(self):
session = self._create_mock_session()
handle = rw_handles.VmdkWriteHandle(session, '10.1.2.3', 443, 'rp-1',
'folder-1', None, 100)
handle._get_progress = mock.Mock(return_value=99)
session.invoke_api = mock.Mock()
self.assertRaises(exceptions.ImageTransferException,
handle.get_imported_vm)
class VmdkReadHandleTest(base.TestCase):
"""Tests for VmdkReadHandle."""
@ -390,6 +414,7 @@ class VmdkReadHandleTest(base.TestCase):
session.invoke_api = mock.Mock(
side_effect=session_invoke_api_side_effect)
handle._get_progress = mock.Mock(return_value=100)
handle.close()
self.assertEqual(2, session.invoke_api.call_count)

View File

@ -0,0 +1,5 @@
---
fixes:
- |
Incomplete VMDK upload during ImportVApp is falsely marked as successful
leading to a corrupted VM.