summaryrefslogtreecommitdiff
path: root/ceilometer/compute
diff options
context:
space:
mode:
authorClaudiu Belu <cbelu@cloudbasesolutions.com>2018-02-22 18:06:10 +0200
committerClaudiu Belu <cbelu@cloudbasesolutions.com>2018-02-22 18:11:49 +0200
commite2a3542fe8d5f562b590192dc34ece5eafa51931 (patch)
tree223dd6ff6d91e0ad5a2c3301bacc6d0167408196 /ceilometer/compute
parent01670dfcb47a78b8ee04f27203f027a31395d854 (diff)
downloadceilometer-e2a3542fe8d5f562b590192dc34ece5eafa51931.tar.gz
hyper-v: Converts all os-win exceptions
When os-win was first introduced, a decorator which converts all os-win exceptions to virt inspector exceptions has been added to the HyperVInspector. However, the decorator works as intended for methods that return values, and not for the ones that yield (they return a generator). This patch makes sure that exceptions are converted properly for yielding methods as well. Closes-Bug #1751088 Change-Id: I7d09e1860c6940758f0d0965fedfe4dd285e0cae
Diffstat (limited to 'ceilometer/compute')
-rw-r--r--ceilometer/compute/virt/hyperv/inspector.py76
1 files changed, 43 insertions, 33 deletions
diff --git a/ceilometer/compute/virt/hyperv/inspector.py b/ceilometer/compute/virt/hyperv/inspector.py
index f1819f22..3d4fcb42 100644
--- a/ceilometer/compute/virt/hyperv/inspector.py
+++ b/ceilometer/compute/virt/hyperv/inspector.py
@@ -26,39 +26,45 @@ from ceilometer.compute.pollsters import util
from ceilometer.compute.virt import inspector as virt_inspector
-def convert_exceptions(function, exception_map):
+def convert_exceptions(exception_map, yields=True):
expected_exceptions = tuple(exception_map.keys())
- @functools.wraps(function)
- def wrapper(*args, **kwargs):
- try:
- return function(*args, **kwargs)
- except expected_exceptions as ex:
- # exception might be a subclass of an expected exception.
- for expected in expected_exceptions:
- if isinstance(ex, expected):
- raised_exception = exception_map[expected]
- break
-
- exc_info = sys.exc_info()
- # NOTE(claudiub): Python 3 raises the exception object given as
- # the second argument in six.reraise.
- # The original message will be maintained by passing the original
- # exception.
- exc = raised_exception(six.text_type(exc_info[1]))
- six.reraise(raised_exception, exc, exc_info[2])
- return wrapper
-
-
-def decorate_all_methods(decorator, *args, **kwargs):
- def decorate(cls):
- for attr in cls.__dict__:
- class_member = getattr(cls, attr)
- if callable(class_member):
- setattr(cls, attr, decorator(class_member, *args, **kwargs))
- return cls
-
- return decorate
+ def _reraise_exception(exc):
+ # exception might be a subclass of an expected exception.
+ for expected in expected_exceptions:
+ if isinstance(exc, expected):
+ raised_exception = exception_map[expected]
+ break
+
+ exc_info = sys.exc_info()
+ # NOTE(claudiub): Python 3 raises the exception object given as
+ # the second argument in six.reraise.
+ # The original message will be maintained by passing the
+ # original exception.
+ exc = raised_exception(six.text_type(exc_info[1]))
+ six.reraise(raised_exception, exc, exc_info[2])
+
+ def decorator(function):
+ if yields:
+ @functools.wraps(function)
+ def wrapper(*args, **kwargs):
+ try:
+ # NOTE(claudiub): We're consuming the function's yield in
+ # order to avoid yielding a generator.
+ for item in function(*args, **kwargs):
+ yield item
+ except expected_exceptions as ex:
+ _reraise_exception(ex)
+ else:
+ @functools.wraps(function)
+ def wrapper(*args, **kwargs):
+ try:
+ return function(*args, **kwargs)
+ except expected_exceptions as ex:
+ _reraise_exception(ex)
+
+ return wrapper
+ return decorator
exception_conversion_map = collections.OrderedDict([
@@ -69,12 +75,11 @@ exception_conversion_map = collections.OrderedDict([
(os_win_exc.OSWinException, virt_inspector.InspectorException),
])
-# NOTE(claudiub): the purpose of the decorator below is to prevent any
+# NOTE(claudiub): the purpose of the decorators below is to prevent any
# os_win exceptions (subclasses of OSWinException) to leak outside of the
# HyperVInspector.
-@decorate_all_methods(convert_exceptions, exception_conversion_map)
class HyperVInspector(virt_inspector.Inspector):
def __init__(self, conf):
@@ -91,6 +96,7 @@ class HyperVInspector(virt_inspector.Inspector):
return float(host_cpu_clock * host_cpu_count)
+ @convert_exceptions(exception_conversion_map, yields=False)
def inspect_instance(self, instance, duration):
instance_name = util.instance_name(instance)
(cpu_clock_used,
@@ -105,6 +111,7 @@ class HyperVInspector(virt_inspector.Inspector):
cpu_time=cpu_time,
memory_usage=memory_usage)
+ @convert_exceptions(exception_conversion_map)
def inspect_vnics(self, instance, duration):
instance_name = util.instance_name(instance)
for vnic_metrics in self._utils.get_vnic_metrics(instance_name):
@@ -122,6 +129,7 @@ class HyperVInspector(virt_inspector.Inspector):
tx_drop=0,
tx_errors=0)
+ @convert_exceptions(exception_conversion_map)
def inspect_disks(self, instance, duration):
instance_name = util.instance_name(instance)
for disk_metrics in self._utils.get_disk_metrics(instance_name):
@@ -134,6 +142,7 @@ class HyperVInspector(virt_inspector.Inspector):
write_bytes=disk_metrics['write_mb'] * units.Mi,
errors=0, wr_total_times=0, rd_total_times=0)
+ @convert_exceptions(exception_conversion_map)
def inspect_disk_latency(self, instance, duration):
instance_name = util.instance_name(instance)
for disk_metrics in self._utils.get_disk_latency_metrics(
@@ -142,6 +151,7 @@ class HyperVInspector(virt_inspector.Inspector):
device=disk_metrics['instance_id'],
disk_latency=disk_metrics['disk_latency'] / 1000)
+ @convert_exceptions(exception_conversion_map)
def inspect_disk_iops(self, instance, duration):
instance_name = util.instance_name(instance)
for disk_metrics in self._utils.get_disk_iops_count(instance_name):