Merge "NFS update volume attachment format during volume snapshot"
This commit is contained in:
commit
a7b1388932
@ -1066,17 +1066,19 @@ class NfsDriverTestCase(test.TestCase):
|
|||||||
if file_format:
|
if file_format:
|
||||||
volume.admin_metadata = {'format': file_format}
|
volume.admin_metadata = {'format': file_format}
|
||||||
mock_get.return_value = volume
|
mock_get.return_value = volume
|
||||||
path = 'path'
|
local_vol_dir = 'dir'
|
||||||
newSize = volume['size'] + 1
|
newSize = volume['size'] + 1
|
||||||
|
|
||||||
with mock.patch.object(image_utils, 'resize_image') as resize:
|
with mock.patch.object(image_utils, 'resize_image') as resize:
|
||||||
with mock.patch.object(drv, 'local_path', return_value=path):
|
with mock.patch.object(drv, '_local_volume_dir',
|
||||||
|
return_value=local_vol_dir):
|
||||||
with mock.patch.object(drv, '_is_share_eligible',
|
with mock.patch.object(drv, '_is_share_eligible',
|
||||||
return_value=True):
|
return_value=True):
|
||||||
with mock.patch.object(drv, '_is_file_size_equal',
|
with mock.patch.object(drv, '_is_file_size_equal',
|
||||||
return_value=True):
|
return_value=True):
|
||||||
drv.extend_volume(volume, newSize)
|
drv.extend_volume(volume, newSize)
|
||||||
|
|
||||||
|
path = os.path.join(local_vol_dir, volume.name)
|
||||||
resize.assert_called_once_with(path, newSize,
|
resize.assert_called_once_with(path, newSize,
|
||||||
run_as_root=True,
|
run_as_root=True,
|
||||||
file_format=file_format)
|
file_format=file_format)
|
||||||
|
@ -363,11 +363,13 @@ class RemoteFsSnapDriverTestCase(test.TestCase):
|
|||||||
self.context, connection_info=conn_info)
|
self.context, connection_info=conn_info)
|
||||||
snapshot.volume.volume_attachment.objects.append(attachment)
|
snapshot.volume.volume_attachment.objects.append(attachment)
|
||||||
mock_save = self.mock_object(attachment, 'save')
|
mock_save = self.mock_object(attachment, 'save')
|
||||||
|
mock_vol_save = self.mock_object(snapshot.volume, 'save')
|
||||||
|
|
||||||
# After the snapshot the connection info should change the name of
|
# After the snapshot the connection info should change the name of
|
||||||
# the file
|
# the file
|
||||||
expected = copy.deepcopy(attachment.connection_info)
|
expected = copy.deepcopy(attachment.connection_info)
|
||||||
expected['name'] = snapshot.volume.name + '.' + snapshot.id
|
expected['name'] = snapshot.volume.name + '.' + snapshot.id
|
||||||
|
expected['format'] = 'qcow2'
|
||||||
else:
|
else:
|
||||||
expected_method_called = '_do_create_snapshot'
|
expected_method_called = '_do_create_snapshot'
|
||||||
|
|
||||||
@ -386,6 +388,8 @@ class RemoteFsSnapDriverTestCase(test.TestCase):
|
|||||||
|
|
||||||
if volume_in_use:
|
if volume_in_use:
|
||||||
mock_save.assert_called_once()
|
mock_save.assert_called_once()
|
||||||
|
# We should have updated the volume format after the snapshot
|
||||||
|
mock_vol_save.assert_called_once()
|
||||||
changed_fields = attachment.cinder_obj_get_changes()
|
changed_fields = attachment.cinder_obj_get_changes()
|
||||||
self.assertEqual(expected, changed_fields['connection_info'])
|
self.assertEqual(expected, changed_fields['connection_info'])
|
||||||
|
|
||||||
|
@ -392,18 +392,22 @@ class NfsDriver(remotefs.RemoteFSSnapDriverDistributed):
|
|||||||
raise exception.ExtendVolumeError(reason='Insufficient space to'
|
raise exception.ExtendVolumeError(reason='Insufficient space to'
|
||||||
' extend volume %s to %sG'
|
' extend volume %s to %sG'
|
||||||
% (volume.id, new_size))
|
% (volume.id, new_size))
|
||||||
path = self.local_path(volume)
|
# Use the active image file because this volume might have snapshot(s).
|
||||||
|
active_file = self.get_active_image_from_info(volume)
|
||||||
|
active_file_path = os.path.join(self._local_volume_dir(volume),
|
||||||
|
active_file)
|
||||||
LOG.info('Resizing file to %sG...', new_size)
|
LOG.info('Resizing file to %sG...', new_size)
|
||||||
file_format = None
|
file_format = None
|
||||||
admin_metadata = objects.Volume.get_by_id(
|
admin_metadata = objects.Volume.get_by_id(
|
||||||
context.get_admin_context(), volume.id).admin_metadata
|
context.get_admin_context(), volume.id).admin_metadata
|
||||||
|
|
||||||
if admin_metadata and 'format' in admin_metadata:
|
if admin_metadata and 'format' in admin_metadata:
|
||||||
file_format = admin_metadata['format']
|
file_format = admin_metadata['format']
|
||||||
image_utils.resize_image(path, new_size,
|
image_utils.resize_image(active_file_path, new_size,
|
||||||
run_as_root=self._execute_as_root,
|
run_as_root=self._execute_as_root,
|
||||||
file_format=file_format)
|
file_format=file_format)
|
||||||
if file_format == 'qcow2' and not self._is_file_size_equal(
|
if file_format == 'qcow2' and not self._is_file_size_equal(
|
||||||
path, new_size):
|
active_file_path, new_size):
|
||||||
raise exception.ExtendVolumeError(
|
raise exception.ExtendVolumeError(
|
||||||
reason='Resizing image file failed.')
|
reason='Resizing image file failed.')
|
||||||
|
|
||||||
|
@ -1720,9 +1720,18 @@ class RemoteFSSnapDriverBase(RemoteFSDriver):
|
|||||||
self._create_snapshot_online(snapshot,
|
self._create_snapshot_online(snapshot,
|
||||||
backing_filename,
|
backing_filename,
|
||||||
new_snap_path)
|
new_snap_path)
|
||||||
|
# Update the format for the volume and the connection_info. The
|
||||||
|
# connection_info needs to reflect the current volume format in
|
||||||
|
# order for Nova to create the disk device correctly whenever the
|
||||||
|
# instance is stopped/started or rebooted.
|
||||||
|
new_format = 'qcow2'
|
||||||
|
snapshot.volume.admin_metadata['format'] = new_format
|
||||||
|
with snapshot.volume.obj_as_admin():
|
||||||
|
snapshot.volume.save()
|
||||||
# Update reference in the only attachment (no multi-attach support)
|
# Update reference in the only attachment (no multi-attach support)
|
||||||
attachment = snapshot.volume.volume_attachment[0]
|
attachment = snapshot.volume.volume_attachment[0]
|
||||||
attachment.connection_info['name'] = active
|
attachment.connection_info['name'] = active
|
||||||
|
attachment.connection_info['format'] = new_format
|
||||||
# Let OVO know it has been updated
|
# Let OVO know it has been updated
|
||||||
attachment.connection_info = attachment.connection_info
|
attachment.connection_info = attachment.connection_info
|
||||||
attachment.save()
|
attachment.save()
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
fixes:
|
||||||
|
- |
|
||||||
|
NFS driver `bug #1989514`_: When creating a snapshot of an attached volume,
|
||||||
|
the volume attachment format was not updated in its connection_info and
|
||||||
|
could have resulted in an unbootable guest. This has been fixed.
|
||||||
|
|
||||||
|
.. _bug #1989514: https://bugs.launchpad.net/cinder/+bug/1989514
|
Loading…
Reference in New Issue
Block a user