From 593152d8d8b34a17beed3226fef40275fb4e15dd Mon Sep 17 00:00:00 2001 From: Lucian Petrut Date: Tue, 8 Jan 2019 13:21:21 +0200 Subject: [PATCH] Silently continue when disconnecting missing vhds os-win should silently pass when requested to disconnect a vhd that's missing. At the moment, it's erroring out, which prevents some Nova instances from being cleaned up. This change checks if the image to be disconnected actually exists before attempting to open it. Change-Id: Ic734d38e1939165a89a79842d37e98b4cbbcb3bf Closes-Bug: #1810927 --- .../utils/storage/virtdisk/test_vhdutils.py | 29 ++++++++++++------- os_win/utils/storage/virtdisk/vhdutils.py | 5 ++++ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/os_win/tests/unit/utils/storage/virtdisk/test_vhdutils.py b/os_win/tests/unit/utils/storage/virtdisk/test_vhdutils.py index f63708b8..b68bfeeb 100644 --- a/os_win/tests/unit/utils/storage/virtdisk/test_vhdutils.py +++ b/os_win/tests/unit/utils/storage/virtdisk/test_vhdutils.py @@ -817,23 +817,30 @@ class VHDUtilsTestCase(test_base.BaseTestCase): bool(attach_flag & w_const.ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME)) + @ddt.data(True, False) + @mock.patch('os.path.exists') @mock.patch.object(vhdutils.VHDUtils, '_open') - def test_detach_virtual_disk(self, mock_open): + def test_detach_virtual_disk(self, exists, mock_open, mock_exists): + mock_exists.return_value = exists self._mock_run.return_value = w_const.ERROR_NOT_READY self._vhdutils.detach_virtual_disk(mock.sentinel.vhd_path) - mock_open.assert_called_once_with( - mock.sentinel.vhd_path, - open_access_mask=w_const.VIRTUAL_DISK_ACCESS_DETACH) + mock_exists.assert_called_once_with(mock.sentinel.vhd_path) + if exists: + mock_open.assert_called_once_with( + mock.sentinel.vhd_path, + open_access_mask=w_const.VIRTUAL_DISK_ACCESS_DETACH) - self._mock_run.assert_called_once_with( - vhdutils.virtdisk.DetachVirtualDisk, - mock_open.return_value, - 0, 0, - ignored_error_codes=[w_const.ERROR_NOT_READY], - **self._run_args) - self._mock_close.assert_called_once_with(mock_open.return_value) + self._mock_run.assert_called_once_with( + vhdutils.virtdisk.DetachVirtualDisk, + mock_open.return_value, + 0, 0, + ignored_error_codes=[w_const.ERROR_NOT_READY], + **self._run_args) + self._mock_close.assert_called_once_with(mock_open.return_value) + else: + mock_open.assert_not_called() @mock.patch.object(vhdutils.VHDUtils, '_open') def test_get_virtual_disk_physical_path(self, mock_open): diff --git a/os_win/utils/storage/virtdisk/vhdutils.py b/os_win/utils/storage/virtdisk/vhdutils.py index 36e1911e..361e9305 100644 --- a/os_win/utils/storage/virtdisk/vhdutils.py +++ b/os_win/utils/storage/virtdisk/vhdutils.py @@ -589,6 +589,11 @@ class VHDUtils(object): return handle def detach_virtual_disk(self, vhd_path): + if not os.path.exists(vhd_path): + LOG.debug("Image %s could not be found. Skipping detach.", + vhd_path) + return + open_access_mask = w_const.VIRTUAL_DISK_ACCESS_DETACH handle = self._open(vhd_path, open_access_mask=open_access_mask)