summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell Bryant <rbryant@redhat.com>2012-07-20 10:32:23 -0400
committerRussell Bryant <rbryant@redhat.com>2012-07-25 19:48:30 -0400
commiteebc64f949ccb2acb7462efc18f538f1827985af (patch)
tree3dedcfd1e0a3d26fe3e370f80e3a84fbcbdbb2d9
parent9072290b22732f29152cca1bff54c7a0af5643f7 (diff)
downloadnova-eebc64f949ccb2acb7462efc18f538f1827985af.tar.gz
nova-eebc64f949ccb2acb7462efc18f538f1827985af.tar.xz
nova-eebc64f949ccb2acb7462efc18f538f1827985af.zip
Update decorators in compute manager.
This patch modifies two decorators in the compute manager: checks_instance_lock and wrap_instance_fault. Both of these assumed that the function they are wrapping takes two positional arguments: context and instance_uuid. They will automatically adapt to the new form that the functions they wrap will be taking. These functions will all be modified to take either a full instance dict or an instance_uuid for backwards compatibility. Part of blueprint no-db-messaging. Change-Id: I93e331706aed1c97877655ce54784a0dbd8de89e
-rw-r--r--nova/compute/manager.py94
1 files changed, 78 insertions, 16 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index e19a4ec90..3e66bd20f 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -36,6 +36,7 @@ terminating it.
import contextlib
import functools
+import inspect
import os
import socket
import sys
@@ -165,14 +166,17 @@ def publisher_id(host=None):
def checks_instance_lock(function):
"""Decorator to prevent action against locked instances for non-admins."""
- @functools.wraps(function)
- def decorated_function(self, context, instance_uuid, *args, **kwargs):
- LOG.info(_("check_instance_lock: decorating: |%s|"), function,
- context=context, instance_uuid=instance_uuid)
- LOG.info(_("check_instance_lock: arguments: |%(self)s| |%(context)s|")
- % locals(), context=context, instance_uuid=instance_uuid)
+
+ # NOTE(russellb): There are two versions of the checks_instance_lock
+ # decorator. This function is the core code for it. This just serves
+ # as a transition from when every function expected a context
+ # and instance_uuid as positional arguments to where everything is a kwarg,
+ # and the function may get either an instance_uuid or an instance.
+ def _checks_instance_lock_core(self, cb, context, instance_uuid,
+ *args, **kwargs):
locked = self._get_lock(context, instance_uuid)
admin = context.is_admin
+
LOG.info(_("check_instance_lock: locked: |%s|"), locked,
context=context, instance_uuid=instance_uuid)
LOG.info(_("check_instance_lock: admin: |%s|"), admin,
@@ -180,15 +184,39 @@ def checks_instance_lock(function):
# if admin or unlocked call function otherwise log error
if admin or not locked:
- LOG.info(_("check_instance_lock: executing: |%s|"), function,
- context=context, instance_uuid=instance_uuid)
- function(self, context, instance_uuid, *args, **kwargs)
+ cb(self, context, *args, **kwargs)
else:
- LOG.error(_("check_instance_lock: not executing |%s|"),
- function, context=context, instance_uuid=instance_uuid)
return False
- return decorated_function
+ @functools.wraps(function)
+ def decorated_function(self, context, instance_uuid, *args, **kwargs):
+
+ def _cb(self, context, *args, **kwargs):
+ function(self, context, instance_uuid, *args, **kwargs)
+
+ return _checks_instance_lock_core(self, _cb, context, instance_uuid,
+ *args, **kwargs)
+
+ @functools.wraps(function)
+ def decorated_function_new(self, context, *args, **kwargs):
+ try:
+ instance_uuid = kwargs['instance_uuid']
+ except KeyError:
+ instance_uuid = kwargs['instance']['uuid']
+
+ def _cb(self, context, *args, **kwargs):
+ function(self, context, *args, **kwargs)
+
+ return _checks_instance_lock_core(self, _cb, context, instance_uuid,
+ *args, **kwargs)
+
+ expected_args = ['context', 'instance_uuid']
+ argspec = inspect.getargspec(function)
+
+ if expected_args == argspec.args[1:len(expected_args) + 1]:
+ return decorated_function
+ else:
+ return decorated_function_new
def wrap_instance_fault(function):
@@ -197,10 +225,16 @@ def wrap_instance_fault(function):
This decorator wraps a method to catch any exceptions having to do with
an instance that may get thrown. It then logs an instance fault in the db.
"""
- @functools.wraps(function)
- def decorated_function(self, context, instance_uuid, *args, **kwargs):
+
+ # NOTE(russellb): There are two versions of the wrap_instance_fault
+ # decorator. This function is the core code for it. This just serves
+ # as a transition from when every function expected a context
+ # and instance_uuid as positional arguments to where everything is a kwarg,
+ # and the function may get either an instance_uuid or an instance.
+ def _wrap_instance_fault_core(self, cb, context, instance_uuid,
+ *args, **kwargs):
try:
- return function(self, context, instance_uuid, *args, **kwargs)
+ return cb(self, context, *args, **kwargs)
except exception.InstanceNotFound:
raise
except Exception, e:
@@ -208,7 +242,35 @@ def wrap_instance_fault(function):
self.add_instance_fault_from_exc(context, instance_uuid, e,
sys.exc_info())
- return decorated_function
+ @functools.wraps(function)
+ def decorated_function(self, context, instance_uuid, *args, **kwargs):
+
+ def _cb(self, context, *args, **_kwargs):
+ return function(self, context, instance_uuid, *args, **kwargs)
+
+ return _wrap_instance_fault_core(self, _cb, context, instance_uuid,
+ *args, **kwargs)
+
+ @functools.wraps(function)
+ def decorated_function_new(self, context, *args, **kwargs):
+ if 'instance_uuid' in kwargs:
+ instance_uuid = kwargs['instance_uuid']
+ else:
+ instance_uuid = kwargs['instance']['uuid']
+
+ def _cb(self, context, *args, **kwargs):
+ return function(self, context, *args, **kwargs)
+
+ return _wrap_instance_fault_core(self, _cb, context, instance_uuid,
+ *args, **kwargs)
+
+ expected_args = ['context', 'instance_uuid']
+ argspec = inspect.getargspec(function)
+
+ if expected_args == argspec.args[1:len(expected_args) + 1]:
+ return decorated_function
+ else:
+ return decorated_function_new
def _get_image_meta(context, image_ref):