Merge "Add assert_min_rpc_version decorator"

This commit is contained in:
Jenkins 2017-01-26 08:58:57 +00:00 committed by Gerrit Code Review
commit 2202f73d41
3 changed files with 32 additions and 44 deletions

View File

@ -31,10 +31,11 @@ from oslo_log import log as logging
import oslo_messaging as messaging import oslo_messaging as messaging
from oslo_utils import importutils from oslo_utils import importutils
profiler = importutils.try_import('osprofiler.profiler') profiler = importutils.try_import('osprofiler.profiler')
import six
import cinder.context import cinder.context
import cinder.exception import cinder.exception
from cinder.i18n import _LE, _LI from cinder.i18n import _, _LE, _LI
from cinder import objects from cinder import objects
from cinder.objects import base from cinder.objects import base
@ -170,6 +171,28 @@ def get_notifier(service=None, host=None, publisher_id=None):
return NOTIFIER.prepare(publisher_id=publisher_id) return NOTIFIER.prepare(publisher_id=publisher_id)
def assert_min_rpc_version(min_ver, exc=None):
"""Decorator to block RPC calls when version cap is lower than min_ver."""
if exc is None:
exc = cinder.exception.ServiceTooOld
def decorator(f):
@six.wraps(f)
def _wrapper(self, *args, **kwargs):
if not self.client.can_send_version(min_ver):
msg = _('One of %(binary)s services is too old to accept '
'%(method)s request. Required RPC API version is '
'%(version)s. Are you running mixed versions of '
'%(binary)ss?') % {'binary': self.BINARY,
'version': min_ver,
'method': f.__name__}
raise exc(msg)
return f(self, *args, **kwargs)
return _wrapper
return decorator
LAST_RPC_VERSIONS = {} LAST_RPC_VERSIONS = {}
LAST_OBJ_VERSIONS = {} LAST_OBJ_VERSIONS = {}

View File

@ -20,8 +20,6 @@ from oslo_serialization import jsonutils
from oslo_utils import timeutils from oslo_utils import timeutils
from cinder.common import constants from cinder.common import constants
from cinder import exception
from cinder.i18n import _
from cinder import rpc from cinder import rpc
@ -148,13 +146,10 @@ class SchedulerAPI(rpc.RPCAPI):
} }
return cctxt.cast(ctxt, 'manage_existing', **msg_args) return cctxt.cast(ctxt, 'manage_existing', **msg_args)
@rpc.assert_min_rpc_version('3.2')
def extend_volume(self, ctxt, volume, new_size, reservations, def extend_volume(self, ctxt, volume, new_size, reservations,
request_spec, filter_properties=None): request_spec, filter_properties=None):
cctxt = self._get_cctxt() cctxt = self._get_cctxt()
if not cctxt.can_send_version('3.2'):
msg = _('extend_volume requires cinder-scheduler '
'RPC API version >= 3.2.')
raise exception.ServiceTooOld(msg)
request_spec_p = jsonutils.to_primitive(request_spec) request_spec_p = jsonutils.to_primitive(request_spec)
msg_args = { msg_args = {
@ -194,14 +189,9 @@ class SchedulerAPI(rpc.RPCAPI):
cctxt = self._get_cctxt(fanout=True, version=version) cctxt = self._get_cctxt(fanout=True, version=version)
cctxt.cast(ctxt, 'update_service_capabilities', **msg_args) cctxt.cast(ctxt, 'update_service_capabilities', **msg_args)
@rpc.assert_min_rpc_version('3.1')
def notify_service_capabilities(self, ctxt, service_name, def notify_service_capabilities(self, ctxt, service_name,
backend, capabilities, timestamp=None): backend, capabilities, timestamp=None):
version = '3.1'
if not self.client.can_send_version(version):
msg = _('notify_service_capabilities requires cinder-scheduler '
'RPC API version >= 3.1.')
raise exception.ServiceTooOld(msg)
parameters = {'service_name': service_name, parameters = {'service_name': service_name,
'capabilities': capabilities} 'capabilities': capabilities}
if self.client.can_send_version('3.5'): if self.client.can_send_version('3.5'):
@ -209,32 +199,23 @@ class SchedulerAPI(rpc.RPCAPI):
parameters.update(backend=backend, parameters.update(backend=backend,
timestamp=self.prepare_timestamp(timestamp)) timestamp=self.prepare_timestamp(timestamp))
else: else:
version = '3.1'
parameters['host'] = backend parameters['host'] = backend
cctxt = self._get_cctxt(version=version) cctxt = self._get_cctxt(version=version)
cctxt.cast(ctxt, 'notify_service_capabilities', **parameters) cctxt.cast(ctxt, 'notify_service_capabilities', **parameters)
@rpc.assert_min_rpc_version('3.4')
def work_cleanup(self, ctxt, cleanup_request): def work_cleanup(self, ctxt, cleanup_request):
"""Generate individual service cleanup requests from user request.""" """Generate individual service cleanup requests from user request."""
if not self.client.can_send_version('3.4'):
msg = _('One of cinder-scheduler services is too old to accept '
'such request. Are you running mixed Newton-Ocata'
'cinder-schedulers?')
raise exception.ServiceTooOld(msg)
cctxt = self.client.prepare(version='3.4') cctxt = self.client.prepare(version='3.4')
# Response will have services that are receiving the cleanup request # Response will have services that are receiving the cleanup request
# and services that couldn't receive it since they are down. # and services that couldn't receive it since they are down.
return cctxt.call(ctxt, 'work_cleanup', return cctxt.call(ctxt, 'work_cleanup',
cleanup_request=cleanup_request) cleanup_request=cleanup_request)
@rpc.assert_min_rpc_version('3.4')
def do_cleanup(self, ctxt, cleanup_request): def do_cleanup(self, ctxt, cleanup_request):
"""Perform this scheduler's resource cleanup as per cleanup_request.""" """Perform this scheduler's resource cleanup as per cleanup_request."""
if not self.client.can_send_version('3.4'):
msg = _('One of cinder-scheduler services is too old to accept '
'such request. Are you running mixed Newton-Ocata'
'cinder-schedulers?')
raise exception.ServiceTooOld(msg)
cctxt = self.client.prepare(version='3.4') cctxt = self.client.prepare(version='3.4')
cctxt.cast(ctxt, 'do_cleanup', cleanup_request=cleanup_request) cctxt.cast(ctxt, 'do_cleanup', cleanup_request=cleanup_request)

View File

@ -14,8 +14,6 @@
from cinder.common import constants from cinder.common import constants
from cinder import exception
from cinder.i18n import _
from cinder import objects from cinder import objects
from cinder import quota from cinder import quota
from cinder import rpc from cinder import rpc
@ -429,13 +427,8 @@ class VolumeAPI(rpc.RPCAPI):
cctxt.cast(ctxt, 'delete_group_snapshot', cctxt.cast(ctxt, 'delete_group_snapshot',
group_snapshot=group_snapshot) group_snapshot=group_snapshot)
@rpc.assert_min_rpc_version('3.9')
def attachment_update(self, ctxt, vref, connector, attachment_id): def attachment_update(self, ctxt, vref, connector, attachment_id):
if not self.client.can_send_version('3.9'):
msg = _('One of cinder-volume services is too old to accept '
'such request. Are you running mixed Newton-Ocata'
'cinder-schedulers?')
raise exception.ServiceTooOld(msg)
version = self._compat_ver('3.9') version = self._compat_ver('3.9')
cctxt = self._get_cctxt(vref.host, version=version) cctxt = self._get_cctxt(vref.host, version=version)
return cctxt.call(ctxt, return cctxt.call(ctxt,
@ -444,13 +437,8 @@ class VolumeAPI(rpc.RPCAPI):
connector=connector, connector=connector,
attachment_id=attachment_id) attachment_id=attachment_id)
@rpc.assert_min_rpc_version('3.9')
def attachment_delete(self, ctxt, attachment_id, vref): def attachment_delete(self, ctxt, attachment_id, vref):
if not self.client.can_send_version('3.9'):
msg = _('One of cinder-volume services is too old to accept '
'such request. Are you running mixed Newton-Ocata'
'cinder-schedulers?')
raise exception.ServiceTooOld(msg)
version = self._compat_ver('3.9') version = self._compat_ver('3.9')
cctxt = self._get_cctxt(vref.host, version=version) cctxt = self._get_cctxt(vref.host, version=version)
return cctxt.call(ctxt, return cctxt.call(ctxt,
@ -458,13 +446,9 @@ class VolumeAPI(rpc.RPCAPI):
attachment_id=attachment_id, attachment_id=attachment_id,
vref=vref) vref=vref)
@rpc.assert_min_rpc_version('3.7')
def do_cleanup(self, ctxt, cleanup_request): def do_cleanup(self, ctxt, cleanup_request):
"""Perform this service/cluster resource cleanup as requested.""" """Perform this service/cluster resource cleanup as requested."""
if not self.client.can_send_version('3.7'):
msg = _('One of cinder-volume services is too old to accept such '
'a request. Are you running mixed Newton-Ocata services?')
raise exception.ServiceTooOld(msg)
destination = cleanup_request.service_topic_queue destination = cleanup_request.service_topic_queue
cctxt = self._get_cctxt(destination, '3.7') cctxt = self._get_cctxt(destination, '3.7')
# NOTE(geguileo): This call goes to do_cleanup code in # NOTE(geguileo): This call goes to do_cleanup code in