Avoid propagating wmi exceptions for soft shutdown
The soft shutdown operation is expected to fail while the VM is still booting. The issue is that in some cases, os-win will propagate a wmi exception that Nova cannot handle: http://paste.openstack.org/raw/800833/ That's because of Msvm_ShutdownComponent.InitiateShutdown, an asynchronous WMI method that can sometimes throw a wmi exception right away. For now, we're taking care of this specific WMI call only. If needed, we may consider handling all async WMI methods by introducing a new decorator or helper function. Change-Id: I9263b14c3c343db6453645152cb9274e38864b48 Closes-Bug: #1907270
This commit is contained in:
parent
954693f5ff
commit
fa9061f31d
|
@ -233,6 +233,19 @@ class VMUtilsTestCase(test_base.OsWinBaseTestCase):
|
|||
self._vmutils._jobutils.check_ret_val.assert_called_once_with(
|
||||
self._FAKE_RET_VAL, None)
|
||||
|
||||
def test_soft_shutdown_vm_wmi_exc(self):
|
||||
self._lookup_vm()
|
||||
mock_shutdown = mock.MagicMock()
|
||||
mock_shutdown.InitiateShutdown.side_effect = exceptions.x_wmi
|
||||
self._vmutils._conn.Msvm_ShutdownComponent.return_value = [
|
||||
mock_shutdown]
|
||||
|
||||
# We ensure that the wmi exception gets converted.
|
||||
self.assertRaises(
|
||||
exceptions.HyperVException,
|
||||
self._vmutils.soft_shutdown_vm,
|
||||
self._FAKE_VM_NAME)
|
||||
|
||||
def test_soft_shutdown_vm_no_component(self):
|
||||
mock_vm = self._lookup_vm()
|
||||
self._vmutils._conn.Msvm_ShutdownComponent.return_value = []
|
||||
|
|
|
@ -662,19 +662,26 @@ class VMUtils(baseutils.BaseUtilsVirt):
|
|||
return [nic.ElementName for nic in nics]
|
||||
|
||||
def soft_shutdown_vm(self, vm_name):
|
||||
vm = self._lookup_vm_check(vm_name, as_vssd=False)
|
||||
shutdown_component = self._conn.Msvm_ShutdownComponent(
|
||||
SystemName=vm.Name)
|
||||
try:
|
||||
vm = self._lookup_vm_check(vm_name, as_vssd=False)
|
||||
shutdown_component = self._conn.Msvm_ShutdownComponent(
|
||||
SystemName=vm.Name)
|
||||
|
||||
if not shutdown_component:
|
||||
# If no shutdown_component is found, it means the VM is already
|
||||
# in a shutdown state.
|
||||
return
|
||||
if not shutdown_component:
|
||||
# If no shutdown_component is found, it means the VM is already
|
||||
# in a shutdown state.
|
||||
return
|
||||
|
||||
reason = 'Soft shutdown requested by OpenStack Nova.'
|
||||
(ret_val, ) = shutdown_component[0].InitiateShutdown(Force=False,
|
||||
Reason=reason)
|
||||
self._jobutils.check_ret_val(ret_val, None)
|
||||
reason = 'Soft shutdown requested by OpenStack Nova.'
|
||||
(ret_val, ) = shutdown_component[0].InitiateShutdown(Force=False,
|
||||
Reason=reason)
|
||||
self._jobutils.check_ret_val(ret_val, None)
|
||||
except exceptions.x_wmi as ex:
|
||||
# This operation is expected to fail while the instance is booting.
|
||||
# In some cases, InitiateShutdown immediately throws an error
|
||||
# instead of returning an asynchronous job reference.
|
||||
msg = _("Soft shutdown failed. VM name: %s. Error: %s.")
|
||||
raise exceptions.HyperVException(msg % (vm_name, ex))
|
||||
|
||||
@_utils.retry_decorator(exceptions=exceptions.WMIJobFailed)
|
||||
def set_vm_state(self, vm_name, req_state):
|
||||
|
|
Loading…
Reference in New Issue