RBD: use versioned objects

Change-Id: I4dff418ccdbd364c327b35ce78421271877bbf4e
This commit is contained in:
Jon Bernard 2016-02-09 17:46:53 -05:00 committed by Jon Bernard
parent 04b2cdf9b5
commit 39c11adaee
2 changed files with 148 additions and 148 deletions

View File

@ -23,12 +23,14 @@ import tempfile
import mock
from oslo_utils import units
from cinder import context
from cinder import exception
from cinder.i18n import _
import cinder.image.glance
from cinder.image import image_utils
from cinder import objects
from cinder import test
from cinder.tests.unit import fake_snapshot
from cinder.tests.unit import fake_volume
from cinder.tests.unit import test_volume
from cinder.tests.unit import utils
@ -150,12 +152,22 @@ class RBDTestCase(test.TestCase):
configuration=self.cfg)
self.driver.set_initialized()
self.volume_name = u'volume-00000001'
self.snapshot_name = u'snapshot-00000001'
self.volume_size = 1
self.volume = dict(name=self.volume_name, size=self.volume_size)
self.snapshot = dict(volume_name=self.volume_name,
name=self.snapshot_name)
self.context = context.get_admin_context()
self.volume_a = fake_volume.fake_volume_obj(
self.context,
**{'name': u'volume-0000000a',
'id': '4c39c3c7-168f-4b32-b585-77f1b3bf0a38',
'size': 10})
self.volume_b = fake_volume.fake_volume_obj(
self.context,
**{'name': u'volume-0000000b',
'id': '0c7d1f44-5a06-403f-bb82-ae7ad0d693a6',
'size': 10})
self.snapshot = fake_snapshot.fake_snapshot_obj(
self.context, name='snapshot-0000000a')
@ddt.data({'cluster_name': None, 'pool_name': 'rbd'},
{'cluster_name': 'volumes', 'pool_name': None})
@ -173,12 +185,12 @@ class RBDTestCase(test.TestCase):
client = self.mock_client.return_value
client.__enter__.return_value = client
self.driver.create_volume(self.volume)
self.driver.create_volume(self.volume_a)
chunk_size = self.cfg.rbd_store_chunk_size * units.Mi
order = int(math.log(chunk_size, 2))
args = [client.ioctx, str(self.volume_name),
self.volume_size * units.Gi, order]
args = [client.ioctx, str(self.volume_a.name),
self.volume_a.size * units.Gi, order]
kwargs = {'old_format': False,
'features': client.features}
self.mock_rbd.RBD.return_value.create.assert_called_once_with(
@ -193,9 +205,9 @@ class RBDTestCase(test.TestCase):
with mock.patch.object(self.driver.rbd.Image(), 'close') \
as mock_rbd_image_close:
mock_rbd_image_size.return_value = 2 * units.Gi
existing_ref = {'source-name': self.volume_name}
existing_ref = {'source-name': self.volume_a.name}
return_size = self.driver.manage_existing_get_size(
self.volume,
self.volume_a,
existing_ref)
self.assertEqual(2, return_size)
mock_rbd_image_size.assert_called_once_with()
@ -209,10 +221,10 @@ class RBDTestCase(test.TestCase):
with mock.patch.object(self.driver.rbd.Image(), 'close') \
as mock_rbd_image_close:
mock_rbd_image_size.return_value = 'abcd'
existing_ref = {'source-name': self.volume_name}
existing_ref = {'source-name': self.volume_a.name}
self.assertRaises(exception.VolumeBackendAPIException,
self.driver.manage_existing_get_size,
self.volume, existing_ref)
self.volume_a, existing_ref)
mock_rbd_image_size.assert_called_once_with()
mock_rbd_image_close.assert_called_once_with()
@ -227,11 +239,11 @@ class RBDTestCase(test.TestCase):
exist_volume = 'vol-exist'
existing_ref = {'source-name': exist_volume}
mock_rbd_image_rename.return_value = 0
self.driver.manage_existing(self.volume, existing_ref)
self.driver.manage_existing(self.volume_a, existing_ref)
mock_rbd_image_rename.assert_called_with(
client.ioctx,
exist_volume,
self.volume_name)
self.volume_a.name)
@common_mocks
def test_manage_existing_with_exist_rbd_image(self):
@ -245,7 +257,7 @@ class RBDTestCase(test.TestCase):
existing_ref = {'source-name': exist_volume}
self.assertRaises(self.mock_rbd.ImageExists,
self.driver.manage_existing,
self.volume, existing_ref)
self.volume_a, existing_ref)
# Make sure the exception was raised
self.assertEqual(RAISED_EXCEPTIONS,
@ -275,11 +287,11 @@ class RBDTestCase(test.TestCase):
mock_delete_backup_snaps:
mock_get_clone_info.return_value = (None, None, None)
self.driver.delete_volume(self.volume)
self.driver.delete_volume(self.volume_a)
mock_get_clone_info.assert_called_once_with(
self.mock_rbd.Image.return_value,
self.volume_name,
self.volume_a.name,
None)
(self.driver.rbd.Image.return_value
.list_snaps.assert_called_once_with())
@ -295,7 +307,7 @@ class RBDTestCase(test.TestCase):
@common_mocks
def delete_volume_not_found(self):
self.mock_rbd.Image.side_effect = self.mock_rbd.ImageNotFound
self.assertIsNone(self.driver.delete_volume(self.volume))
self.assertIsNone(self.driver.delete_volume(self.volume_a))
self.mock_rbd.Image.assert_called_once_with()
# Make sure the exception was raised
self.assertEqual(RAISED_EXCEPTIONS, [self.mock_rbd.ImageNotFound])
@ -315,11 +327,11 @@ class RBDTestCase(test.TestCase):
with mock.patch.object(driver, 'RADOSClient') as \
mock_rados_client:
self.assertRaises(exception.VolumeIsBusy,
self.driver.delete_volume, self.volume)
self.driver.delete_volume, self.volume_a)
mock_get_clone_info.assert_called_once_with(
self.mock_rbd.Image.return_value,
self.volume_name,
self.volume_a.name,
None)
(self.mock_rbd.Image.return_value.list_snaps
.assert_called_once_with())
@ -348,10 +360,10 @@ class RBDTestCase(test.TestCase):
mock_delete_backup_snaps:
with mock.patch.object(driver, 'RADOSClient') as \
mock_rados_client:
self.assertIsNone(self.driver.delete_volume(self.volume))
self.assertIsNone(self.driver.delete_volume(self.volume_a))
mock_get_clone_info.assert_called_once_with(
self.mock_rbd.Image.return_value,
self.volume_name,
self.volume_a.name,
None)
(self.mock_rbd.Image.return_value.list_snaps
.assert_called_once_with())
@ -367,28 +379,34 @@ class RBDTestCase(test.TestCase):
[self.mock_rbd.ImageNotFound])
@common_mocks
def test_create_snapshot(self):
@mock.patch('cinder.objects.Volume.get_by_id')
def test_create_snapshot(self, volume_get_by_id):
volume_get_by_id.return_value = self.volume_a
proxy = self.mock_proxy.return_value
proxy.__enter__.return_value = proxy
self.driver.create_snapshot(self.snapshot)
args = [str(self.snapshot_name)]
args = [str(self.snapshot.name)]
proxy.create_snap.assert_called_with(*args)
proxy.protect_snap.assert_called_with(*args)
@common_mocks
def test_delete_snapshot(self):
@mock.patch('cinder.objects.Volume.get_by_id')
def test_delete_snapshot(self, volume_get_by_id):
volume_get_by_id.return_value = self.volume_a
proxy = self.mock_proxy.return_value
proxy.__enter__.return_value = proxy
self.driver.delete_snapshot(self.snapshot)
proxy.remove_snap.assert_called_with(self.snapshot_name)
proxy.unprotect_snap.assert_called_with(self.snapshot_name)
proxy.remove_snap.assert_called_with(self.snapshot.name)
proxy.unprotect_snap.assert_called_with(self.snapshot.name)
@common_mocks
def test_delete_notfound_snapshot(self):
@mock.patch('cinder.objects.Volume.get_by_id')
def test_delete_notfound_snapshot(self, volume_get_by_id):
volume_get_by_id.return_value = self.volume_a
proxy = self.mock_proxy.return_value
proxy.__enter__.return_value = proxy
@ -397,11 +415,13 @@ class RBDTestCase(test.TestCase):
self.driver.delete_snapshot(self.snapshot)
proxy.remove_snap.assert_called_with(self.snapshot_name)
proxy.unprotect_snap.assert_called_with(self.snapshot_name)
proxy.remove_snap.assert_called_with(self.snapshot.name)
proxy.unprotect_snap.assert_called_with(self.snapshot.name)
@common_mocks
def test_delete_unprotected_snapshot(self):
@mock.patch('cinder.objects.Volume.get_by_id')
def test_delete_unprotected_snapshot(self, volume_get_by_id):
volume_get_by_id.return_value = self.volume_a
proxy = self.mock_proxy.return_value
proxy.__enter__.return_value = proxy
proxy.unprotect_snap.side_effect = self.mock_rbd.InvalidArgument
@ -411,7 +431,9 @@ class RBDTestCase(test.TestCase):
self.assertTrue(proxy.remove_snap.called)
@common_mocks
def test_delete_busy_snapshot(self):
@mock.patch('cinder.objects.Volume.get_by_id')
def test_delete_busy_snapshot(self, volume_get_by_id):
volume_get_by_id.return_value = self.volume_a
proxy = self.mock_proxy.return_value
proxy.__enter__.return_value = proxy
@ -431,7 +453,7 @@ class RBDTestCase(test.TestCase):
mock_get_children_info.assert_called_once_with(
proxy,
self.snapshot_name)
self.snapshot.name)
self.assertTrue(mock_log.info.called)
self.assertTrue(proxy.unprotect_snap.called)
@ -446,7 +468,7 @@ class RBDTestCase(test.TestCase):
volume.list_children.return_value = list_children
info = self.driver._get_children_info(volume,
self.snapshot_name)
self.snapshot['name'])
self.assertEqual(list_children, info)
@ -455,10 +477,10 @@ class RBDTestCase(test.TestCase):
volume = self.mock_rbd.Image()
volume.set_snap = mock.Mock()
volume.parent_info = mock.Mock()
parent_info = ('a', 'b', '%s.clone_snap' % (self.volume_name))
parent_info = ('a', 'b', '%s.clone_snap' % (self.volume_a.name))
volume.parent_info.return_value = parent_info
info = self.driver._get_clone_info(volume, self.volume_name)
info = self.driver._get_clone_info(volume, self.volume_a.name)
self.assertEqual(parent_info, info)
@ -470,12 +492,12 @@ class RBDTestCase(test.TestCase):
volume = self.mock_rbd.Image()
volume.set_snap = mock.Mock()
volume.parent_info = mock.Mock()
parent_info = ('a', 'b', '%s.clone_snap' % (self.volume_name))
parent_info = ('a', 'b', '%s.clone_snap' % (self.volume_a.name))
volume.parent_info.return_value = parent_info
snapshot = self.mock_rbd.ImageSnapshot()
info = self.driver._get_clone_info(volume, self.volume_name,
info = self.driver._get_clone_info(volume, self.volume_a.name,
snap=snapshot)
self.assertEqual(parent_info, info)
@ -492,7 +514,7 @@ class RBDTestCase(test.TestCase):
snapshot = self.mock_rbd.ImageSnapshot()
info = self.driver._get_clone_info(volume, self.volume_name,
info = self.driver._get_clone_info(volume, self.volume_a.name,
snap=snapshot)
self.assertEqual((None, None, None), info)
@ -507,11 +529,11 @@ class RBDTestCase(test.TestCase):
volume = self.mock_rbd.Image()
volume.set_snap = mock.Mock()
volume.parent_info = mock.Mock()
parent_info = ('a', 'b', '%s.clone_snap' % (self.volume_name))
parent_info = ('a', 'b', '%s.clone_snap' % (self.volume_a.name))
volume.parent_info.return_value = parent_info
info = self.driver._get_clone_info(volume,
"%s.deleted" % (self.volume_name))
"%s.deleted" % (self.volume_a.name))
self.assertEqual(parent_info, info)
@ -520,9 +542,6 @@ class RBDTestCase(test.TestCase):
@common_mocks
def test_create_cloned_volume_same_size(self):
src_name = u'volume-00000001'
dst_name = u'volume-00000002'
self.cfg.rbd_max_clone_depth = 2
with mock.patch.object(self.driver, '_get_clone_depth') as \
@ -531,17 +550,14 @@ class RBDTestCase(test.TestCase):
with mock.patch.object(self.driver, '_resize') as mock_resize:
mock_get_clone_depth.return_value = 1
self.driver.create_cloned_volume({'name': dst_name,
'size': 10},
{'name': src_name,
'size': 10})
self.driver.create_cloned_volume(self.volume_b, self.volume_a)
(self.mock_rbd.Image.return_value.create_snap
.assert_called_once_with('.'.join((dst_name,
'clone_snap'))))
.assert_called_once_with('.'.join(
(self.volume_b.name, 'clone_snap'))))
(self.mock_rbd.Image.return_value.protect_snap
.assert_called_once_with('.'.join((dst_name,
'clone_snap'))))
.assert_called_once_with('.'.join(
(self.volume_b.name, 'clone_snap'))))
self.assertEqual(
1, self.mock_rbd.RBD.return_value.clone.call_count)
self.mock_rbd.Image.return_value.close \
@ -552,9 +568,6 @@ class RBDTestCase(test.TestCase):
@common_mocks
def test_create_cloned_volume_different_size(self):
src_name = u'volume-00000001'
dst_name = u'volume-00000002'
self.cfg.rbd_max_clone_depth = 2
with mock.patch.object(self.driver, '_get_clone_depth') as \
@ -563,17 +576,15 @@ class RBDTestCase(test.TestCase):
with mock.patch.object(self.driver, '_resize') as mock_resize:
mock_get_clone_depth.return_value = 1
self.driver.create_cloned_volume({'name': dst_name,
'size': 20},
{'name': src_name,
'size': 10})
self.volume_b.size = 20
self.driver.create_cloned_volume(self.volume_b, self.volume_a)
(self.mock_rbd.Image.return_value.create_snap
.assert_called_once_with('.'.join((dst_name,
'clone_snap'))))
.assert_called_once_with('.'.join(
(self.volume_b.name, 'clone_snap'))))
(self.mock_rbd.Image.return_value.protect_snap
.assert_called_once_with('.'.join((dst_name,
'clone_snap'))))
.assert_called_once_with('.'.join(
(self.volume_b.name, 'clone_snap'))))
self.assertEqual(
1, self.mock_rbd.RBD.return_value.clone.call_count)
self.mock_rbd.Image.return_value.close \
@ -584,34 +595,34 @@ class RBDTestCase(test.TestCase):
@common_mocks
def test_create_cloned_volume_w_flatten(self):
src_name = u'volume-00000001'
dst_name = u'volume-00000002'
self.cfg.rbd_max_clone_depth = 1
with mock.patch.object(self.driver, '_get_clone_info') as \
mock_get_clone_info:
mock_get_clone_info.return_value = (
('fake_pool', dst_name, '.'.join((dst_name, 'clone_snap'))))
('fake_pool', self.volume_b.name,
'.'.join((self.volume_b.name, 'clone_snap'))))
with mock.patch.object(self.driver, '_get_clone_depth') as \
mock_get_clone_depth:
# Try with no flatten required
mock_get_clone_depth.return_value = 1
self.assertRaises(self.mock_rbd.RBD.Error,
self.driver.create_cloned_volume,
dict(name=dst_name), dict(name=src_name))
self.driver.create_cloned_volume(self.volume_b, self.volume_a)
(self.mock_rbd.Image.return_value.create_snap
.assert_called_once_with('.'.join((dst_name, 'clone_snap'))))
.assert_called_once_with('.'.join(
(self.volume_b.name, 'clone_snap'))))
(self.mock_rbd.Image.return_value.protect_snap
.assert_called_once_with('.'.join((dst_name, 'clone_snap'))))
.assert_called_once_with('.'.join(
(self.volume_b.name, 'clone_snap'))))
self.assertEqual(
1, self.mock_rbd.RBD.return_value.clone.call_count)
(self.mock_rbd.Image.return_value.unprotect_snap
.assert_called_once_with('.'.join((dst_name, 'clone_snap'))))
.assert_called_once_with('.'.join(
(self.volume_b.name, 'clone_snap'))))
(self.mock_rbd.Image.return_value.remove_snap
.assert_called_once_with('.'.join((dst_name, 'clone_snap'))))
.assert_called_once_with('.'.join(
(self.volume_b.name, 'clone_snap'))))
# We expect the driver to close both volumes, so 2 is expected
self.assertEqual(
@ -620,9 +631,6 @@ class RBDTestCase(test.TestCase):
@common_mocks
def test_create_cloned_volume_w_clone_exception(self):
src_name = u'volume-00000001'
dst_name = u'volume-00000002'
self.cfg.rbd_max_clone_depth = 2
self.mock_rbd.RBD.return_value.clone.side_effect = (
self.mock_rbd.RBD.Error)
@ -633,18 +641,22 @@ class RBDTestCase(test.TestCase):
self.assertRaises(self.mock_rbd.RBD.Error,
self.driver.create_cloned_volume,
{'name': dst_name}, {'name': src_name})
self.volume_b, self.volume_a)
(self.mock_rbd.Image.return_value.create_snap
.assert_called_once_with('.'.join((dst_name, 'clone_snap'))))
.assert_called_once_with('.'.join(
(self.volume_b.name, 'clone_snap'))))
(self.mock_rbd.Image.return_value.protect_snap
.assert_called_once_with('.'.join((dst_name, 'clone_snap'))))
.assert_called_once_with('.'.join(
(self.volume_b.name, 'clone_snap'))))
self.assertEqual(
1, self.mock_rbd.RBD.return_value.clone.call_count)
(self.mock_rbd.Image.return_value.unprotect_snap
.assert_called_once_with('.'.join((dst_name, 'clone_snap'))))
.assert_called_once_with('.'.join(
(self.volume_b.name, 'clone_snap'))))
(self.mock_rbd.Image.return_value.remove_snap
.assert_called_once_with('.'.join((dst_name, 'clone_snap'))))
.assert_called_once_with('.'.join(
(self.volume_b.name, 'clone_snap'))))
self.mock_rbd.Image.return_value.close.assert_called_once_with()
@common_mocks
@ -720,7 +732,7 @@ class RBDTestCase(test.TestCase):
with mock.patch.object(self.driver, 'delete_volume'):
with mock.patch.object(self.driver, '_resize'):
mock_image_service = mock.MagicMock()
args = [None, {'name': 'test', 'size': 1},
args = [None, self.volume_a,
mock_image_service, None]
self.driver.copy_image_to_volume(*args)
@ -811,23 +823,21 @@ class RBDTestCase(test.TestCase):
mock_get_mon_addrs:
mock_get_mon_addrs.return_value = (hosts, ports)
volume_id = '0a83f0a3-ef6e-47b6-a8aa-20436bc9ed01'
expected = {
'driver_volume_type': 'rbd',
'data': {
'name': '%s/%s' % (self.cfg.rbd_pool,
self.volume_name),
self.volume_a.name),
'hosts': hosts,
'ports': ports,
'auth_enabled': False,
'auth_username': None,
'secret_type': 'ceph',
'secret_uuid': None,
'volume_id': volume_id
'volume_id': self.volume_a.id
}
}
volume = dict(name=self.volume_name, id=volume_id)
actual = self.driver.initialize_connection(volume, None)
actual = self.driver.initialize_connection(self.volume_a, None)
self.assertDictMatch(expected, actual)
self.assertTrue(mock_get_mon_addrs.called)
@ -849,10 +859,10 @@ class RBDTestCase(test.TestCase):
# capture both rados client used to perform the clone
client.__enter__.side_effect = mock__enter__(client)
self.driver._clone(self.volume, src_pool, src_image, src_snap)
self.driver._clone(self.volume_a, src_pool, src_image, src_snap)
args = [client_stack[0].ioctx, str(src_image), str(src_snap),
client_stack[1].ioctx, str(self.volume_name)]
client_stack[1].ioctx, str(self.volume_a.name)]
kwargs = {'features': client.features}
self.mock_rbd.RBD.return_value.clone.assert_called_once_with(
*args, **kwargs)
@ -861,14 +871,10 @@ class RBDTestCase(test.TestCase):
@common_mocks
def test_extend_volume(self):
fake_size = '20'
fake_vol = {'project_id': 'testprjid', 'name': self.volume_name,
'size': fake_size,
'id': 'a720b3c0-d1f0-11e1-9b23-0800200c9a66'}
size = int(fake_size) * units.Gi
with mock.patch.object(self.driver, '_resize') as mock_resize:
self.driver.extend_volume(fake_vol, fake_size)
mock_resize.assert_called_once_with(fake_vol, size=size)
self.driver.extend_volume(self.volume_a, fake_size)
mock_resize.assert_called_once_with(self.volume_a, size=size)
@common_mocks
def test_retype(self):
@ -910,27 +916,21 @@ class RBDTestCase(test.TestCase):
with mock.patch.object(self.driver.rbd.RBD(), 'rename') as mock_rename:
context = {}
current_volume = {'id': 'curr_id',
'name': 'curr_name',
'provider_location': 'curr_provider_location'}
original_volume = {'id': 'orig_id',
'name': 'orig_name',
'provider_location': 'orig_provider_location'}
mock_rename.return_value = 0
model_update = self.driver.update_migrated_volume(context,
original_volume,
current_volume,
self.volume_a,
self.volume_b,
'available')
mock_rename.assert_called_with(client.ioctx,
'volume-%s' % current_volume['id'],
'volume-%s' % original_volume['id'])
'volume-%s' % self.volume_b.id,
'volume-%s' % self.volume_a.id)
self.assertEqual({'_name_id': None,
'provider_location': None}, model_update)
def test_rbd_volume_proxy_init(self):
mock_driver = mock.Mock(name='driver')
mock_driver._connect_to_rados.return_value = (None, None)
with driver.RBDVolumeProxy(mock_driver, self.volume_name):
with driver.RBDVolumeProxy(mock_driver, self.volume_a.name):
self.assertEqual(1, mock_driver._connect_to_rados.call_count)
self.assertFalse(mock_driver._disconnect_from_rados.called)
@ -939,7 +939,7 @@ class RBDTestCase(test.TestCase):
mock_driver.reset_mock()
snap = u'snapshot-name'
with driver.RBDVolumeProxy(mock_driver, self.volume_name,
with driver.RBDVolumeProxy(mock_driver, self.volume_a.name,
snapshot=snap):
self.assertEqual(1, mock_driver._connect_to_rados.call_count)
self.assertFalse(mock_driver._disconnect_from_rados.called)

View File

@ -454,8 +454,8 @@ class RBDDriver(driver.TransferVD, driver.ExtendVD,
and that clone has rbd_max_clone_depth clones behind it, the source
volume will be flattened.
"""
src_name = utils.convert_str(src_vref['name'])
dest_name = utils.convert_str(volume['name'])
src_name = utils.convert_str(src_vref.name)
dest_name = utils.convert_str(volume.name)
flatten_parent = False
# Do full copy if requested
@ -520,27 +520,27 @@ class RBDDriver(driver.TransferVD, driver.ExtendVD,
finally:
src_volume.close()
if volume['size'] != src_vref['size']:
if volume.size != src_vref.size:
LOG.debug("resize volume '%(dst_vol)s' from %(src_size)d to "
"%(dst_size)d",
{'dst_vol': volume['name'], 'src_size': src_vref['size'],
'dst_size': volume['size']})
{'dst_vol': volume.name, 'src_size': src_vref.size,
'dst_size': volume.size})
self._resize(volume)
LOG.debug("clone created successfully")
def create_volume(self, volume):
"""Creates a logical volume."""
size = int(volume['size']) * units.Gi
size = int(volume.size) * units.Gi
LOG.debug("creating volume '%s'", volume['name'])
LOG.debug("creating volume '%s'", volume.name)
chunk_size = self.configuration.rbd_store_chunk_size * units.Mi
order = int(math.log(chunk_size, 2))
with RADOSClient(self) as client:
self.RBDProxy().create(client.ioctx,
utils.convert_str(volume['name']),
utils.convert_str(volume.name),
size,
order,
old_format=False,
@ -555,31 +555,31 @@ class RBDDriver(driver.TransferVD, driver.ExtendVD,
def _clone(self, volume, src_pool, src_image, src_snap):
LOG.debug('cloning %(pool)s/%(img)s@%(snap)s to %(dst)s',
dict(pool=src_pool, img=src_image, snap=src_snap,
dst=volume['name']))
dst=volume.name))
with RADOSClient(self, src_pool) as src_client:
with RADOSClient(self) as dest_client:
self.RBDProxy().clone(src_client.ioctx,
utils.convert_str(src_image),
utils.convert_str(src_snap),
dest_client.ioctx,
utils.convert_str(volume['name']),
utils.convert_str(volume.name),
features=src_client.features)
def _resize(self, volume, **kwargs):
size = kwargs.get('size', None)
if not size:
size = int(volume['size']) * units.Gi
size = int(volume.size) * units.Gi
with RBDVolumeProxy(self, volume['name']) as vol:
with RBDVolumeProxy(self, volume.name) as vol:
vol.resize(size)
def create_volume_from_snapshot(self, volume, snapshot):
"""Creates a volume from a snapshot."""
self._clone(volume, self.configuration.rbd_pool,
snapshot['volume_name'], snapshot['name'])
snapshot.volume_name, snapshot.name)
if self.configuration.rbd_flatten_volume_from_snapshot:
self._flatten(self.configuration.rbd_pool, volume['name'])
if int(volume['size']):
self._flatten(self.configuration.rbd_pool, volume.name)
if int(volume.size):
self._resize(volume)
def _delete_backup_snaps(self, rbd_image):
@ -666,7 +666,7 @@ class RBDDriver(driver.TransferVD, driver.ExtendVD,
"""Deletes a logical volume."""
# NOTE(dosaboy): this was broken by commit cbe1d5f. Ensure names are
# utf-8 otherwise librbd will barf.
volume_name = utils.convert_str(volume['name'])
volume_name = utils.convert_str(volume.name)
with RADOSClient(self) as client:
try:
rbd_image = self.rbd.Image(client.ioctx, volume_name)
@ -686,11 +686,11 @@ class RBDDriver(driver.TransferVD, driver.ExtendVD,
try:
snaps = rbd_image.list_snaps()
for snap in snaps:
if snap['name'].endswith('.clone_snap'):
if snap.name.endswith('.clone_snap'):
LOG.debug("volume has clone snapshot(s)")
# We grab one of these and use it when fetching parent
# info in case the volume has been flattened.
clone_snap = snap['name']
clone_snap = snap.name
break
raise exception.VolumeIsBusy(volume_name=volume_name)
@ -739,8 +739,8 @@ class RBDDriver(driver.TransferVD, driver.ExtendVD,
def create_snapshot(self, snapshot):
"""Creates an rbd snapshot."""
with RBDVolumeProxy(self, snapshot['volume_name']) as volume:
snap = utils.convert_str(snapshot['name'])
with RBDVolumeProxy(self, snapshot.volume_name) as volume:
snap = utils.convert_str(snapshot.name)
volume.create_snap(snap)
volume.protect_snap(snap)
@ -748,8 +748,8 @@ class RBDDriver(driver.TransferVD, driver.ExtendVD,
"""Deletes an rbd snapshot."""
# NOTE(dosaboy): this was broken by commit cbe1d5f. Ensure names are
# utf-8 otherwise librbd will barf.
volume_name = utils.convert_str(snapshot['volume_name'])
snap_name = utils.convert_str(snapshot['name'])
volume_name = utils.convert_str(snapshot.volume_name)
snap_name = utils.convert_str(snapshot.name)
with RBDVolumeProxy(self, volume_name) as volume:
try:
@ -802,14 +802,14 @@ class RBDDriver(driver.TransferVD, driver.ExtendVD,
'driver_volume_type': 'rbd',
'data': {
'name': '%s/%s' % (self.configuration.rbd_pool,
volume['name']),
volume.name),
'hosts': hosts,
'ports': ports,
'auth_enabled': (self.configuration.rbd_user is not None),
'auth_username': self.configuration.rbd_user,
'secret_type': 'ceph',
'secret_uuid': self.configuration.rbd_secret_uuid,
'volume_id': volume['id'],
'volume_id': volume.id,
}
}
LOG.debug('connection data: %s', data)
@ -915,7 +915,7 @@ class RBDDriver(driver.TransferVD, driver.ExtendVD,
image_utils.fetch_to_raw(context, image_service, image_id,
tmp.name,
self.configuration.volume_dd_blocksize,
size=volume['size'])
size=volume.size)
self.delete_volume(volume)
@ -926,7 +926,7 @@ class RBDDriver(driver.TransferVD, driver.ExtendVD,
args = ['rbd', 'import',
'--pool', self.configuration.rbd_pool,
'--order', order,
tmp.name, volume['name'],
tmp.name, volume.name,
'--new-format']
args.extend(self._ceph_args())
self._try_execute(*args)
@ -935,11 +935,11 @@ class RBDDriver(driver.TransferVD, driver.ExtendVD,
def copy_volume_to_image(self, context, volume, image_service, image_meta):
tmp_dir = self._image_conversion_dir()
tmp_file = os.path.join(tmp_dir,
volume['name'] + '-' + image_meta['id'])
volume.name + '-' + image_meta['id'])
with fileutils.remove_path_on_error(tmp_file):
args = ['rbd', 'export',
'--pool', self.configuration.rbd_pool,
volume['name'], tmp_file]
volume.name, tmp_file]
args.extend(self._ceph_args())
self._try_execute(*args)
image_utils.upload_volume(context, image_service,
@ -948,9 +948,9 @@ class RBDDriver(driver.TransferVD, driver.ExtendVD,
def backup_volume(self, context, backup, backup_service):
"""Create a new backup from an existing volume."""
volume = self.db.volume_get(context, backup['volume_id'])
volume = self.db.volume_get(context, backup.volume_id)
with RBDVolumeProxy(self, volume['name'],
with RBDVolumeProxy(self, volume.name,
self.configuration.rbd_pool) as rbd_image:
rbd_meta = RBDImageMetadata(rbd_image, self.configuration.rbd_pool,
self.configuration.rbd_user,
@ -962,26 +962,26 @@ class RBDDriver(driver.TransferVD, driver.ExtendVD,
def restore_backup(self, context, backup, volume, backup_service):
"""Restore an existing backup to a new or existing volume."""
with RBDVolumeProxy(self, volume['name'],
with RBDVolumeProxy(self, volume.name,
self.configuration.rbd_pool) as rbd_image:
rbd_meta = RBDImageMetadata(rbd_image, self.configuration.rbd_pool,
self.configuration.rbd_user,
self.configuration.rbd_ceph_conf)
rbd_fd = RBDImageIOWrapper(rbd_meta)
backup_service.restore(backup, volume['id'], rbd_fd)
backup_service.restore(backup, volume.id, rbd_fd)
LOG.debug("volume restore complete.")
def extend_volume(self, volume, new_size):
"""Extend an existing volume."""
old_size = volume['size']
old_size = volume.size
try:
size = int(new_size) * units.Gi
self._resize(volume, size=size)
except Exception:
msg = _('Failed to Extend Volume '
'%(volname)s') % {'volname': volume['name']}
'%(volname)s') % {'volname': volume.name}
LOG.error(msg)
raise exception.VolumeBackendAPIException(data=msg)
@ -1005,7 +1005,7 @@ class RBDDriver(driver.TransferVD, driver.ExtendVD,
rbd_name = existing_ref['source-name']
self.RBDProxy().rename(client.ioctx,
utils.convert_str(rbd_name),
utils.convert_str(volume['name']))
utils.convert_str(volume.name))
def manage_existing_get_size(self, volume, existing_ref):
"""Return size of an existing image for manage_existing.
@ -1069,8 +1069,8 @@ class RBDDriver(driver.TransferVD, driver.ExtendVD,
name_id = None
provider_location = None
existing_name = CONF.volume_name_template % new_volume['id']
wanted_name = CONF.volume_name_template % volume['id']
existing_name = CONF.volume_name_template % new_volume.id
wanted_name = CONF.volume_name_template % volume.id
with RADOSClient(self) as client:
try:
self.RBDProxy().rename(client.ioctx,
@ -1078,11 +1078,11 @@ class RBDDriver(driver.TransferVD, driver.ExtendVD,
utils.convert_str(wanted_name))
except self.rbd.ImageNotFound:
LOG.error(_LE('Unable to rename the logical volume '
'for volume %s.'), volume['id'])
'for volume %s.'), volume.id)
# If the rename fails, _name_id should be set to the new
# volume id and provider_location should be set to the
# one from the new volume as well.
name_id = new_volume['_name_id'] or new_volume['id']
name_id = new_volume._name_id or new_volume.id
provider_location = new_volume['provider_location']
return {'_name_id': name_id, 'provider_location': provider_location}