Merge "Fix wait for detach code to handle 'disk not found error'"
This commit is contained in:
commit
187aa6dd74
@ -270,6 +270,26 @@ class GuestTestCase(test.NoDBTestCase):
|
|||||||
exception.DeviceNotFound, self.guest.detach_device_with_retry,
|
exception.DeviceNotFound, self.guest.detach_device_with_retry,
|
||||||
get_config, "/dev/vdb", persistent=True, live=True)
|
get_config, "/dev/vdb", persistent=True, live=True)
|
||||||
|
|
||||||
|
@mock.patch.object(libvirt_guest.Guest, "detach_device")
|
||||||
|
def test_detach_device_with_retry_operation_failed(self, mock_detach):
|
||||||
|
conf = mock.Mock(spec=vconfig.LibvirtConfigGuestDevice)
|
||||||
|
conf.to_xml.return_value = "</xml>"
|
||||||
|
get_config = mock.Mock(return_value=conf)
|
||||||
|
fake_device = "vdb"
|
||||||
|
fake_exc = fakelibvirt.make_libvirtError(
|
||||||
|
fakelibvirt.libvirtError,
|
||||||
|
msg="invalid argument: no target device vdb",
|
||||||
|
error_code=fakelibvirt.VIR_ERR_OPERATION_FAILED,
|
||||||
|
error_message="disk vdb not found",
|
||||||
|
error_domain=fakelibvirt.VIR_FROM_DOMAIN)
|
||||||
|
mock_detach.side_effect = [None, fake_exc]
|
||||||
|
retry_detach = self.guest.detach_device_with_retry(
|
||||||
|
get_config, fake_device, persistent=True, live=True,
|
||||||
|
inc_sleep_time=.01, max_retry_count=3)
|
||||||
|
# Some time later, we can do the wait/retry to ensure detach
|
||||||
|
self.domain.detachDeviceFlags.reset_mock()
|
||||||
|
self.assertRaises(exception.DeviceNotFound, retry_detach)
|
||||||
|
|
||||||
def test_get_xml_desc(self):
|
def test_get_xml_desc(self):
|
||||||
self.guest.get_xml_desc()
|
self.guest.get_xml_desc()
|
||||||
self.domain.XMLDesc.assert_called_once_with(flags=0)
|
self.domain.XMLDesc.assert_called_once_with(flags=0)
|
||||||
|
@ -375,10 +375,18 @@ class Guest(object):
|
|||||||
def _do_wait_and_retry_detach():
|
def _do_wait_and_retry_detach():
|
||||||
config = get_device_conf_func(device)
|
config = get_device_conf_func(device)
|
||||||
if config is not None:
|
if config is not None:
|
||||||
|
try:
|
||||||
# Device is already detached from persistent domain
|
# Device is already detached from persistent domain
|
||||||
# and only transient domain needs update
|
# and only transient domain needs update
|
||||||
self.detach_device(config, persistent=False, live=live)
|
self.detach_device(config, persistent=False, live=live)
|
||||||
# Raise error since the device still existed on the guest
|
except libvirt.libvirtError as ex:
|
||||||
|
with excutils.save_and_reraise_exception():
|
||||||
|
errcode = ex.get_error_code()
|
||||||
|
if errcode == libvirt.VIR_ERR_OPERATION_FAILED:
|
||||||
|
errmsg = ex.get_error_message()
|
||||||
|
if 'not found' in errmsg:
|
||||||
|
raise exception.DeviceNotFound(device=device)
|
||||||
|
|
||||||
reason = _("Unable to detach from guest transient domain.")
|
reason = _("Unable to detach from guest transient domain.")
|
||||||
raise exception.DeviceDetachFailed(device=device,
|
raise exception.DeviceDetachFailed(device=device,
|
||||||
reason=reason)
|
reason=reason)
|
||||||
|
Loading…
Reference in New Issue
Block a user