]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Call to_primitive on volumes.rpcapi.create_volume
authorFlaper Fesp <flaper87@gmail.com>
Wed, 4 Sep 2013 11:29:22 +0000 (13:29 +0200)
committerFlavio Percoco <flaper87@gmail.com>
Tue, 10 Sep 2013 09:29:16 +0000 (11:29 +0200)
cinder.volume.rpcapi.create_volume does not convert the request_spec to
primitive before casting the request. This makes requests containing non
primitive types to fail. For example:

cinder create --metadata=Type=test --source-volid $VOLID 1

This will create a new database record and call create_volume on
volume.rpcapi.  This will fail because VolumeMetadata won't be
serialized correctly when calling cast. This, however, is not True when
--source-volid is not passed because in such case,
scheduler.rpcpai.create_volume will be called, which converts
request_spec to primitive correctly.

Closes-Bug: #1213964
Change-Id: I096d815254c9782390fba05ea9cd9af925635402

cinder/tests/test_volume_rpcapi.py
cinder/volume/rpcapi.py

index dead83eff4477d924d6f98d703c79f26deb96dbe..1a596bb83a4cf3c619b47ef7b1310380176e2806 100644 (file)
@@ -42,6 +42,7 @@ class VolumeRpcAPITestCase(test.TestCase):
         vol['availability_zone'] = CONF.storage_availability_zone
         vol['status'] = "available"
         vol['attach_status'] = "detached"
+        vol['metadata'] = {"test_key": "test_val"}
         volume = db.volume_create(self.context, vol)
 
         snpshot = {
@@ -53,6 +54,7 @@ class VolumeRpcAPITestCase(test.TestCase):
             'display_description': 'fake_description'}
         snapshot = db.snapshot_create(self.context, snpshot)
         self.fake_volume = jsonutils.to_primitive(volume)
+        self.fake_volume_metadata = volume["volume_metadata"]
         self.fake_snapshot = jsonutils.to_primitive(snapshot)
 
     def test_serialized_volume_has_id(self):
@@ -70,6 +72,11 @@ class VolumeRpcAPITestCase(test.TestCase):
         expected_retval = 'foo' if method == 'call' else None
 
         expected_version = kwargs.pop('version', rpcapi.BASE_RPC_API_VERSION)
+
+        if 'request_spec' in kwargs:
+            spec = jsonutils.to_primitive(kwargs['request_spec'])
+            kwargs['request_spec'] = spec
+
         expected_msg = rpcapi.make_msg(method, **kwargs)
         if 'volume' in expected_msg['args']:
             volume = expected_msg['args']['volume']
@@ -131,6 +138,20 @@ class VolumeRpcAPITestCase(test.TestCase):
                               source_volid='fake_src_id',
                               version='1.4')
 
+    def test_create_volume_serialization(self):
+        request_spec = {"metadata": self.fake_volume_metadata}
+        self._test_volume_api('create_volume',
+                              rpc_method='cast',
+                              volume=self.fake_volume,
+                              host='fake_host1',
+                              request_spec=request_spec,
+                              filter_properties='fake_properties',
+                              allow_reschedule=True,
+                              snapshot_id='fake_snapshot_id',
+                              image_id='fake_image_id',
+                              source_volid='fake_src_id',
+                              version='1.4')
+
     def test_delete_volume(self):
         self._test_volume_api('delete_volume',
                               rpc_method='cast',
index 4737319f81295963b88f6d2381139f06f71b6a07..c74005921cb06ca78b81735d33001800ca7874ad 100644 (file)
@@ -20,6 +20,7 @@ Client side of the volume RPC API.
 
 from oslo.config import cfg
 
+from cinder.openstack.common import jsonutils
 from cinder.openstack.common import rpc
 import cinder.openstack.common.rpc.proxy
 
@@ -61,10 +62,12 @@ class VolumeAPI(cinder.openstack.common.rpc.proxy.RpcProxy):
                       allow_reschedule=True,
                       snapshot_id=None, image_id=None,
                       source_volid=None):
+
+        request_spec_p = jsonutils.to_primitive(request_spec)
         self.cast(ctxt,
                   self.make_msg('create_volume',
                                 volume_id=volume['id'],
-                                request_spec=request_spec,
+                                request_spec=request_spec_p,
                                 filter_properties=filter_properties,
                                 allow_reschedule=allow_reschedule,
                                 snapshot_id=snapshot_id,