From b69ff314544f78e25b3644d4b17af127e1e8aa76 Mon Sep 17 00:00:00 2001 From: Russell Bryant Date: Fri, 25 May 2012 16:24:03 -0400 Subject: [PATCH] Remove nova.context dependency from nova.rpc Part of blueprint common-rpc. This patch removes the usage of nova.context from nova.rpc. Everything needed to implement RpcContext now exists within nova.rpc. Change-Id: I9e6ec0d22e55d3d4f38e12e0fdd2df745da496f5 --- nova/rpc/amqp.py | 7 +++---- nova/rpc/common.py | 44 +++++++++++++++++++++++++++++++++++++++++++ nova/rpc/impl_fake.py | 7 +++---- 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/nova/rpc/amqp.py b/nova/rpc/amqp.py index 4850eb47..479b232b 100644 --- a/nova/rpc/amqp.py +++ b/nova/rpc/amqp.py @@ -33,7 +33,6 @@ from eventlet import greenpool from eventlet import pools from eventlet import semaphore -from nova import context from nova import log as logging from nova.openstack.common import excutils from nova.openstack.common import local @@ -168,12 +167,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/nova/rpc/common.py b/nova/rpc/common.py index 120b41c1..85177f86 100644 --- a/nova/rpc/common.py +++ b/nova/rpc/common.py @@ -25,6 +25,7 @@ from nova import log as logging from nova.openstack.common import cfg from nova.openstack.common import importutils from nova.openstack.common import jsonutils +from nova.openstack.common import local LOG = logging.getLogger(__name__) @@ -267,3 +268,46 @@ 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 nova-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 nova code that uses this to + # convert the RpcContext back to its native RequestContext doing + # something like nova.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/nova/rpc/impl_fake.py b/nova/rpc/impl_fake.py index 70a8ca5f..a6af6247 100644 --- a/nova/rpc/impl_fake.py +++ b/nova/rpc/impl_fake.py @@ -23,15 +23,14 @@ import time import eventlet -from nova import context from nova.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