Merge "VMware: add support for VM diagnostics"

This commit is contained in:
Jenkins 2013-12-04 09:39:01 +00:00 committed by Gerrit Code Review
commit 6728c7e353
4 changed files with 104 additions and 12 deletions

View File

@ -653,9 +653,23 @@ class VMwareAPIVMTestCase(test.NoDBTestCase):
instance=None) instance=None)
def test_get_diagnostics(self): def test_get_diagnostics(self):
# Simply tests that the VMwareESXDriver doesn't implement the self._create_vm()
# get_diagnostics API. expected = {'memoryReservation': 0, 'suspendInterval': 0,
self.assertRaises(NotImplementedError, self.conn.get_diagnostics, None) 'maxCpuUsage': 2000, 'toolsInstallerMounted': False,
'consumedOverheadMemory': 20, 'numEthernetCards': 1,
'numCpu': 1, 'featureRequirement': [{'key': 'cpuid.AES'}],
'memoryOverhead': 21417984,
'guestMemoryUsage': 0, 'connectionState': 'connected',
'memorySizeMB': 512, 'balloonedMemory': 0,
'vmPathName': 'fake_path', 'template': False,
'overallCpuUsage': 0, 'powerState': 'poweredOn',
'cpuReservation': 0, 'overallCpuDemand': 0,
'numVirtualDisks': 1, 'hostMemoryUsage': 141}
expected = dict([('vmware:' + k, v) for k, v in expected.items()])
self.assertThat(
self.conn.get_diagnostics({'name': 1, 'uuid': self.uuid,
'node': self.instance_node}),
matchers.DictMatches(expected))
def test_get_console_output(self): def test_get_console_output(self):
self._create_instance_in_the_db() self._create_instance_in_the_db()
@ -1215,13 +1229,6 @@ class VMwareAPIVCDriverTestCase(VMwareAPIVMTestCase):
self.conn.unplug_vifs, self.conn.unplug_vifs,
instance=self.instance, network_info=None) instance=self.instance, network_info=None)
def test_get_diagnostics(self):
# Tests that the VMwareVCDriver doesn't implement get_diagnostics.
self._create_instance_in_the_db()
self.assertRaises(NotImplementedError,
self.conn.get_diagnostics,
self.instance)
def test_migrate_disk_and_power_off(self): def test_migrate_disk_and_power_off(self):
def fake_update_instance_progress(context, instance, step, def fake_update_instance_progress(context, instance, step,
total_steps): total_steps):

View File

@ -325,6 +325,38 @@ class VirtualMachine(ManagedObject):
self.set("config.extraConfig", kwargs.get("extra_config", None)) self.set("config.extraConfig", kwargs.get("extra_config", None))
self.set('runtime.host', kwargs.get("runtime_host", None)) self.set('runtime.host', kwargs.get("runtime_host", None))
self.device = kwargs.get("virtual_device") self.device = kwargs.get("virtual_device")
# Sample of diagnostics data is below.
config = [
('template', False),
('vmPathName', 'fake_path'),
('memorySizeMB', 512),
('cpuReservation', 0),
('memoryReservation', 0),
('numCpu', 1),
('numEthernetCards', 1),
('numVirtualDisks', 1)]
self.set("summary.config", config)
quickStats = [
('overallCpuUsage', 0),
('overallCpuDemand', 0),
('guestMemoryUsage', 0),
('hostMemoryUsage', 141),
('balloonedMemory', 0),
('consumedOverheadMemory', 20)]
self.set("summary.quickStats", quickStats)
key1 = {'key': 'cpuid.AES'}
key2 = {'key': 'cpuid.AVX'}
runtime = [
('connectionState', 'connected'),
('powerState', 'poweredOn'),
('toolsInstallerMounted', False),
('suspendInterval', 0),
('memoryOverhead', 21417984),
('maxCpuUsage', 2000),
('featureRequirement', [key1, key2])]
self.set("summary.runtime", runtime)
def reconfig(self, factory, val): def reconfig(self, factory, val):
""" """

View File

@ -51,6 +51,32 @@ def get_moref(value, type):
return moref return moref
def object_to_dict(obj, list_depth=1):
"""Convert Suds object into serializable format.
The calling function can limit the amount of list entries that
are converted.
"""
d = {}
for k, v in suds.sudsobject.asdict(obj).iteritems():
if hasattr(v, '__keylist__'):
d[k] = object_to_dict(v, list_depth=list_depth)
elif isinstance(v, list):
d[k] = []
used = 0
for item in v:
used = used + 1
if used > list_depth:
break
if hasattr(item, '__keylist__'):
d[k].append(object_to_dict(item, list_depth=list_depth))
else:
d[k].append(item)
else:
d[k] = v
return d
class VIMMessagePlugin(suds.plugin.MessagePlugin): class VIMMessagePlugin(suds.plugin.MessagePlugin):
def addAttributeForValue(self, node): def addAttributeForValue(self, node):
# suds does not handle AnyType properly. # suds does not handle AnyType properly.

View File

@ -46,6 +46,7 @@ from nova import utils
from nova.virt import configdrive from nova.virt import configdrive
from nova.virt import driver from nova.virt import driver
from nova.virt.vmwareapi import vif as vmwarevif from nova.virt.vmwareapi import vif as vmwarevif
from nova.virt.vmwareapi import vim
from nova.virt.vmwareapi import vim_util from nova.virt.vmwareapi import vim_util
from nova.virt.vmwareapi import vm_util from nova.virt.vmwareapi import vm_util
from nova.virt.vmwareapi import vmware_images from nova.virt.vmwareapi import vmware_images
@ -1294,10 +1295,36 @@ class VMwareVMOps(object):
'num_cpu': int(query['summary.config.numCpu']), 'num_cpu': int(query['summary.config.numCpu']),
'cpu_time': 0} 'cpu_time': 0}
def _get_diagnostic_from_object_properties(self, props, wanted_props):
diagnostics = {}
while props:
for elem in props.objects:
for prop in elem.propSet:
if prop.name in wanted_props:
prop_dict = vim.object_to_dict(prop.val, list_depth=1)
diagnostics.update(prop_dict)
token = vm_util._get_token(props)
if not token:
break
props = self._session._call_method(vim_util,
"continue_to_get_objects",
token)
return diagnostics
def get_diagnostics(self, instance): def get_diagnostics(self, instance):
"""Return data about VM diagnostics.""" """Return data about VM diagnostics."""
msg = _("get_diagnostics not implemented for vmwareapi") vm_ref = vm_util.get_vm_ref(self._session, instance)
raise NotImplementedError(msg) lst_properties = ["summary.config",
"summary.quickStats",
"summary.runtime"]
vm_props = self._session._call_method(vim_util,
"get_object_properties", None, vm_ref, "VirtualMachine",
lst_properties)
data = self._get_diagnostic_from_object_properties(vm_props,
set(lst_properties))
# Add a namespace to all of the diagnostsics
return dict([('vmware:' + k, v) for k, v in data.items()])
def get_console_output(self, instance): def get_console_output(self, instance):
"""Return snapshot of console.""" """Return snapshot of console."""