summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSandy Walsh <sandy.walsh@rackspace.com>2011-05-06 07:19:57 -0700
committerSandy Walsh <sandy.walsh@rackspace.com>2011-05-06 07:19:57 -0700
commitfa9eeb65533d897f6e81067986dc614582fb310a (patch)
tree645e126202d5e18d343298e4949aedf39c9d09da
parent114a55d0243f79db7ea1ef29830a9428dbf1aa33 (diff)
downloadnova-fa9eeb65533d897f6e81067986dc614582fb310a.tar.gz
nova-fa9eeb65533d897f6e81067986dc614582fb310a.tar.xz
nova-fa9eeb65533d897f6e81067986dc614582fb310a.zip
grabbed from dist-sched branch
-rw-r--r--nova/compute/manager.py17
-rw-r--r--nova/virt/hyperv.py9
-rw-r--r--nova/virt/libvirt_conn.py8
-rw-r--r--nova/virt/xenapi_conn.py69
4 files changed, 103 insertions, 0 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 1ff78007b..473f93170 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -1083,6 +1083,13 @@ class ComputeManager(manager.SchedulerDependentManager):
error_list.append(ex)
try:
+ self._report_driver_status()
+ except Exception as ex:
+ LOG.warning(_("Error during report_driver_status(): %s"),
+ unicode(ex))
+ error_list.append(ex)
+
+ try:
self._poll_instance_states(context)
except Exception as ex:
LOG.warning(_("Error during instance poll: %s"),
@@ -1091,6 +1098,16 @@ class ComputeManager(manager.SchedulerDependentManager):
return error_list
+ def _report_driver_status(self):
+ curr_time = time.time()
+ if curr_time - self._last_host_check > FLAGS.host_state_interval:
+ self._last_host_check = curr_time
+ LOG.info(_("Updating host status"))
+ # This will grab info about the host and queue it
+ # to be sent to the Schedulers.
+ self.update_service_capabilities(
+ self.driver.get_host_stats(refresh=True))
+
def _poll_instance_states(self, context):
vm_instances = self.driver.list_instances_detail()
vm_instances = dict((vm.name, vm) for vm in vm_instances)
diff --git a/nova/virt/hyperv.py b/nova/virt/hyperv.py
index 9026e737e..573e5130e 100644
--- a/nova/virt/hyperv.py
+++ b/nova/virt/hyperv.py
@@ -486,3 +486,12 @@ class HyperVConnection(driver.ComputeDriver):
def update_available_resource(self, ctxt, host):
"""This method is supported only by libvirt."""
return
+
+ def update_host_status(self):
+ """See xenapi_conn.py implementation."""
+ pass
+
+ def get_host_stats(self, refresh=False):
+ """See xenapi_conn.py implementation."""
+ pass
+
diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py
index 9780c69a6..555e44ce2 100644
--- a/nova/virt/libvirt_conn.py
+++ b/nova/virt/libvirt_conn.py
@@ -1582,6 +1582,14 @@ class LibvirtConnection(driver.ComputeDriver):
"""See comments of same method in firewall_driver."""
self.firewall_driver.unfilter_instance(instance_ref)
+ def update_host_status(self):
+ """See xenapi_conn.py implementation."""
+ pass
+
+ def get_host_stats(self, refresh=False):
+ """See xenapi_conn.py implementation."""
+ pass
+
class FirewallDriver(object):
def prepare_instance_filter(self, instance, network_info=None):
diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py
index 0cabccf08..63a53af2e 100644
--- a/nova/virt/xenapi_conn.py
+++ b/nova/virt/xenapi_conn.py
@@ -168,6 +168,13 @@ class XenAPIConnection(driver.ComputeDriver):
session = XenAPISession(url, user, pw)
self._vmops = VMOps(session)
self._volumeops = VolumeOps(session)
+ self._host_state = None
+
+ @property
+ def HostState(self):
+ if not self._host_state:
+ self._host_state = HostState(self.session)
+ return self._host_state
def init_host(self, host):
#FIXME(armando): implement this
@@ -315,6 +322,16 @@ class XenAPIConnection(driver.ComputeDriver):
"""This method is supported only by libvirt."""
raise NotImplementedError('This method is supported only by libvirt.')
+ 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()
+
+ 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)
+
class XenAPISession(object):
"""The session to invoke XenAPI SDK calls"""
@@ -436,6 +453,58 @@ class XenAPISession(object):
raise
+class HostState(object):
+ """Manages information about the XenServer host this compute
+ node is running on.
+ """
+ def __init__(self, session):
+ super(HostState, self).__init__()
+ self._session = session
+ self._stats = {}
+ self.update_status()
+
+ def get_host_stats(self, refresh=False):
+ """Return the current state of the host. If 'refresh' is
+ True, run the update first.
+ """
+ if refresh:
+ self.update_status()
+ return self._stats
+
+ def update_status(self):
+ """Since under Xenserver, a compute node runs on a given host,
+ we can get host status information using xenapi.
+ """
+ LOG.debug(_("Updating host stats"))
+ # Make it something unlikely to match any actual instance ID
+ task_id = random.randint(-80000, -70000)
+ task = self._session.async_call_plugin("xenhost", "host_data", {})
+ task_result = self._session.wait_for_task(task, task_id)
+ if not task_result:
+ task_result = json.dumps("")
+ try:
+ data = json.loads(task_result)
+ except ValueError as e:
+ # Invalid JSON object
+ LOG.error(_("Unable to get updated status: %s") % e)
+ return
+ # Get the SR usage
+ try:
+ sr_ref = vm_utils.safe_find_sr(self._session)
+ except exception.NotFound as e:
+ # No SR configured
+ LOG.error(_("Unable to get SR for this host: %s") % e)
+ return
+ sr_rec = self._session.get_xenapi().SR.get_record(sr_ref)
+ total = int(sr_rec["virtual_allocation"])
+ used = int(sr_rec["physical_utilisation"])
+ data["disk"] = dd = {}
+ dd["total"] = total
+ dd["used"] = used
+ dd["available"] = total - used
+ self._stats = data
+
+
def _parse_xmlrpc_value(val):
"""Parse the given value as if it were an XML-RPC value. This is
sometimes used as the format for the task.result field."""