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)
def test_get_diagnostics(self):
# Simply tests that the VMwareESXDriver doesn't implement the
# get_diagnostics API.
self.assertRaises(NotImplementedError, self.conn.get_diagnostics, None)
self._create_vm()
expected = {'memoryReservation': 0, 'suspendInterval': 0,
'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):
self._create_instance_in_the_db()
@ -1215,13 +1229,6 @@ class VMwareAPIVCDriverTestCase(VMwareAPIVMTestCase):
self.conn.unplug_vifs,
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 fake_update_instance_progress(context, instance, step,
total_steps):

View File

@ -325,6 +325,38 @@ class VirtualMachine(ManagedObject):
self.set("config.extraConfig", kwargs.get("extra_config", None))
self.set('runtime.host', kwargs.get("runtime_host", None))
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):
"""

View File

@ -51,6 +51,32 @@ def get_moref(value, type):
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):
def addAttributeForValue(self, node):
# 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 driver
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 vm_util
from nova.virt.vmwareapi import vmware_images
@ -1294,10 +1295,36 @@ class VMwareVMOps(object):
'num_cpu': int(query['summary.config.numCpu']),
'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):
"""Return data about VM diagnostics."""
msg = _("get_diagnostics not implemented for vmwareapi")
raise NotImplementedError(msg)
vm_ref = vm_util.get_vm_ref(self._session, instance)
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):
"""Return snapshot of console."""