From 5d857a2cad43ed2a258fdda88bfcb943f49fca17 Mon Sep 17 00:00:00 2001 From: Qiaowei Ren Date: Thu, 7 Aug 2014 10:14:53 +0800 Subject: [PATCH] XenAPI support: Changes for cpu_util Implemented inspect_cpu_util() to inspect the CPU utilization (%) for an instance. Change-Id: I0cd1c926f074be632d9c5ce071dfd4d0d3ba78a7 Implements: blueprint xenapi-support --- ceilometer/compute/virt/xenapi/inspector.py | 31 +++++++++++++++++++ .../compute/virt/xenapi/test_inspector.py | 28 +++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/ceilometer/compute/virt/xenapi/inspector.py b/ceilometer/compute/virt/xenapi/inspector.py index bc3e98558..6a9086495 100644 --- a/ceilometer/compute/virt/xenapi/inspector.py +++ b/ceilometer/compute/virt/xenapi/inspector.py @@ -22,6 +22,7 @@ try: except ImportError: api = None +from ceilometer.compute.pollsters import util from ceilometer.compute.virt import inspector as virt_inspector from ceilometer.openstack.common.gettextutils import _ @@ -96,6 +97,18 @@ class XenapiInspector(virt_inspector.Inspector): for vm_ref in vms.keys(): yield vm_ref, vms[vm_ref] + def _lookup_by_name(self, instance_name): + vm_refs = self._call_xenapi("VM.get_by_name_label", instance_name) + n = len(vm_refs) + if n == 0: + raise virt_inspector.InstanceNotFoundException( + _('VM %s not found in XenServer') % instance_name) + elif n > 1: + raise XenapiException( + _('Multiple VM %s found in XenServer') % instance_name) + else: + return vm_refs[0] + def inspect_instances(self): for vm_ref, vm_rec in self._list_vms(): name = vm_rec['name_label'] @@ -103,3 +116,21 @@ class XenapiInspector(virt_inspector.Inspector): uuid = other_config.get('nova_uuid') if uuid: yield virt_inspector.Instance(name, uuid) + + def inspect_cpu_util(self, instance, duration=None): + instance_name = util.instance_name(instance) + vm_ref = self._lookup_by_name(instance_name) + metrics_ref = self._call_xenapi("VM.get_metrics", vm_ref) + metrics_rec = self._call_xenapi("VM_metrics.get_record", + metrics_ref) + vcpus_number = metrics_rec['VCPUs_number'] + vcpus_utils = metrics_rec['VCPUs_utilisation'] + if len(vcpus_utils) == 0: + msg = _("Could not get VM %s CPU Utilization") % instance_name + raise XenapiException(msg) + + utils = 0.0 + for num in range(int(vcpus_number)): + utils += vcpus_utils.get(str(num)) + utils = utils / int(vcpus_number) * 100 + return virt_inspector.CPUUtilStats(util=utils) diff --git a/ceilometer/tests/compute/virt/xenapi/test_inspector.py b/ceilometer/tests/compute/virt/xenapi/test_inspector.py index 8e5c6b045..fface5635 100644 --- a/ceilometer/tests/compute/virt/xenapi/test_inspector.py +++ b/ceilometer/tests/compute/virt/xenapi/test_inspector.py @@ -19,6 +19,7 @@ import mock from oslotest import base +from ceilometer.compute.virt import inspector as virt_inspector from ceilometer.compute.virt.xenapi import inspector as xenapi_inspector @@ -46,3 +47,30 @@ class TestXenapiInspection(base.BaseTestCase): inspected_instance = inspected_instances[0] self.assertEqual('fake_name', inspected_instance.name) self.assertEqual('fake_uuid', inspected_instance.UUID) + + def test_inspect_cpu_util(self): + fake_instance = {'OS-EXT-SRV-ATTR:instance_name': 'fake_instance_name', + 'id': 'fake_instance_id'} + fake_stat = virt_inspector.CPUUtilStats(util=40) + + def fake_xenapi_request(method, args): + metrics_rec = { + 'memory_actual': '536870912', + 'VCPUs_number': '1', + 'VCPUs_utilisation': {'0': 0.4, } + } + + if method == 'VM.get_by_name_label': + return ['vm_ref'] + elif method == 'VM.get_metrics': + return 'metrics_ref' + elif method == 'VM_metrics.get_record': + return metrics_rec + else: + return None + + session = self.inspector.session + with mock.patch.object(session, 'xenapi_request', + side_effect=fake_xenapi_request): + cpu_util_stat = self.inspector.inspect_cpu_util(fake_instance) + self.assertEqual(fake_stat, cpu_util_stat)