Merge "Remove support for 1.x volume RPC API"

This commit is contained in:
Jenkins 2016-05-19 14:53:09 +00:00 committed by Gerrit Code Review
commit 8dc1a4907b
5 changed files with 337 additions and 986 deletions

View File

@ -547,26 +547,6 @@ class BackupTestCase(BaseBackupTest):
self.assertEqual(fields.BackupStatus.ERROR, backup['status'])
self.assertTrue(mock_run_backup.called)
@mock.patch('cinder.utils.brick_get_connector_properties')
@mock.patch('cinder.utils.temporary_chown')
@mock.patch('six.moves.builtins.open')
def test_create_backup_old_volume_service(self, mock_open,
mock_temporary_chown,
mock_get_backup_device):
"""Test error handling when there's too old volume service in env."""
vol_id = self._create_volume_db_entry(size=1)
backup = self._create_backup_db_entry(volume_id=vol_id)
with mock.patch.object(self.backup_mgr.volume_rpcapi.client,
'version_cap', '1.37'):
self.assertRaises(exception.ServiceTooOld,
self.backup_mgr.create_backup, self.ctxt, backup)
vol = db.volume_get(self.ctxt, vol_id)
self.assertEqual('available', vol['status'])
self.assertEqual('error_backing-up', vol['previous_status'])
backup = db.backup_get(self.ctxt, backup.id)
self.assertEqual(fields.BackupStatus.ERROR, backup['status'])
@mock.patch('cinder.utils.brick_get_connector_properties')
@mock.patch('cinder.volume.rpcapi.VolumeAPI.get_backup_device')
@mock.patch('cinder.utils.temporary_chown')
@ -678,31 +658,6 @@ class BackupTestCase(BaseBackupTest):
self.assertEqual(fields.BackupStatus.AVAILABLE, backup['status'])
self.assertTrue(mock_run_restore.called)
@mock.patch('cinder.utils.brick_get_connector_properties')
def test_restore_backup_with_old_volume_service(self, mock_get_conn):
"""Test error handling when an error occurs during backup restore."""
vol_id = self._create_volume_db_entry(status='restoring-backup',
size=1)
backup = self._create_backup_db_entry(
status=fields.BackupStatus.RESTORING, volume_id=vol_id)
# Unmock secure_file_operations_enabled
self.volume_patches['secure_file_operations_enabled'].stop()
with mock.patch.object(self.backup_mgr.volume_rpcapi.client,
'version_cap', '1.37'):
self.assertRaises(exception.ServiceTooOld,
self.backup_mgr.restore_backup,
self.ctxt,
backup,
vol_id)
vol = db.volume_get(self.ctxt, vol_id)
self.assertEqual('error_restoring', vol['status'])
backup = db.backup_get(self.ctxt, backup.id)
self.assertEqual(fields.BackupStatus.AVAILABLE, backup['status'])
self.volume_patches['secure_file_operations_enabled'].start()
def test_restore_backup_with_bad_service(self):
"""Test error handling.

File diff suppressed because it is too large Load Diff

View File

@ -17,13 +17,11 @@ Unit Tests for cinder.volume.rpcapi
"""
import copy
import mock
from oslo_config import cfg
from oslo_serialization import jsonutils
from cinder import context
from cinder import db
from cinder import exception
from cinder import objects
from cinder import test
from cinder.tests.unit import fake_backup
@ -221,58 +219,29 @@ class VolumeRpcAPITestCase(test.TestCase):
else:
self.assertEqual(expected_msg[kwarg], value)
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_create_consistencygroup(self, mock_can_send_version):
def test_create_consistencygroup(self):
self._test_volume_api('create_consistencygroup', rpc_method='cast',
group=self.fake_cg, host='fake_host1',
version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('create_consistencygroup', rpc_method='cast',
group=self.fake_cg, host='fake_host1',
version='1.26')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_delete_consistencygroup(self, mock_can_send_version):
def test_delete_consistencygroup(self):
self._test_volume_api('delete_consistencygroup', rpc_method='cast',
group=self.fake_cg, version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('delete_consistencygroup', rpc_method='cast',
group=self.fake_cg, version='1.26')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_update_consistencygroup(self, mock_can_send_version):
def test_update_consistencygroup(self):
self._test_volume_api('update_consistencygroup', rpc_method='cast',
group=self.fake_cg, add_volumes=['vol1'],
remove_volumes=['vol2'], version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('update_consistencygroup', rpc_method='cast',
group=self.fake_cg, add_volumes=['vol1'],
remove_volumes=['vol2'], version='1.26')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_create_cgsnapshot(self, mock_can_send_version):
def test_create_cgsnapshot(self):
self._test_volume_api('create_cgsnapshot', rpc_method='cast',
cgsnapshot=self.fake_cgsnap, version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('create_cgsnapshot', rpc_method='cast',
cgsnapshot=self.fake_cgsnap, version='1.31')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_delete_cgsnapshot(self, mock_can_send_version):
def test_delete_cgsnapshot(self):
self._test_volume_api('delete_cgsnapshot', rpc_method='cast',
cgsnapshot=self.fake_cgsnap, version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('delete_cgsnapshot', rpc_method='cast',
cgsnapshot=self.fake_cgsnap, version='1.31')
@mock.patch('oslo_messaging.RPCClient.can_send_version',
return_value=True)
def test_create_volume(self, can_send_version):
def test_create_volume(self):
self._test_volume_api('create_volume',
rpc_method='cast',
volume=self.fake_volume_obj,
@ -281,26 +250,8 @@ class VolumeRpcAPITestCase(test.TestCase):
filter_properties='fake_properties',
allow_reschedule=True,
version='2.0')
can_send_version.assert_called_once_with('2.0')
@mock.patch('oslo_messaging.RPCClient.can_send_version',
return_value=False)
def test_create_volume_old(self, can_send_version):
# Tests backwards compatibility with older clients
self._test_volume_api('create_volume',
rpc_method='cast',
volume=self.fake_volume_obj,
host='fake_host1',
request_spec='fake_request_spec',
filter_properties='fake_properties',
allow_reschedule=True,
version='1.24')
can_send_version.assert_has_calls([mock.call('2.0'),
mock.call('1.32')])
@mock.patch('oslo_messaging.RPCClient.can_send_version',
return_value=True)
def test_create_volume_serialization(self, can_send_version):
def test_create_volume_serialization(self):
request_spec = {"metadata": self.fake_volume_metadata}
self._test_volume_api('create_volume',
rpc_method='cast',
@ -310,59 +261,31 @@ class VolumeRpcAPITestCase(test.TestCase):
filter_properties='fake_properties',
allow_reschedule=True,
version='2.0')
can_send_version.assert_called_once_with('2.0')
@mock.patch('oslo_messaging.RPCClient.can_send_version',
return_value=True)
def test_delete_volume(self, can_send_version):
def test_delete_volume(self):
self._test_volume_api('delete_volume',
rpc_method='cast',
volume=self.fake_volume_obj,
unmanage_only=False,
cascade=False,
version='2.0')
can_send_version.assert_called_once_with('2.0')
@mock.patch('oslo_messaging.RPCClient.can_send_version',
return_value=False)
def test_delete_volume_old(self, can_send_version):
self._test_volume_api('delete_volume',
rpc_method='cast',
volume=self.fake_volume_obj,
unmanage_only=False,
version='1.15')
can_send_version.assert_has_calls([mock.call('2.0'),
mock.call('1.40'),
mock.call('1.33')])
@mock.patch('oslo_messaging.RPCClient.can_send_version',
return_value=True)
def test_delete_volume_cascade(self, can_send_version):
def test_delete_volume_cascade(self):
self._test_volume_api('delete_volume',
rpc_method='cast',
volume=self.fake_volume_obj,
unmanage_only=False,
cascade=True,
version='2.0')
can_send_version.assert_any_call('2.0')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_create_snapshot(self, mock_can_send_version):
def test_create_snapshot(self):
self._test_volume_api('create_snapshot',
rpc_method='cast',
volume=self.fake_volume,
snapshot=self.fake_snapshot,
version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('create_snapshot',
rpc_method='cast',
volume=self.fake_volume,
snapshot=self.fake_snapshot,
version='1.20')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_delete_snapshot(self, mock_can_send_version):
def test_delete_snapshot(self):
self._test_volume_api('delete_snapshot',
rpc_method='cast',
snapshot=self.fake_snapshot,
@ -370,16 +293,7 @@ class VolumeRpcAPITestCase(test.TestCase):
unmanage_only=False,
version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('delete_snapshot',
rpc_method='cast',
snapshot=self.fake_snapshot,
host='fake_host',
unmanage_only=False,
version='1.20')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_delete_snapshot_with_unmanage_only(self, mock_can_send_version):
def test_delete_snapshot_with_unmanage_only(self):
self._test_volume_api('delete_snapshot',
rpc_method='cast',
snapshot=self.fake_snapshot,
@ -387,16 +301,7 @@ class VolumeRpcAPITestCase(test.TestCase):
unmanage_only=True,
version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('delete_snapshot',
rpc_method='cast',
snapshot=self.fake_snapshot,
host='fake_host',
unmanage_only=True,
version='1.20')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_attach_volume_to_instance(self, mock_can_send_version):
def test_attach_volume_to_instance(self):
self._test_volume_api('attach_volume',
rpc_method='call',
volume=self.fake_volume,
@ -406,18 +311,7 @@ class VolumeRpcAPITestCase(test.TestCase):
mode='ro',
version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('attach_volume',
rpc_method='call',
volume=self.fake_volume,
instance_uuid='fake_uuid',
host_name=None,
mountpoint='fake_mountpoint',
mode='ro',
version='1.11')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_attach_volume_to_host(self, mock_can_send_version):
def test_attach_volume_to_host(self):
self._test_volume_api('attach_volume',
rpc_method='call',
volume=self.fake_volume,
@ -427,33 +321,14 @@ class VolumeRpcAPITestCase(test.TestCase):
mode='rw',
version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('attach_volume',
rpc_method='call',
volume=self.fake_volume,
instance_uuid=None,
host_name='fake_host',
mountpoint='fake_mountpoint',
mode='rw',
version='1.11')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_detach_volume(self, mock_can_send_version):
def test_detach_volume(self):
self._test_volume_api('detach_volume',
rpc_method='call',
volume=self.fake_volume,
attachment_id='fake_uuid',
version="2.0")
mock_can_send_version.return_value = False
self._test_volume_api('detach_volume',
rpc_method='call',
volume=self.fake_volume,
attachment_id='fake_uuid',
version="1.20")
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_copy_volume_to_image(self, mock_can_send_version):
def test_copy_volume_to_image(self):
self._test_volume_api('copy_volume_to_image',
rpc_method='cast',
volume=self.fake_volume,
@ -462,32 +337,14 @@ class VolumeRpcAPITestCase(test.TestCase):
'disk_format': 'fake_type'},
version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('copy_volume_to_image',
rpc_method='cast',
volume=self.fake_volume,
image_meta={'id': 'fake_image_id',
'container_format': 'fake_type',
'disk_format': 'fake_type'},
version='1.3')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_initialize_connection(self, mock_can_send_version):
def test_initialize_connection(self):
self._test_volume_api('initialize_connection',
rpc_method='call',
volume=self.fake_volume,
connector='fake_connector',
version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('initialize_connection',
rpc_method='call',
volume=self.fake_volume,
connector='fake_connector',
version='1.0')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_terminate_connection(self, mock_can_send_version):
def test_terminate_connection(self):
self._test_volume_api('terminate_connection',
rpc_method='call',
volume=self.fake_volume,
@ -495,16 +352,7 @@ class VolumeRpcAPITestCase(test.TestCase):
force=False,
version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('terminate_connection',
rpc_method='call',
volume=self.fake_volume,
connector='fake_connector',
force=False,
version='1.0')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_accept_transfer(self, mock_can_send_version):
def test_accept_transfer(self):
self._test_volume_api('accept_transfer',
rpc_method='call',
volume=self.fake_volume,
@ -514,42 +362,15 @@ class VolumeRpcAPITestCase(test.TestCase):
'-8ffd-0800200c9a66',
version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('accept_transfer',
rpc_method='call',
volume=self.fake_volume,
new_user='e5565fd0-06c8-11e3-'
'8ffd-0800200c9b77',
new_project='e4465fd0-06c8-11e3'
'-8ffd-0800200c9a66',
version='1.9')
@mock.patch('oslo_messaging.RPCClient.can_send_version',
return_value=True)
def test_extend_volume(self, can_send_version):
def test_extend_volume(self):
self._test_volume_api('extend_volume',
rpc_method='cast',
volume=self.fake_volume_obj,
new_size=1,
reservations=self.fake_reservations,
version='2.0')
can_send_version.assert_called_once_with('2.0')
@mock.patch('oslo_messaging.RPCClient.can_send_version',
return_value=False)
def test_extend_volume_old(self, can_send_version):
self._test_volume_api('extend_volume',
rpc_method='cast',
volume=self.fake_volume_obj,
new_size=1,
reservations=self.fake_reservations,
version='1.14')
can_send_version.assert_has_calls([mock.call('2.0'),
mock.call('1.35')])
@mock.patch('oslo_messaging.RPCClient.can_send_version',
return_value=True)
def test_migrate_volume(self, can_send_version):
def test_migrate_volume(self):
class FakeHost(object):
def __init__(self):
self.host = 'host'
@ -561,51 +382,16 @@ class VolumeRpcAPITestCase(test.TestCase):
dest_host=dest_host,
force_host_copy=True,
version='2.0')
can_send_version.assert_called_once_with('2.0')
@mock.patch('oslo_messaging.RPCClient.can_send_version',
return_value=False)
def test_migrate_volume_old(self, can_send_version):
class FakeHost(object):
def __init__(self):
self.host = 'host'
self.capabilities = {}
dest_host = FakeHost()
self._test_volume_api('migrate_volume',
rpc_method='cast',
volume=self.fake_volume_obj,
dest_host=dest_host,
force_host_copy=True,
version='1.8')
can_send_version.assert_has_calls([mock.call('2.0'),
mock.call('1.36')])
@mock.patch('oslo_messaging.RPCClient.can_send_version',
return_value=True)
def test_migrate_volume_completion(self, can_send_version):
def test_migrate_volume_completion(self):
self._test_volume_api('migrate_volume_completion',
rpc_method='call',
volume=self.fake_volume_obj,
new_volume=self.fake_volume_obj,
error=False,
version='2.0')
can_send_version.assert_called_once_with('2.0')
@mock.patch('oslo_messaging.RPCClient.can_send_version',
return_value=False)
def test_migrate_volume_completion_old(self, can_send_version):
self._test_volume_api('migrate_volume_completion',
rpc_method='call',
volume=self.fake_volume_obj,
new_volume=self.fake_volume_obj,
error=False,
version='1.10')
can_send_version.assert_has_calls([mock.call('2.0'),
mock.call('1.36')])
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
@mock.patch('cinder.quota.DbQuotaDriver.rollback')
def test_retype(self, rollback, can_send_version):
def test_retype(self):
class FakeHost(object):
def __init__(self):
self.host = 'host'
@ -620,93 +406,15 @@ class VolumeRpcAPITestCase(test.TestCase):
reservations=self.fake_reservations,
old_reservations=self.fake_reservations,
version='2.0')
rollback.assert_not_called()
can_send_version.assert_called_once_with('2.0')
@mock.patch('oslo_messaging.RPCClient.can_send_version',
side_effect=[False, True])
@mock.patch('cinder.quota.DbQuotaDriver.rollback')
def test_retype_137(self, rollback, can_send_version):
class FakeHost(object):
def __init__(self):
self.host = 'host'
self.capabilities = {}
dest_host = FakeHost()
self._test_volume_api('retype',
rpc_method='cast',
volume=self.fake_volume_obj,
new_type_id='fake',
dest_host=dest_host,
migration_policy='never',
reservations=self.fake_reservations,
old_reservations=self.fake_reservations,
version='1.37')
rollback.assert_not_called()
can_send_version.assert_any_call('2.0')
can_send_version.assert_any_call('1.37')
@mock.patch('cinder.quota.DbQuotaDriver.rollback')
@mock.patch('oslo_messaging.RPCClient.can_send_version',
side_effect=[False, False, True])
def test_retype_version_134(self, can_send_version, rollback):
class FakeHost(object):
def __init__(self):
self.host = 'host'
self.capabilities = {}
dest_host = FakeHost()
self._test_volume_api('retype',
rpc_method='cast',
volume=self.fake_volume_obj,
new_type_id='fake',
dest_host=dest_host,
migration_policy='never',
reservations=self.fake_reservations,
old_reservations=self.fake_reservations,
version='1.34')
self.assertTrue(rollback.called)
can_send_version.assert_any_call('2.0')
can_send_version.assert_any_call('1.37')
can_send_version.assert_any_call('1.34')
@mock.patch('cinder.quota.DbQuotaDriver.rollback')
@mock.patch('oslo_messaging.RPCClient.can_send_version',
side_effect=[False, False, False])
def test_retype_version_112(self, can_send_version, rollback):
class FakeHost(object):
def __init__(self):
self.host = 'host'
self.capabilities = {}
dest_host = FakeHost()
self._test_volume_api('retype',
rpc_method='cast',
volume=self.fake_volume_obj,
new_type_id='fake',
dest_host=dest_host,
migration_policy='never',
reservations=self.fake_reservations,
old_reservations=self.fake_reservations,
version='1.12')
self.assertTrue(rollback.called)
can_send_version.assert_any_call('1.37')
can_send_version.assert_any_call('1.34')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_manage_existing(self, mock_can_send_version):
def test_manage_existing(self):
self._test_volume_api('manage_existing',
rpc_method='cast',
volume=self.fake_volume,
ref={'lv_name': 'foo'},
version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('manage_existing',
rpc_method='cast',
volume=self.fake_volume,
ref={'lv_name': 'foo'},
version='1.15')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_manage_existing_snapshot(self, mock_can_send_version):
def test_manage_existing_snapshot(self):
volume_update = {'host': 'fake_host'}
snpshot = {
'id': fake.SNAPSHOT_ID,
@ -727,74 +435,33 @@ class VolumeRpcAPITestCase(test.TestCase):
host='fake_host',
version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('manage_existing_snapshot',
rpc_method='cast',
snapshot=my_fake_snapshot_obj,
ref='foo',
host='fake_host',
version='1.28')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_promote_replica(self, mock_can_send_version):
def test_promote_replica(self):
self._test_volume_api('promote_replica',
rpc_method='cast',
volume=self.fake_volume,
version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('promote_replica',
rpc_method='cast',
volume=self.fake_volume,
version='1.17')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_reenable_replica(self, mock_can_send_version):
def test_reenable_replica(self):
self._test_volume_api('reenable_replication',
rpc_method='cast',
volume=self.fake_volume,
version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('reenable_replication',
rpc_method='cast',
volume=self.fake_volume,
version='1.17')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_freeze_host(self, mock_can_send_version):
def test_freeze_host(self):
self._test_volume_api('freeze_host', rpc_method='call',
host='fake_host', version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('freeze_host', rpc_method='call',
host='fake_host', version='1.39')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_thaw_host(self, mock_can_send_version):
def test_thaw_host(self):
self._test_volume_api('thaw_host', rpc_method='call', host='fake_host',
version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('thaw_host', rpc_method='call', host='fake_host',
version='1.39')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_failover_host(self, mock_can_send_version):
def test_failover_host(self):
self._test_volume_api('failover_host', rpc_method='cast',
host='fake_host',
secondary_backend_id='fake_backend',
version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('failover_host', rpc_method='cast',
host='fake_host',
secondary_backend_id='fake_backend',
version='1.39')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_create_consistencygroup_from_src_cgsnapshot(
self, mock_can_send_version):
def test_create_consistencygroup_from_src_cgsnapshot(self):
self._test_volume_api('create_consistencygroup_from_src',
rpc_method='cast',
group=self.fake_cg,
@ -802,16 +469,7 @@ class VolumeRpcAPITestCase(test.TestCase):
source_cg=None,
version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('create_consistencygroup_from_src',
rpc_method='cast',
group=self.fake_cg,
cgsnapshot=self.fake_cgsnap,
source_cg=None,
version='1.31')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_create_consistencygroup_from_src_cg(self, mock_can_send_version):
def test_create_consistencygroup_from_src_cg(self):
self._test_volume_api('create_consistencygroup_from_src',
rpc_method='cast',
group=self.fake_cg2,
@ -819,64 +477,28 @@ class VolumeRpcAPITestCase(test.TestCase):
source_cg=self.fake_src_cg,
version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('create_consistencygroup_from_src',
rpc_method='cast',
group=self.fake_cg2,
cgsnapshot=None,
source_cg=self.fake_src_cg,
version='1.31')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_get_capabilities(self, mock_can_send_version):
def test_get_capabilities(self):
self._test_volume_api('get_capabilities',
rpc_method='call',
host='fake_host',
discover=True,
version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('get_capabilities',
rpc_method='call',
host='fake_host',
discover=True,
version='1.29')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_remove_export(self, mock_can_send_version):
def test_remove_export(self):
self._test_volume_api('remove_export',
rpc_method='cast',
volume=self.fake_volume,
version='2.0')
mock_can_send_version.return_value = False
self._test_volume_api('remove_export',
rpc_method='cast',
volume=self.fake_volume,
version='1.30')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_get_backup_device(self, mock_can_send_version):
def test_get_backup_device(self):
self._test_volume_api('get_backup_device',
rpc_method='call',
backup=self.fake_backup_obj,
volume=self.fake_volume_obj,
version='2.0')
mock_can_send_version.return_value = False
self.assertRaises(exception.ServiceTooOld, self._test_volume_api,
'get_backup_device', rpc_method='call',
backup=self.fake_backup_obj,
volume=self.fake_volume_obj, version='1.38')
@mock.patch('oslo_messaging.RPCClient.can_send_version', return_value=True)
def test_secure_file_operations_enabled(self, mock_can_send_version):
def test_secure_file_operations_enabled(self):
self._test_volume_api('secure_file_operations_enabled',
rpc_method='call',
volume=self.fake_volume_obj,
version='2.0')
mock_can_send_version.return_value = False
self.assertRaises(exception.ServiceTooOld, self._test_volume_api,
'secure_file_operations_enabled', rpc_method='call',
volume=self.fake_volume_obj, version='1.38')

View File

@ -236,7 +236,6 @@ class VolumeManager(manager.SchedulerDependentManager):
# update_service_capabilities needs service_name to be volume
super(VolumeManager, self).__init__(service_name='volume',
*args, **kwargs)
self.additional_endpoints.append(_VolumeV1Proxy(self))
self.configuration = config.Configuration(volume_manager_opts,
config_group=service_name)
self.stats = {}
@ -506,10 +505,10 @@ class VolumeManager(manager.SchedulerDependentManager):
# threadpool to prevent the main volume service thread
# from being blocked.
self._add_to_threadpool(self.delete_volume, ctxt,
volume['id'])
volume['id'], volume=volume)
else:
# By default, delete volumes sequentially
self.delete_volume(ctxt, volume['id'])
self.delete_volume(ctxt, volume['id'], volume=volume)
LOG.info(_LI("Resume volume delete completed successfully."),
resource=volume)
@ -562,7 +561,7 @@ class VolumeManager(manager.SchedulerDependentManager):
filter_properties=None, allow_reschedule=True,
volume=None):
"""Creates the volume."""
# FIXME(thangp): Remove this in v2.0 of RPC API.
# FIXME(dulek): Remove this in v3.0 of RPC API.
if volume is None:
# For older clients, mimic the old behavior and look up the volume
# by its volume_id.
@ -678,7 +677,7 @@ class VolumeManager(manager.SchedulerDependentManager):
context = context.elevated()
try:
# FIXME(thangp): Remove this in v2.0 of RPC API.
# FIXME(dulek): Remove this in v3.0 of RPC API.
if volume is None:
volume = objects.Volume.get_by_id(context, volume_id)
else:
@ -686,8 +685,7 @@ class VolumeManager(manager.SchedulerDependentManager):
except exception.VolumeNotFound:
# NOTE(thingee): It could be possible for a volume to
# be deleted when resuming deletes from init_host().
LOG.debug("Attempted delete of non-existent volume: %s",
volume_id)
LOG.debug("Attempted delete of non-existent volume: %s", volume_id)
return
if context.project_id != volume.project_id:
@ -1213,7 +1211,7 @@ class VolumeManager(manager.SchedulerDependentManager):
try:
self.create_volume(ctx, image_volume.id,
allow_reschedule=False)
allow_reschedule=False, volume=image_volume)
image_volume = self.db.volume_get(ctx, image_volume.id)
if image_volume.status != 'available':
raise exception.InvalidVolume(_('Volume is not available.'))
@ -1729,7 +1727,9 @@ class VolumeManager(manager.SchedulerDependentManager):
# The above call is synchronous so we complete the migration
self.migrate_volume_completion(ctxt, volume.id,
new_volume.id,
error=False)
error=False,
volume=volume,
new_volume=new_volume)
else:
nova_api = compute.API()
# This is an async call to Nova, which will call the completion
@ -1788,7 +1788,7 @@ class VolumeManager(manager.SchedulerDependentManager):
def migrate_volume_completion(self, ctxt, volume_id, new_volume_id,
error=False, volume=None, new_volume=None):
# FIXME(thangp): Remove this in v2.0 of RPC API.
# FIXME(dulek): Remove this in v3.0 of RPC API.
if volume is None or new_volume is None:
# For older clients, mimic the old behavior and look up the volume
# by its volume_id.
@ -1879,7 +1879,7 @@ class VolumeManager(manager.SchedulerDependentManager):
def migrate_volume(self, ctxt, volume_id, host, force_host_copy=False,
new_type_id=None, volume=None):
"""Migrate the volume to the specified host (called on source host)."""
# FIXME(thangp): Remove this in v2.0 of RPC API.
# FIXME(dulek): Remove this in v3.0 of RPC API.
if volume is None:
# For older clients, mimic the old behavior and look up the volume
# by its volume_id.
@ -2060,7 +2060,7 @@ class VolumeManager(manager.SchedulerDependentManager):
def extend_volume(self, context, volume_id, new_size, reservations,
volume=None):
# FIXME(thangp): Remove this in v2.0 of RPC API.
# FIXME(dulek): Remove this in v3.0 of RPC API.
if volume is None:
# For older clients, mimic the old behavior and look up the volume
# by its volume_id.
@ -2131,7 +2131,7 @@ class VolumeManager(manager.SchedulerDependentManager):
context = ctxt.elevated()
# FIXME(thangp): Remove this in v2.0 of RPC API.
# FIXME(dulek): Remove this in v3.0 of RPC API.
if volume is None:
# For older clients, mimic the old behavior and look up the volume
# by its volume_id.
@ -3172,15 +3172,8 @@ class VolumeManager(manager.SchedulerDependentManager):
self._notify_about_cgsnapshot_usage(context, cgsnapshot, "delete.end",
snapshots)
def update_migrated_volume(self, ctxt, volume, new_volume,
volume_status):
def update_migrated_volume(self, ctxt, volume, new_volume, volume_status):
"""Finalize migration process on backend device."""
# FIXME(thangp): Remove this in v2.0 of RPC API.
if (not isinstance(volume, objects.Volume) or
not isinstance(new_volume, objects.Volume)):
volume = objects.Volume.get_by_id(ctxt, volume['id'])
new_volume = objects.Volume.get_by_id(ctxt, new_volume['id'])
model_update = None
model_update_default = {'_name_id': new_volume.name_id,
'provider_location':
@ -3434,148 +3427,3 @@ class VolumeManager(manager.SchedulerDependentManager):
def secure_file_operations_enabled(self, ctxt, volume):
secure_enabled = self.driver.secure_file_operations_enabled()
return secure_enabled
# TODO(dulek): This goes away immediately in Newton and is just present in
# Mitaka so that we can receive v1.x and v2.0 messages
class _VolumeV1Proxy(object):
target = messaging.Target(version='1.40')
def __init__(self, manager):
self.manager = manager
def create_volume(self, context, volume_id, request_spec=None,
filter_properties=None, allow_reschedule=True,
volume=None):
return self.manager.create_volume(
context, volume_id, request_spec=request_spec,
filter_properties=filter_properties,
allow_reschedule=allow_reschedule, volume=volume)
def delete_volume(self, context, volume_id, unmanage_only=False,
volume=None, cascade=False):
return self.manager.delete_volume(
context, volume_id, unmanage_only=unmanage_only, volume=volume,
cascade=cascade)
def create_snapshot(self, context, volume_id, snapshot):
return self.manager.create_snapshot(context, volume_id, snapshot)
def delete_snapshot(self, context, snapshot, unmanage_only=False):
return self.manager.delete_snapshot(context, snapshot,
unmanage_only=unmanage_only)
def attach_volume(self, context, volume_id, instance_uuid, host_name,
mountpoint, mode):
return self.manager.attach_volume(context, volume_id, instance_uuid,
host_name, mountpoint, mode)
def detach_volume(self, context, volume_id, attachment_id=None):
return self.manager.detach_volume(context, volume_id,
attachment_id=attachment_id)
def copy_volume_to_image(self, context, volume_id, image_meta):
return self.manager.copy_volume_to_image(context, volume_id,
image_meta)
def initialize_connection(self, context, volume_id, connector):
return self.manager.initialize_connection(context, volume_id,
connector)
def terminate_connection(self, context, volume_id, connector, force=False):
return self.manager.terminate_connection(context, volume_id, connector,
force=force)
def remove_export(self, context, volume_id):
return self.manager.remove_export(context, volume_id)
def accept_transfer(self, context, volume_id, new_user, new_project):
return self.manager.accept_transfer(context, volume_id, new_user,
new_project)
def migrate_volume_completion(self, ctxt, volume_id, new_volume_id,
error=False, volume=None, new_volume=None):
return self.manager.migrate_volume_completion(
ctxt, volume_id, new_volume_id, error=error, volume=volume,
new_volume=new_volume)
def migrate_volume(self, ctxt, volume_id, host, force_host_copy=False,
new_type_id=None, volume=None):
return self.manager.migrate_volume(
ctxt, volume_id, host, force_host_copy=force_host_copy,
new_type_id=new_type_id, volume=volume)
def publish_service_capabilities(self, context):
return self.manager.publish_service_capabilities(context)
def extend_volume(self, context, volume_id, new_size, reservations,
volume=None):
return self.manager.extend_volume(context, volume_id, new_size,
reservations, volume=volume)
def retype(self, ctxt, volume_id, new_type_id, host,
migration_policy='never', reservations=None,
volume=None, old_reservations=None):
return self.manager.retype(ctxt, volume_id, new_type_id, host,
migration_policy=migration_policy,
reservations=reservations, volume=volume,
old_reservations=old_reservations)
def manage_existing(self, ctxt, volume_id, ref=None):
return self.manager.manage_existing(ctxt, volume_id, ref=ref)
def promote_replica(self, ctxt, volume_id):
return self.manager.promote_replica(ctxt, volume_id)
def reenable_replication(self, ctxt, volume_id):
return self.manager.reenable_replication(ctxt, volume_id)
def create_consistencygroup(self, context, group):
return self.manager.create_consistencygroup(context, group)
def create_consistencygroup_from_src(self, context, group,
cgsnapshot=None, source_cg=None):
return self.manager.create_consistencygroup_from_src(
context, group, cgsnapshot=cgsnapshot, source_cg=source_cg)
def delete_consistencygroup(self, context, group):
return self.manager.delete_consistencygroup(context, group)
def update_consistencygroup(self, context, group, add_volumes=None,
remove_volumes=None):
return self.manager.update_consistencygroup(
context, group, add_volumes=add_volumes,
remove_volumes=remove_volumes)
def create_cgsnapshot(self, context, cgsnapshot):
return self.manager.create_cgsnapshot(context, cgsnapshot)
def delete_cgsnapshot(self, context, cgsnapshot):
return self.manager.delete_cgsnapshot(context, cgsnapshot)
def update_migrated_volume(self, ctxt, volume, new_volume, volume_status):
return self.manager.update_migrated_volume(ctxt, volume, new_volume,
volume_status)
def failover_host(self, context, secondary_backend_id=None):
return self.manager.failover_host(
context, secondary_backend_id=secondary_backend_id)
def freeze_host(self, context):
return self.manager.freeze_host(context)
def thaw_host(self, context):
return self.manager.thaw_host(context)
def manage_existing_snapshot(self, ctxt, snapshot, ref=None):
return self.manager.manage_exisiting_snapshot(ctxt, snapshot, ref=ref)
def get_capabilities(self, context, discover):
return self.manager.get_capabilities(context, discover)
def get_backup_device(self, ctxt, backup):
return self.manager.get_backup_device(ctxt, backup)
def secure_file_operations_enabled(self, ctxt, volume):
return self.manager.secure_file_operations_enabled(ctxt, volume)

View File

@ -19,8 +19,6 @@ Client side of the volume RPC API.
from oslo_config import cfg
from oslo_serialization import jsonutils
from cinder import exception
from cinder.i18n import _
from cinder import quota
from cinder import rpc
from cinder.volume import utils
@ -103,36 +101,27 @@ class VolumeAPI(rpc.RPCAPI):
2.0 - Remove 1.x compatibility
"""
RPC_API_VERSION = '1.40'
RPC_API_VERSION = '2.0'
TOPIC = CONF.volume_topic
BINARY = 'cinder-volume'
def _compat_ver(self, current, legacy):
if self.client.can_send_version(current):
return current
else:
return legacy
def _get_cctxt(self, host, version):
new_host = utils.get_volume_rpc_host(host)
return self.client.prepare(server=new_host, version=version)
def create_consistencygroup(self, ctxt, group, host):
version = self._compat_ver('2.0', '1.26')
cctxt = self._get_cctxt(host, version)
cctxt = self._get_cctxt(host, '2.0')
cctxt.cast(ctxt, 'create_consistencygroup',
group=group)
def delete_consistencygroup(self, ctxt, group):
version = self._compat_ver('2.0', '1.26')
cctxt = self._get_cctxt(group.host, version)
cctxt = self._get_cctxt(group.host, '2.0')
cctxt.cast(ctxt, 'delete_consistencygroup',
group=group)
def update_consistencygroup(self, ctxt, group, add_volumes=None,
remove_volumes=None):
version = self._compat_ver('2.0', '1.26')
cctxt = self._get_cctxt(group.host, version)
cctxt = self._get_cctxt(group.host, '2.0')
cctxt.cast(ctxt, 'update_consistencygroup',
group=group,
add_volumes=add_volumes,
@ -140,83 +129,47 @@ class VolumeAPI(rpc.RPCAPI):
def create_consistencygroup_from_src(self, ctxt, group, cgsnapshot=None,
source_cg=None):
version = self._compat_ver('2.0', '1.31')
cctxt = self._get_cctxt(group.host, version)
cctxt = self._get_cctxt(group.host, '2.0')
cctxt.cast(ctxt, 'create_consistencygroup_from_src',
group=group,
cgsnapshot=cgsnapshot,
source_cg=source_cg)
def create_cgsnapshot(self, ctxt, cgsnapshot):
version = self._compat_ver('2.0', '1.31')
cctxt = self._get_cctxt(cgsnapshot.consistencygroup.host, version)
cctxt = self._get_cctxt(cgsnapshot.consistencygroup.host, '2.0')
cctxt.cast(ctxt, 'create_cgsnapshot', cgsnapshot=cgsnapshot)
def delete_cgsnapshot(self, ctxt, cgsnapshot):
version = self._compat_ver('2.0', '1.31')
cctxt = self._get_cctxt(cgsnapshot.consistencygroup.host, version)
cctxt = self._get_cctxt(cgsnapshot.consistencygroup.host, '2.0')
cctxt.cast(ctxt, 'delete_cgsnapshot', cgsnapshot=cgsnapshot)
def create_volume(self, ctxt, volume, host, request_spec,
filter_properties, allow_reschedule=True):
request_spec_p = jsonutils.to_primitive(request_spec)
msg_args = {'volume_id': volume.id, 'request_spec': request_spec_p,
'filter_properties': filter_properties,
'allow_reschedule': allow_reschedule}
if self.client.can_send_version('2.0'):
version = '2.0'
msg_args['volume'] = volume
elif self.client.can_send_version('1.32'):
version = '1.32'
msg_args['volume'] = volume
else:
version = '1.24'
cctxt = self._get_cctxt(host, version)
request_spec_p = jsonutils.to_primitive(request_spec)
cctxt.cast(ctxt, 'create_volume', **msg_args)
cctxt = self._get_cctxt(host, '2.0')
cctxt.cast(ctxt, 'create_volume', volume_id=volume.id,
request_spec=request_spec_p,
filter_properties=filter_properties,
allow_reschedule=allow_reschedule, volume=volume)
def delete_volume(self, ctxt, volume, unmanage_only=False, cascade=False):
msg_args = {'volume_id': volume.id, 'unmanage_only': unmanage_only}
version = '1.15'
if self.client.can_send_version('2.0'):
version = '2.0'
msg_args['volume'] = volume
if cascade:
msg_args['cascade'] = cascade
elif self.client.can_send_version('1.40'):
version = '1.40'
msg_args['volume'] = volume
if cascade:
msg_args['cascade'] = cascade
elif cascade:
msg = _('Cascade option is not supported.')
raise exception.Invalid(reason=msg)
elif self.client.can_send_version('1.33'):
version = '1.33'
msg_args['volume'] = volume
cctxt = self._get_cctxt(volume.host, version)
cctxt.cast(ctxt, 'delete_volume', **msg_args)
cctxt = self._get_cctxt(volume.host, '2.0')
cctxt.cast(ctxt, 'delete_volume', volume_id=volume.id,
unmanage_only=unmanage_only, volume=volume, cascade=cascade)
def create_snapshot(self, ctxt, volume, snapshot):
version = self._compat_ver('2.0', '1.20')
cctxt = self._get_cctxt(volume['host'], version=version)
cctxt = self._get_cctxt(volume['host'], '2.0')
cctxt.cast(ctxt, 'create_snapshot', volume_id=volume['id'],
snapshot=snapshot)
def delete_snapshot(self, ctxt, snapshot, host, unmanage_only=False):
version = self._compat_ver('2.0', '1.20')
cctxt = self._get_cctxt(host, version=version)
cctxt = self._get_cctxt(host, '2.0')
cctxt.cast(ctxt, 'delete_snapshot', snapshot=snapshot,
unmanage_only=unmanage_only)
def attach_volume(self, ctxt, volume, instance_uuid, host_name,
mountpoint, mode):
version = self._compat_ver('2.0', '1.11')
cctxt = self._get_cctxt(volume['host'], version)
cctxt = self._get_cctxt(volume['host'], '2.0')
return cctxt.call(ctxt, 'attach_volume',
volume_id=volume['id'],
instance_uuid=instance_uuid,
@ -225,143 +178,84 @@ class VolumeAPI(rpc.RPCAPI):
mode=mode)
def detach_volume(self, ctxt, volume, attachment_id):
version = self._compat_ver('2.0', '1.20')
cctxt = self._get_cctxt(volume['host'], version)
cctxt = self._get_cctxt(volume['host'], '2.0')
return cctxt.call(ctxt, 'detach_volume', volume_id=volume['id'],
attachment_id=attachment_id)
def copy_volume_to_image(self, ctxt, volume, image_meta):
version = self._compat_ver('2.0', '1.3')
cctxt = self._get_cctxt(volume['host'], version)
cctxt = self._get_cctxt(volume['host'], '2.0')
cctxt.cast(ctxt, 'copy_volume_to_image', volume_id=volume['id'],
image_meta=image_meta)
def initialize_connection(self, ctxt, volume, connector):
version = self._compat_ver('2.0', '1.0')
cctxt = self._get_cctxt(volume['host'], version=version)
cctxt = self._get_cctxt(volume['host'], '2.0')
return cctxt.call(ctxt, 'initialize_connection',
volume_id=volume['id'],
connector=connector)
def terminate_connection(self, ctxt, volume, connector, force=False):
version = self._compat_ver('2.0', '1.0')
cctxt = self._get_cctxt(volume['host'], version=version)
cctxt = self._get_cctxt(volume['host'], '2.0')
return cctxt.call(ctxt, 'terminate_connection', volume_id=volume['id'],
connector=connector, force=force)
def remove_export(self, ctxt, volume):
version = self._compat_ver('2.0', '1.30')
cctxt = self._get_cctxt(volume['host'], version)
cctxt = self._get_cctxt(volume['host'], '2.0')
cctxt.cast(ctxt, 'remove_export', volume_id=volume['id'])
def publish_service_capabilities(self, ctxt):
version = self._compat_ver('2.0', '1.2')
cctxt = self.client.prepare(fanout=True, version=version)
cctxt = self.client.prepare(fanout=True, version='2.0')
cctxt.cast(ctxt, 'publish_service_capabilities')
def accept_transfer(self, ctxt, volume, new_user, new_project):
version = self._compat_ver('2.0', '1.9')
cctxt = self._get_cctxt(volume['host'], version)
cctxt = self._get_cctxt(volume['host'], '2.0')
return cctxt.call(ctxt, 'accept_transfer', volume_id=volume['id'],
new_user=new_user, new_project=new_project)
def extend_volume(self, ctxt, volume, new_size, reservations):
msg_args = {'volume_id': volume.id, 'new_size': new_size,
'reservations': reservations}
if self.client.can_send_version('2.0'):
version = '2.0'
msg_args['volume'] = volume
elif self.client.can_send_version('1.35'):
version = '1.35'
msg_args['volume'] = volume
else:
version = '1.14'
cctxt = self._get_cctxt(volume.host, version)
cctxt.cast(ctxt, 'extend_volume', **msg_args)
cctxt = self._get_cctxt(volume.host, '2.0')
cctxt.cast(ctxt, 'extend_volume', volume_id=volume.id,
new_size=new_size, reservations=reservations, volume=volume)
def migrate_volume(self, ctxt, volume, dest_host, force_host_copy):
host_p = {'host': dest_host.host,
'capabilities': dest_host.capabilities}
msg_args = {'volume_id': volume.id, 'host': host_p,
'force_host_copy': force_host_copy}
if self.client.can_send_version('2.0'):
version = '2.0'
msg_args['volume'] = volume
elif self.client.can_send_version('1.36'):
version = '1.36'
msg_args['volume'] = volume
else:
version = '1.8'
cctxt = self._get_cctxt(volume.host, version)
cctxt.cast(ctxt, 'migrate_volume', **msg_args)
cctxt = self._get_cctxt(volume.host, '2.0')
cctxt.cast(ctxt, 'migrate_volume', volume_id=volume.id, host=host_p,
force_host_copy=force_host_copy, volume=volume)
def migrate_volume_completion(self, ctxt, volume, new_volume, error):
msg_args = {'volume_id': volume.id, 'new_volume_id': new_volume.id,
'error': error}
if self.client.can_send_version('2.0'):
version = '2.0'
msg_args['volume'] = volume
msg_args['new_volume'] = new_volume
elif self.client.can_send_version('1.36'):
version = '1.36'
msg_args['volume'] = volume
msg_args['new_volume'] = new_volume
else:
version = '1.10'
cctxt = self._get_cctxt(volume.host, version)
return cctxt.call(ctxt, 'migrate_volume_completion', **msg_args)
cctxt = self._get_cctxt(volume.host, '2.0')
return cctxt.call(ctxt, 'migrate_volume_completion',
volume_id=volume.id, new_volume_id=new_volume.id,
error=error, volume=volume, new_volume=new_volume)
def retype(self, ctxt, volume, new_type_id, dest_host,
migration_policy='never', reservations=None,
old_reservations=None):
host_p = {'host': dest_host.host,
'capabilities': dest_host.capabilities}
msg_args = {'volume_id': volume.id, 'new_type_id': new_type_id,
'host': host_p, 'migration_policy': migration_policy,
'reservations': reservations}
if self.client.can_send_version('2.0'):
version = '2.0'
msg_args.update(volume=volume, old_reservations=old_reservations)
elif self.client.can_send_version('1.37'):
version = '1.37'
msg_args.update(volume=volume, old_reservations=old_reservations)
elif self.client.can_send_version('1.34'):
if old_reservations is not None:
QUOTAS.rollback(ctxt, old_reservations)
version = '1.34'
msg_args['volume'] = volume
else:
if old_reservations is not None:
QUOTAS.rollback(ctxt, old_reservations)
version = '1.12'
cctxt = self._get_cctxt(volume.host, version)
cctxt.cast(ctxt, 'retype', **msg_args)
cctxt = self._get_cctxt(volume.host, '2.0')
cctxt.cast(ctxt, 'retype', volume_id=volume.id,
new_type_id=new_type_id, host=host_p,
migration_policy=migration_policy,
reservations=reservations, volume=volume,
old_reservations=old_reservations)
def manage_existing(self, ctxt, volume, ref):
version = self._compat_ver('2.0', '1.15')
cctxt = self._get_cctxt(volume['host'], version)
cctxt = self._get_cctxt(volume['host'], '2.0')
cctxt.cast(ctxt, 'manage_existing', volume_id=volume['id'], ref=ref)
def promote_replica(self, ctxt, volume):
version = self._compat_ver('2.0', '1.17')
cctxt = self._get_cctxt(volume['host'], version)
cctxt = self._get_cctxt(volume['host'], '2.0')
cctxt.cast(ctxt, 'promote_replica', volume_id=volume['id'])
def reenable_replication(self, ctxt, volume):
version = self._compat_ver('2.0', '1.17')
cctxt = self._get_cctxt(volume['host'], version)
cctxt = self._get_cctxt(volume['host'], '2.0')
cctxt.cast(ctxt, 'reenable_replication', volume_id=volume['id'])
def update_migrated_volume(self, ctxt, volume, new_volume,
original_volume_status):
version = self._compat_ver('2.0', '1.36')
cctxt = self._get_cctxt(new_volume['host'], version)
cctxt = self._get_cctxt(new_volume['host'], '2.0')
cctxt.call(ctxt,
'update_migrated_volume',
volume=volume,
@ -370,56 +264,35 @@ class VolumeAPI(rpc.RPCAPI):
def freeze_host(self, ctxt, host):
"""Set backend host to frozen."""
version = self._compat_ver('2.0', '1.39')
cctxt = self._get_cctxt(host, version)
cctxt = self._get_cctxt(host, '2.0')
return cctxt.call(ctxt, 'freeze_host')
def thaw_host(self, ctxt, host):
"""Clear the frozen setting on a backend host."""
version = self._compat_ver('2.0', '1.39')
cctxt = self._get_cctxt(host, version)
cctxt = self._get_cctxt(host, '2.0')
return cctxt.call(ctxt, 'thaw_host')
def failover_host(self, ctxt, host,
secondary_backend_id=None):
def failover_host(self, ctxt, host, secondary_backend_id=None):
"""Failover host to the specified backend_id (secondary). """
version = self._compat_ver('2.0', '1.39')
cctxt = self._get_cctxt(host, version)
cctxt = self._get_cctxt(host, '2.0')
cctxt.cast(ctxt, 'failover_host',
secondary_backend_id=secondary_backend_id)
def manage_existing_snapshot(self, ctxt, snapshot, ref, host):
version = self._compat_ver('2.0', '1.28')
cctxt = self._get_cctxt(host, version)
cctxt = self._get_cctxt(host, '2.0')
cctxt.cast(ctxt, 'manage_existing_snapshot',
snapshot=snapshot,
ref=ref)
def get_capabilities(self, ctxt, host, discover):
version = self._compat_ver('2.0', '1.29')
cctxt = self._get_cctxt(host, version)
cctxt = self._get_cctxt(host, '2.0')
return cctxt.call(ctxt, 'get_capabilities', discover=discover)
def get_backup_device(self, ctxt, backup, volume):
if (not self.client.can_send_version('1.38') and
not self.client.can_send_version('2.0')):
msg = _('One of cinder-volume services is too old to accept such '
'request. Are you running mixed Liberty-Mitaka '
'cinder-volumes?')
raise exception.ServiceTooOld(msg)
version = self._compat_ver('2.0', '1.38')
cctxt = self._get_cctxt(volume.host, version)
return cctxt.call(ctxt, 'get_backup_device',
backup=backup)
cctxt = self._get_cctxt(volume.host, '2.0')
return cctxt.call(ctxt, 'get_backup_device', backup=backup)
def secure_file_operations_enabled(self, ctxt, volume):
if (not self.client.can_send_version('1.38') and
not self.client.can_send_version('2.0')):
msg = _('One of cinder-volume services is too old to accept such '
'request. Are you running mixed Liberty-Mitaka '
'cinder-volumes?')
raise exception.ServiceTooOld(msg)
version = self._compat_ver('2.0', '1.38')
cctxt = self._get_cctxt(volume.host, version)
cctxt = self._get_cctxt(volume.host, '2.0')
return cctxt.call(ctxt, 'secure_file_operations_enabled',
volume=volume)