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)
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