Merge "VMware: add support for VM diagnostics"
This commit is contained in:
commit
6728c7e353
@ -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):
|
||||
|
@ -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):
|
||||
"""
|
||||
|
@ -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.
|
||||
|
@ -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."""
|
||||
|
Loading…
Reference in New Issue
Block a user