Merge "Support A/A in attach/detach operations"
This commit is contained in:
commit
366acd02b4
@ -773,7 +773,7 @@ class AdminActionsAttachDetachTest(BaseAdminTest):
|
|||||||
attachment = self.volume_api.attach(self.ctx, volume, fake.INSTANCE_ID,
|
attachment = self.volume_api.attach(self.ctx, volume, fake.INSTANCE_ID,
|
||||||
None, mountpoint, 'rw')
|
None, mountpoint, 'rw')
|
||||||
# volume is attached
|
# volume is attached
|
||||||
volume = objects.Volume.get_by_id(self.ctx, volume.id)
|
volume.refresh()
|
||||||
self.assertEqual('in-use', volume.status)
|
self.assertEqual('in-use', volume.status)
|
||||||
self.assertEqual(fake.INSTANCE_ID, attachment['instance_uuid'])
|
self.assertEqual(fake.INSTANCE_ID, attachment['instance_uuid'])
|
||||||
self.assertEqual(mountpoint, attachment['mountpoint'])
|
self.assertEqual(mountpoint, attachment['mountpoint'])
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
Unit Tests for cinder.volume.rpcapi
|
Unit Tests for cinder.volume.rpcapi
|
||||||
"""
|
"""
|
||||||
import copy
|
import copy
|
||||||
import mock
|
|
||||||
|
|
||||||
|
import mock
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_serialization import jsonutils
|
from oslo_serialization import jsonutils
|
||||||
|
|
||||||
@ -188,7 +188,8 @@ class VolumeRpcAPITestCase(test.TestCase):
|
|||||||
elif 'group' in kwargs:
|
elif 'group' in kwargs:
|
||||||
host = kwargs['group']['host']
|
host = kwargs['group']['host']
|
||||||
elif 'volume' in kwargs:
|
elif 'volume' in kwargs:
|
||||||
host = kwargs['volume']['host']
|
vol = kwargs['volume']
|
||||||
|
host = vol.service_topic_queue
|
||||||
elif 'snapshot' in kwargs:
|
elif 'snapshot' in kwargs:
|
||||||
host = 'fake_host'
|
host = 'fake_host'
|
||||||
elif 'cgsnapshot' in kwargs:
|
elif 'cgsnapshot' in kwargs:
|
||||||
@ -239,7 +240,7 @@ class VolumeRpcAPITestCase(test.TestCase):
|
|||||||
elif isinstance(value, objects.Volume):
|
elif isinstance(value, objects.Volume):
|
||||||
expected_volume = expected_msg[kwarg].obj_to_primitive()
|
expected_volume = expected_msg[kwarg].obj_to_primitive()
|
||||||
volume = value.obj_to_primitive()
|
volume = value.obj_to_primitive()
|
||||||
self.assertEqual(expected_volume, volume)
|
self.assertDictEqual(expected_volume, volume)
|
||||||
elif isinstance(value, objects.Backup):
|
elif isinstance(value, objects.Backup):
|
||||||
expected_backup = expected_msg[kwarg].obj_to_primitive()
|
expected_backup = expected_msg[kwarg].obj_to_primitive()
|
||||||
backup = value.obj_to_primitive()
|
backup = value.obj_to_primitive()
|
||||||
@ -372,7 +373,7 @@ class VolumeRpcAPITestCase(test.TestCase):
|
|||||||
def test_create_snapshot(self):
|
def test_create_snapshot(self):
|
||||||
self._test_volume_api('create_snapshot',
|
self._test_volume_api('create_snapshot',
|
||||||
rpc_method='cast',
|
rpc_method='cast',
|
||||||
volume=self.fake_volume,
|
volume=self.fake_volume_obj,
|
||||||
snapshot=self.fake_snapshot,
|
snapshot=self.fake_snapshot,
|
||||||
version='3.0')
|
version='3.0')
|
||||||
|
|
||||||
@ -395,7 +396,7 @@ class VolumeRpcAPITestCase(test.TestCase):
|
|||||||
def test_attach_volume_to_instance(self):
|
def test_attach_volume_to_instance(self):
|
||||||
self._test_volume_api('attach_volume',
|
self._test_volume_api('attach_volume',
|
||||||
rpc_method='call',
|
rpc_method='call',
|
||||||
volume=self.fake_volume,
|
volume=self.fake_volume_obj,
|
||||||
instance_uuid='fake_uuid',
|
instance_uuid='fake_uuid',
|
||||||
host_name=None,
|
host_name=None,
|
||||||
mountpoint='fake_mountpoint',
|
mountpoint='fake_mountpoint',
|
||||||
@ -405,7 +406,22 @@ class VolumeRpcAPITestCase(test.TestCase):
|
|||||||
def test_attach_volume_to_host(self):
|
def test_attach_volume_to_host(self):
|
||||||
self._test_volume_api('attach_volume',
|
self._test_volume_api('attach_volume',
|
||||||
rpc_method='call',
|
rpc_method='call',
|
||||||
volume=self.fake_volume,
|
volume=self.fake_volume_obj,
|
||||||
|
instance_uuid=None,
|
||||||
|
host_name='fake_host',
|
||||||
|
mountpoint='fake_mountpoint',
|
||||||
|
mode='rw',
|
||||||
|
version='3.0')
|
||||||
|
|
||||||
|
def _set_cluster(self):
|
||||||
|
self.fake_volume_obj.cluster_name = 'my_cluster'
|
||||||
|
self.fake_volume_obj.obj_reset_changes(['cluster_name'])
|
||||||
|
|
||||||
|
def test_attach_volume_to_cluster(self):
|
||||||
|
self._set_cluster()
|
||||||
|
self._test_volume_api('attach_volume',
|
||||||
|
rpc_method='call',
|
||||||
|
volume=self.fake_volume_obj,
|
||||||
instance_uuid=None,
|
instance_uuid=None,
|
||||||
host_name='fake_host',
|
host_name='fake_host',
|
||||||
mountpoint='fake_mountpoint',
|
mountpoint='fake_mountpoint',
|
||||||
@ -415,14 +431,22 @@ class VolumeRpcAPITestCase(test.TestCase):
|
|||||||
def test_detach_volume(self):
|
def test_detach_volume(self):
|
||||||
self._test_volume_api('detach_volume',
|
self._test_volume_api('detach_volume',
|
||||||
rpc_method='call',
|
rpc_method='call',
|
||||||
volume=self.fake_volume,
|
volume=self.fake_volume_obj,
|
||||||
|
attachment_id='fake_uuid',
|
||||||
|
version="3.0")
|
||||||
|
|
||||||
|
def test_detach_volume_cluster(self):
|
||||||
|
self._set_cluster()
|
||||||
|
self._test_volume_api('detach_volume',
|
||||||
|
rpc_method='call',
|
||||||
|
volume=self.fake_volume_obj,
|
||||||
attachment_id='fake_uuid',
|
attachment_id='fake_uuid',
|
||||||
version="3.0")
|
version="3.0")
|
||||||
|
|
||||||
def test_copy_volume_to_image(self):
|
def test_copy_volume_to_image(self):
|
||||||
self._test_volume_api('copy_volume_to_image',
|
self._test_volume_api('copy_volume_to_image',
|
||||||
rpc_method='cast',
|
rpc_method='cast',
|
||||||
volume=self.fake_volume,
|
volume=self.fake_volume_obj,
|
||||||
image_meta={'id': 'fake_image_id',
|
image_meta={'id': 'fake_image_id',
|
||||||
'container_format': 'fake_type',
|
'container_format': 'fake_type',
|
||||||
'disk_format': 'fake_type'},
|
'disk_format': 'fake_type'},
|
||||||
@ -435,10 +459,28 @@ class VolumeRpcAPITestCase(test.TestCase):
|
|||||||
connector='fake_connector',
|
connector='fake_connector',
|
||||||
version='3.0')
|
version='3.0')
|
||||||
|
|
||||||
|
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
|
||||||
|
def test_initialize_connection_cluster(self, mock_can_send_version):
|
||||||
|
self._set_cluster()
|
||||||
|
self._test_volume_api('initialize_connection',
|
||||||
|
rpc_method='call',
|
||||||
|
volume=self.fake_volume_obj,
|
||||||
|
connector='fake_connector',
|
||||||
|
version='3.0')
|
||||||
|
|
||||||
def test_terminate_connection(self):
|
def test_terminate_connection(self):
|
||||||
self._test_volume_api('terminate_connection',
|
self._test_volume_api('terminate_connection',
|
||||||
rpc_method='call',
|
rpc_method='call',
|
||||||
volume=self.fake_volume,
|
volume=self.fake_volume_obj,
|
||||||
|
connector='fake_connector',
|
||||||
|
force=False,
|
||||||
|
version='3.0')
|
||||||
|
|
||||||
|
def test_terminate_connection_cluster(self):
|
||||||
|
self._set_cluster()
|
||||||
|
self._test_volume_api('terminate_connection',
|
||||||
|
rpc_method='call',
|
||||||
|
volume=self.fake_volume_obj,
|
||||||
connector='fake_connector',
|
connector='fake_connector',
|
||||||
force=False,
|
force=False,
|
||||||
version='3.0')
|
version='3.0')
|
||||||
@ -446,7 +488,7 @@ class VolumeRpcAPITestCase(test.TestCase):
|
|||||||
def test_accept_transfer(self):
|
def test_accept_transfer(self):
|
||||||
self._test_volume_api('accept_transfer',
|
self._test_volume_api('accept_transfer',
|
||||||
rpc_method='call',
|
rpc_method='call',
|
||||||
volume=self.fake_volume,
|
volume=self.fake_volume_obj,
|
||||||
new_user='e5565fd0-06c8-11e3-'
|
new_user='e5565fd0-06c8-11e3-'
|
||||||
'8ffd-0800200c9b77',
|
'8ffd-0800200c9b77',
|
||||||
new_project='e4465fd0-06c8-11e3'
|
new_project='e4465fd0-06c8-11e3'
|
||||||
@ -566,7 +608,7 @@ class VolumeRpcAPITestCase(test.TestCase):
|
|||||||
def test_remove_export(self):
|
def test_remove_export(self):
|
||||||
self._test_volume_api('remove_export',
|
self._test_volume_api('remove_export',
|
||||||
rpc_method='cast',
|
rpc_method='cast',
|
||||||
volume=self.fake_volume,
|
volume=self.fake_volume_obj,
|
||||||
version='3.0')
|
version='3.0')
|
||||||
|
|
||||||
@mock.patch('oslo_messaging.RPCClient.can_send_version',
|
@mock.patch('oslo_messaging.RPCClient.can_send_version',
|
||||||
|
@ -188,17 +188,17 @@ class VolumeAPI(rpc.RPCAPI):
|
|||||||
|
|
||||||
def attach_volume(self, ctxt, volume, instance_uuid, host_name,
|
def attach_volume(self, ctxt, volume, instance_uuid, host_name,
|
||||||
mountpoint, mode):
|
mountpoint, mode):
|
||||||
cctxt = self._get_cctxt(volume['host'])
|
cctxt = self._get_cctxt(volume.service_topic_queue)
|
||||||
return cctxt.call(ctxt, 'attach_volume',
|
return cctxt.call(ctxt, 'attach_volume',
|
||||||
volume_id=volume['id'],
|
volume_id=volume.id,
|
||||||
instance_uuid=instance_uuid,
|
instance_uuid=instance_uuid,
|
||||||
host_name=host_name,
|
host_name=host_name,
|
||||||
mountpoint=mountpoint,
|
mountpoint=mountpoint,
|
||||||
mode=mode)
|
mode=mode)
|
||||||
|
|
||||||
def detach_volume(self, ctxt, volume, attachment_id):
|
def detach_volume(self, ctxt, volume, attachment_id):
|
||||||
cctxt = self._get_cctxt(volume['host'])
|
cctxt = self._get_cctxt(volume.service_topic_queue)
|
||||||
return cctxt.call(ctxt, 'detach_volume', volume_id=volume['id'],
|
return cctxt.call(ctxt, 'detach_volume', volume_id=volume.id,
|
||||||
attachment_id=attachment_id)
|
attachment_id=attachment_id)
|
||||||
|
|
||||||
def copy_volume_to_image(self, ctxt, volume, image_meta):
|
def copy_volume_to_image(self, ctxt, volume, image_meta):
|
||||||
@ -207,17 +207,17 @@ class VolumeAPI(rpc.RPCAPI):
|
|||||||
image_meta=image_meta)
|
image_meta=image_meta)
|
||||||
|
|
||||||
def initialize_connection(self, ctxt, volume, connector):
|
def initialize_connection(self, ctxt, volume, connector):
|
||||||
cctxt = self._get_cctxt(volume['host'])
|
cctxt = self._get_cctxt(volume.service_topic_queue)
|
||||||
return cctxt.call(ctxt, 'initialize_connection', connector=connector,
|
return cctxt.call(ctxt, 'initialize_connection', connector=connector,
|
||||||
volume=volume)
|
volume=volume)
|
||||||
|
|
||||||
def terminate_connection(self, ctxt, volume, connector, force=False):
|
def terminate_connection(self, ctxt, volume, connector, force=False):
|
||||||
cctxt = self._get_cctxt(volume['host'])
|
cctxt = self._get_cctxt(volume.service_topic_queue)
|
||||||
return cctxt.call(ctxt, 'terminate_connection', volume_id=volume['id'],
|
return cctxt.call(ctxt, 'terminate_connection', volume_id=volume['id'],
|
||||||
connector=connector, force=force)
|
connector=connector, force=force)
|
||||||
|
|
||||||
def remove_export(self, ctxt, volume):
|
def remove_export(self, ctxt, volume):
|
||||||
cctxt = self._get_cctxt(volume['host'])
|
cctxt = self._get_cctxt(volume.service_topic_queue)
|
||||||
cctxt.cast(ctxt, 'remove_export', volume_id=volume['id'])
|
cctxt.cast(ctxt, 'remove_export', volume_id=volume['id'])
|
||||||
|
|
||||||
def publish_service_capabilities(self, ctxt):
|
def publish_service_capabilities(self, ctxt):
|
||||||
|
@ -18,3 +18,5 @@ features:
|
|||||||
detail, show, enable/disable). Index and detail accept filtering by
|
detail, show, enable/disable). Index and detail accept filtering by
|
||||||
`name`, `binary`, `disabled`, `num_hosts`, `num_down_hosts`, and up/down
|
`name`, `binary`, `disabled`, `num_hosts`, `num_down_hosts`, and up/down
|
||||||
status (`is_up`) as URL parameters. Also added their respective policies."
|
status (`is_up`) as URL parameters. Also added their respective policies."
|
||||||
|
- "HA A-A: Attach and detach operations are now cluster aware and make full
|
||||||
|
use of clustered cinder-volume services."
|
||||||
|
Loading…
Reference in New Issue
Block a user