VMWare: Fix nova-compute crash when instance datastore not available

During nova-compute service startup, init_host will try to get_info for
instances. If datastore of certain instances become not reachable, some
VM properties like 'summary.config.memorySizeMB' will not be available.
This will cause nova-compute process exit with error.

Change-Id: I6753ce5658b629c216ebfbaab610c8fd0755466a
Closes-Bug: #1337236
This commit is contained in:
ZHU ZHU 2014-07-03 03:19:19 -05:00 committed by Zhu Zhu
parent 2dea6662cd
commit 488f88c4d0
2 changed files with 42 additions and 19 deletions

View File

@ -269,9 +269,9 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
mock_save.assert_called_once_with()
self.assertEqual(50, instance.progress)
@mock.patch('nova.virt.vmwareapi.vm_util.get_vm_ref',
return_value='fake_ref')
def test_get_info(self, mock_get_vm_ref):
@mock.patch.object(vm_util, 'get_vm_ref', return_value='fake_ref')
@mock.patch.object(driver.VMwareAPISession, '_call_method')
def test_get_info(self, mock_call, mock_get_vm_ref):
props = ['summary.config.numCpu', 'summary.config.memorySizeMB',
'runtime.powerState']
prop_cpu = vmwareapi_fake.Prop(props[0], 4)
@ -281,20 +281,42 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
obj_content = vmwareapi_fake.ObjectContent(None, prop_list=prop_list)
result = vmwareapi_fake.FakeRetrieveResult()
result.add_object(obj_content)
mock_call_method = mock.Mock(return_value=result)
with mock.patch.object(self._session, '_call_method',
mock_call_method):
info = self._vmops.get_info(self._instance)
mock_call_method.assert_called_once_with(vim_util,
'get_object_properties', None, 'fake_ref', 'VirtualMachine',
props)
mock_get_vm_ref.assert_called_once_with(self._session,
self._instance)
self.assertEqual(power_state.RUNNING, info['state'])
self.assertEqual(128 * 1024, info['max_mem'])
self.assertEqual(128 * 1024, info['mem'])
self.assertEqual(4, info['num_cpu'])
self.assertEqual(0, info['cpu_time'])
mock_call.return_value = result
info = self._vmops.get_info(self._instance)
mock_call.assert_called_once_with(vim_util,
'get_object_properties', None, 'fake_ref', 'VirtualMachine',
props)
mock_get_vm_ref.assert_called_once_with(self._session,
self._instance)
self.assertEqual(power_state.RUNNING, info['state'])
self.assertEqual(128 * 1024, info['max_mem'])
self.assertEqual(128 * 1024, info['mem'])
self.assertEqual(4, info['num_cpu'])
self.assertEqual(0, info['cpu_time'])
@mock.patch.object(vm_util, 'get_vm_ref', return_value='fake_ref')
@mock.patch.object(driver.VMwareAPISession, '_call_method')
def test_get_info_when_ds_unavailable(self, mock_call, mock_get_vm_ref):
props = ['summary.config.numCpu', 'summary.config.memorySizeMB',
'runtime.powerState']
prop_state = vmwareapi_fake.Prop(props[2], 'poweredOff')
# when vm's ds not available, only power state can be received
prop_list = [prop_state]
obj_content = vmwareapi_fake.ObjectContent(None, prop_list=prop_list)
result = vmwareapi_fake.FakeRetrieveResult()
result.add_object(obj_content)
mock_call.return_value = result
info = self._vmops.get_info(self._instance)
mock_call.assert_called_once_with(vim_util,
'get_object_properties', None, 'fake_ref', 'VirtualMachine',
props)
mock_get_vm_ref.assert_called_once_with(self._session,
self._instance)
self.assertEqual(power_state.SHUTDOWN, info['state'])
self.assertEqual(0, info['max_mem'])
self.assertEqual(0, info['mem'])
self.assertEqual(0, info['num_cpu'])
self.assertEqual(0, info['cpu_time'])
def _test_get_datacenter_ref_and_name(self, ds_ref_exists=False):
instance_ds_ref = mock.Mock()

View File

@ -1155,11 +1155,12 @@ class VMwareVMOps(object):
lst_properties)
query = vm_util.get_values_from_object_properties(
self._session, vm_props)
max_mem = int(query['summary.config.memorySizeMB']) * 1024
max_mem = int(query.get('summary.config.memorySizeMB', 0)) * 1024
num_cpu = int(query.get('summary.config.numCpu', 0))
return {'state': VMWARE_POWER_STATES[query['runtime.powerState']],
'max_mem': max_mem,
'mem': max_mem,
'num_cpu': int(query['summary.config.numCpu']),
'num_cpu': num_cpu,
'cpu_time': 0}
def _get_diagnostics(self, instance):