summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorin Hochstein <lorin@isi.edu>2011-10-27 20:35:48 -0400
committerLorin Hochstein <lorin@isi.edu>2011-10-27 21:37:12 -0400
commit0cf3789014ccccacb435d3a5c3d74afd304c7b42 (patch)
tree45e69328a2171467c8c3dfb4d3291b2a80ac148b
parent3c3fbaf552948d07c80a5f22aada5f046c3be67b (diff)
downloadnova-0cf3789014ccccacb435d3a5c3d74afd304c7b42.tar.gz
nova-0cf3789014ccccacb435d3a5c3d74afd304c7b42.tar.xz
nova-0cf3789014ccccacb435d3a5c3d74afd304c7b42.zip
Added code to libvirt backend to report state info.
Also renamed property variable in Xen code to make it consistent with nova conventions. Implements blueprint kvm-report-capabilities Change-Id: I7953e857d9b8ce4b410c31b82cead7aaa3fb911f
-rw-r--r--nova/tests/test_libvirt.py62
-rw-r--r--nova/virt/libvirt/connection.py58
-rw-r--r--nova/virt/xenapi_conn.py6
3 files changed, 119 insertions, 7 deletions
diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py
index b7864c9dd..d4db164c9 100644
--- a/nova/tests/test_libvirt.py
+++ b/nova/tests/test_libvirt.py
@@ -1076,6 +1076,68 @@ class LibvirtConnTestCase(test.TestCase):
self.assertRaises(NotImplementedError, compute_driver.reboot, *args)
+class HostStateTestCase(test.TestCase):
+
+ cpu_info = '{"vendor": "Intel", "model": "pentium", "arch": "i686", '\
+ '"features": ["ssse3", "monitor", "pni", "sse2", "sse", "fxsr", '\
+ '"clflush", "pse36", "pat", "cmov", "mca", "pge", "mtrr", "sep", '\
+ '"apic"], "topology": {"cores": "1", "threads": "1", "sockets": "1"}}'
+
+ class FakeConnection(object):
+ """Fake connection object"""
+
+ def get_vcpu_total(self):
+ return 1
+
+ def get_vcpu_used(self):
+ return 0
+
+ def get_cpu_info(self):
+ return HostStateTestCase.cpu_info
+
+ def get_local_gb_total(self):
+ return 100
+
+ def get_local_gb_used(self):
+ return 20
+
+ def get_memory_mb_total(self):
+ return 497
+
+ def get_memory_mb_used(self):
+ return 88
+
+ def get_hypervisor_type(self):
+ return 'QEMU'
+
+ def get_hypervisor_version(self):
+ return 13091
+
+ def test_update_status(self):
+ self.mox.StubOutWithMock(connection, 'get_connection')
+ connection.get_connection(True).AndReturn(self.FakeConnection())
+
+ self.mox.ReplayAll()
+ hs = connection.HostState(True)
+ stats = hs._stats
+ self.assertEquals(stats["vcpus"], 1)
+ self.assertEquals(stats["vcpus_used"], 0)
+ self.assertEquals(stats["cpu_info"], \
+ {"vendor": "Intel", "model": "pentium", "arch": "i686",
+ "features": ["ssse3", "monitor", "pni", "sse2", "sse", "fxsr",
+ "clflush", "pse36", "pat", "cmov", "mca", "pge",
+ "mtrr", "sep", "apic"],
+ "topology": {"cores": "1", "threads": "1", "sockets": "1"}
+ })
+ self.assertEquals(stats["disk_total"], 100)
+ self.assertEquals(stats["disk_used"], 20)
+ self.assertEquals(stats["disk_available"], 80)
+ self.assertEquals(stats["host_memory_total"], 497)
+ self.assertEquals(stats["host_memory_free"], 409)
+ self.assertEquals(stats["hypervisor_type"], 'QEMU')
+ self.assertEquals(stats["hypervisor_version"], 13091)
+
+
class NWFilterFakes:
def __init__(self):
self.filters = {}
diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py
index 3e39482d8..20bd83722 100644
--- a/nova/virt/libvirt/connection.py
+++ b/nova/virt/libvirt/connection.py
@@ -196,6 +196,12 @@ class LibvirtConnection(driver.ComputeDriver):
driver_class = utils.import_class(driver)
self.volume_drivers[driver_type] = driver_class(self)
+ @property
+ def host_state(self):
+ if not self._host_state:
+ self._host_state = HostState(self._session)
+ return self._host_state
+
def init_host(self, host):
# NOTE(nsokolov): moved instance restarting to ComputeManager
pass
@@ -1930,12 +1936,18 @@ class LibvirtConnection(driver.ComputeDriver):
network_info=network_info)
def update_host_status(self):
- """See xenapi_conn.py implementation."""
- pass
+ """Retrieve status info from libvirt.
+
+ Query libvirt to get the state of the compute node, such
+ as memory and disk usage.
+ """
+ return self.host_state.update_status()
def get_host_stats(self, refresh=False):
- """See xenapi_conn.py implementation."""
- pass
+ """Return the current state of the host.
+
+ If 'refresh' is True, run update the stats first."""
+ return self.host_state.get_host_stats(refresh=refresh)
def host_power_action(self, host, action):
"""Reboots, shuts down or powers up the host."""
@@ -1944,3 +1956,41 @@ class LibvirtConnection(driver.ComputeDriver):
def set_host_enabled(self, host, enabled):
"""Sets the specified host's ability to accept new instances."""
pass
+
+
+class HostState(object):
+ """Manages information about the compute node through libvirt"""
+ def __init__(self, read_only):
+ super(HostState, self).__init__()
+ self.read_only = read_only
+ self._stats = {}
+ self.connection = None
+ self.update_status()
+
+ def get_host_stats(self, refresh=False):
+ """Return the current state of the host.
+
+ If 'refresh' is True, run update the stats first."""
+ if refresh:
+ self.update_status()
+ return self._stats
+
+ def update_status(self):
+ """Retrieve status info from libvirt."""
+ LOG.debug(_("Updating host stats"))
+ if self.connection is None:
+ self.connection = get_connection(self.read_only)
+ data = {}
+ data["vcpus"] = self.connection.get_vcpu_total()
+ data["vcpus_used"] = self.connection.get_vcpu_used()
+ data["cpu_info"] = utils.loads(self.connection.get_cpu_info())
+ data["disk_total"] = self.connection.get_local_gb_total()
+ data["disk_used"] = self.connection.get_local_gb_used()
+ data["disk_available"] = data["disk_total"] - data["disk_used"]
+ data["host_memory_total"] = self.connection.get_memory_mb_total()
+ data["host_memory_free"] = data["host_memory_total"] - \
+ self.connection.get_memory_mb_used()
+ data["hypervisor_type"] = self.connection.get_hypervisor_type()
+ data["hypervisor_version"] = self.connection.get_hypervisor_version()
+
+ self._stats = data
diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py
index 0aa8d45a5..2dc57c5ae 100644
--- a/nova/virt/xenapi_conn.py
+++ b/nova/virt/xenapi_conn.py
@@ -174,7 +174,7 @@ class XenAPIConnection(driver.ComputeDriver):
self._host_state = None
@property
- def HostState(self):
+ def host_state(self):
if not self._host_state:
self._host_state = HostState(self._session)
return self._host_state
@@ -377,12 +377,12 @@ class XenAPIConnection(driver.ComputeDriver):
def update_host_status(self):
"""Update the status info of the host, and return those values
to the calling program."""
- return self.HostState.update_status()
+ return self.host_state.update_status()
def get_host_stats(self, refresh=False):
"""Return the current state of the host. If 'refresh' is
True, run the update first."""
- return self.HostState.get_host_stats(refresh=refresh)
+ return self.host_state.get_host_stats(refresh=refresh)
def host_power_action(self, host, action):
"""The only valid values for 'action' on XenServer are 'reboot' or