Pin RPC server's serializer to min obj version
We're passing object version pin on CinderObjectSerializer initialization in RPC clients (rpcapis), but not in RPC servers (managers). This means that objects returned from RPC calls aren't backported and older service can get a response with an object version it doesn't understand. As on RPC server side we don't know who called us, we need to consider minimum object version among all the binaries, not only the one we're running. This commit implements that behavior. Closes-Bug: 1609304 Change-Id: Ibc708eb6ca6d792bec0f38abb4e1b5f58488a414
This commit is contained in:
parent
0f1ea3cfda
commit
9e9b3ec7ea
|
@ -183,7 +183,7 @@ class Service(base.CinderPersistentObject, base.CinderObject,
|
|||
return cls._get_minimum_version('rpc_current_version', context, binary)
|
||||
|
||||
@classmethod
|
||||
def get_minimum_obj_version(cls, context, binary):
|
||||
def get_minimum_obj_version(cls, context, binary=None):
|
||||
return cls._get_minimum_version('object_current_version', context,
|
||||
binary)
|
||||
|
||||
|
|
|
@ -231,10 +231,14 @@ class Service(service.Service):
|
|||
|
||||
LOG.debug("Creating RPC server for service %s", self.topic)
|
||||
|
||||
ctxt = context.get_admin_context()
|
||||
target = messaging.Target(topic=self.topic, server=self.host)
|
||||
endpoints = [self.manager]
|
||||
endpoints.extend(self.manager.additional_endpoints)
|
||||
serializer = objects_base.CinderObjectSerializer()
|
||||
obj_version_cap = objects.Service.get_minimum_obj_version(ctxt)
|
||||
LOG.debug("Pinning object versions for RPC server serializer to %s",
|
||||
obj_version_cap)
|
||||
serializer = objects_base.CinderObjectSerializer(obj_version_cap)
|
||||
self.rpcserver = rpc.get_server(target, endpoints, serializer)
|
||||
self.rpcserver.start()
|
||||
|
||||
|
@ -245,7 +249,7 @@ class Service(service.Service):
|
|||
{'topic': self.topic, 'version': version_string,
|
||||
'cluster': self.cluster})
|
||||
target = messaging.Target(topic=self.topic, server=self.cluster)
|
||||
serializer = objects_base.CinderObjectSerializer()
|
||||
serializer = objects_base.CinderObjectSerializer(obj_version_cap)
|
||||
self.cluster_rpcserver = rpc.get_server(target, endpoints,
|
||||
serializer)
|
||||
self.cluster_rpcserver.start()
|
||||
|
|
|
@ -147,6 +147,21 @@ class TestService(test_objects.BaseObjectsTestCase):
|
|||
objects.Service.get_minimum_obj_version,
|
||||
self.context, 'foo')
|
||||
|
||||
@mock.patch('cinder.db.service_get_all')
|
||||
def test_get_minimum_version_no_binary(self, service_get_all):
|
||||
services_update = [
|
||||
{'rpc_current_version': '1.0', 'object_current_version': '1.3'},
|
||||
{'rpc_current_version': '1.1', 'object_current_version': '1.2'},
|
||||
{'rpc_current_version': '2.0', 'object_current_version': '2.5'},
|
||||
]
|
||||
services = [fake_service.fake_db_service(**s) for s in services_update]
|
||||
service_get_all.return_value = services
|
||||
|
||||
min_obj = objects.Service.get_minimum_obj_version(self.context)
|
||||
self.assertEqual('1.2', min_obj)
|
||||
service_get_all.assert_called_once_with(self.context, binary=None,
|
||||
disabled=None)
|
||||
|
||||
|
||||
class TestServiceList(test_objects.BaseObjectsTestCase):
|
||||
@mock.patch('cinder.db.service_get_all')
|
||||
|
|
|
@ -458,7 +458,7 @@ class ServiceTestCase(test.TestCase):
|
|||
cluster=None, topic=self.topic)
|
||||
self._check_rpc_servers_and_init_host(app, True, None)
|
||||
|
||||
@ddt.data('1.3', '1.8')
|
||||
@ddt.data('1.3', '1.7')
|
||||
@mock.patch('cinder.objects.Service.get_minimum_obj_version')
|
||||
def test_start_rpc_and_init_host_cluster(self, obj_version,
|
||||
get_min_obj_mock):
|
||||
|
|
Loading…
Reference in New Issue