From: Russell Bryant <rbryant@redhat.com>
Date: Fri, 25 May 2012 20:24:03 +0000 (-0400)
Subject: Remove cinder.context dependency from cinder.rpc
X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=d916746ae9f656f6feda9d806c1ea45853e2efa3;p=openstack-build%2Fcinder-build.git

Remove cinder.context dependency from cinder.rpc

Part of blueprint common-rpc.

This patch removes the usage of cinder.context from cinder.rpc.  Everything
needed to implement RpcContext now exists within cinder.rpc.

Change-Id: I9e6ec0d22e55d3d4f38e12e0fdd2df745da496f5
---

diff --git a/cinder/rpc/amqp.py b/cinder/rpc/amqp.py
index c3488037d..0e6e5de6d 100644
--- a/cinder/rpc/amqp.py
+++ b/cinder/rpc/amqp.py
@@ -33,7 +33,6 @@ from eventlet import greenpool
 from eventlet import pools
 from eventlet import semaphore
 
-from cinder import context
 from cinder import log as logging
 from cinder.openstack.common import local
 import cinder.rpc.common as rpc_common
@@ -164,12 +163,12 @@ def msg_reply(conf, msg_id, connection_pool, reply=None, failure=None,
         conn.direct_send(msg_id, msg)
 
 
-class RpcContext(context.RequestContext):
+class RpcContext(rpc_common.CommonRpcContext):
     """Context that supports replying to a rpc.call"""
-    def __init__(self, *args, **kwargs):
+    def __init__(self, **kwargs):
         self.msg_id = kwargs.pop('msg_id', None)
         self.conf = kwargs.pop('conf')
-        super(RpcContext, self).__init__(*args, **kwargs)
+        super(RpcContext, self).__init__(**kwargs)
 
     def reply(self, reply=None, failure=None, ending=False,
               connection_pool=None):
diff --git a/cinder/rpc/common.py b/cinder/rpc/common.py
index e5403cb1e..29db0c4a6 100644
--- a/cinder/rpc/common.py
+++ b/cinder/rpc/common.py
@@ -25,6 +25,7 @@ from cinder import log as logging
 from cinder.openstack.common import cfg
 from cinder.openstack.common import importutils
 from cinder.openstack.common import jsonutils
+from cinder.openstack.common import local
 
 
 LOG = logging.getLogger(__name__)
@@ -248,3 +249,47 @@ def deserialize_remote_exception(conf, data):
         # first exception argument.
         failure.args = (message,) + failure.args[1:]
     return failure
+
+
+class CommonRpcContext(object):
+    def __init__(self, **kwargs):
+        self.values = kwargs
+
+    def __getattr__(self, key):
+        try:
+            return self.values[key]
+        except KeyError:
+            raise AttributeError(key)
+
+    def to_dict(self):
+        return copy.deepcopy(self.values)
+
+    @classmethod
+    def from_dict(cls, values):
+        return cls(**values)
+
+    def update_store(self):
+        local.store.context = self
+
+    def elevated(self, read_deleted=None, overwrite=False):
+        """Return a version of this context with admin flag set."""
+        # TODO(russellb) This method is a bit of a cinder-ism.  It makes
+        # some assumptions about the data in the request context sent
+        # across rpc, while the rest of this class does not.  We could get
+        # rid of this if we changed the cinder code that uses this to
+        # convert the RpcContext back to its native RequestContext doing
+        # something like
+        # cinder.context.RequestContext.from_dict(ctxt.to_dict())
+
+        context = copy.deepcopy(self)
+        context.values['is_admin'] = True
+
+        context.values.setdefault('roles', [])
+
+        if 'admin' not in context.values['roles']:
+            context.values['roles'].append('admin')
+
+        if read_deleted is not None:
+            context.values['read_deleted'] = read_deleted
+
+        return context
diff --git a/cinder/rpc/impl_fake.py b/cinder/rpc/impl_fake.py
index d373f9c40..a1ca192b0 100644
--- a/cinder/rpc/impl_fake.py
+++ b/cinder/rpc/impl_fake.py
@@ -26,15 +26,14 @@ import traceback
 
 import eventlet
 
-from cinder import context
 from cinder.rpc import common as rpc_common
 
 CONSUMERS = {}
 
 
-class RpcContext(context.RequestContext):
-    def __init__(self, *args, **kwargs):
-        super(RpcContext, self).__init__(*args, **kwargs)
+class RpcContext(rpc_common.CommonRpcContext):
+    def __init__(self, **kwargs):
+        super(RpcContext, self).__init__(**kwargs)
         self._response = []
         self._done = False