Fix for volume from image snapshot free space issue
create_from_image() function checks for free space in conversion path (by default /var/lib/cinder/conversion) even if cinder is creating volume from image snapshot. If /var/lib/cinder/conversion has less free space than the size of the image volume is created from, exception will be thrown by check_available_space() function in image_utils module. This patch checks if cinder is configured with allowed_direct_url_schemes = cinder If so, cinder should not check free space in conversion path because volume is created from image snapshot. Closes-Bug: #1683228 Change-Id: I6330ed31dc9336c9d3d09c2d43c8f4913744e9a2
This commit is contained in:
parent
9ae14ed0fc
commit
30bb0dfbe7
@ -1139,6 +1139,71 @@ class CreateVolumeFlowManagerGlanceCinderBackendCase(test.TestCase):
|
||||
self.assertFalse(fake_driver.create_cloned_volume.called)
|
||||
mock_cleanup_cg.assert_called_once_with(volume)
|
||||
|
||||
@mock.patch('cinder.volume.flows.manager.create_volume.'
|
||||
'CreateVolumeFromSpecTask.'
|
||||
'_cleanup_cg_in_volume')
|
||||
@mock.patch('cinder.image.image_utils.TemporaryImages.fetch')
|
||||
@mock.patch('cinder.volume.flows.manager.create_volume.'
|
||||
'CreateVolumeFromSpecTask.'
|
||||
'_handle_bootable_volume_glance_meta')
|
||||
@mock.patch('cinder.image.image_utils.qemu_img_info')
|
||||
def test_create_from_image_volume_ignore_size(self, mock_qemu_info,
|
||||
handle_bootable,
|
||||
mock_fetch_img,
|
||||
mock_cleanup_cg,
|
||||
format='raw',
|
||||
owner=None,
|
||||
location=True):
|
||||
self.flags(allowed_direct_url_schemes=['cinder'])
|
||||
self.override_config('allowed_direct_url_schemes', 'cinder')
|
||||
mock_fetch_img.return_value = mock.MagicMock(
|
||||
spec=utils.get_file_spec())
|
||||
fake_db = mock.MagicMock()
|
||||
fake_driver = mock.MagicMock()
|
||||
fake_manager = create_volume_manager.CreateVolumeFromSpecTask(
|
||||
mock.MagicMock(), fake_db, fake_driver)
|
||||
fake_image_service = fake_image.FakeImageService()
|
||||
|
||||
volume = fake_volume.fake_volume_obj(self.ctxt,
|
||||
host='host@backend#pool')
|
||||
image_volume = fake_volume.fake_volume_obj(self.ctxt,
|
||||
volume_metadata={})
|
||||
image_id = fakes.IMAGE_ID
|
||||
image_info = imageutils.QemuImgInfo()
|
||||
# Making huge image. If cinder will try to convert it, it
|
||||
# will fail because of free space being too low.
|
||||
image_info.virtual_size = '1073741824000000000000'
|
||||
mock_qemu_info.return_value = image_info
|
||||
url = 'cinder://%s' % image_volume['id']
|
||||
image_location = None
|
||||
if location:
|
||||
image_location = (url, [{'url': url, 'metadata': {}}])
|
||||
image_meta = {'id': image_id,
|
||||
'container_format': 'bare',
|
||||
'disk_format': format,
|
||||
'size': 1024,
|
||||
'owner': owner or self.ctxt.project_id,
|
||||
'virtual_size': None,
|
||||
'cinder_encryption_key_id': None}
|
||||
|
||||
fake_driver.clone_image.return_value = (None, False)
|
||||
fake_db.volume_get_all_by_host.return_value = [image_volume]
|
||||
fake_manager._create_from_image(self.ctxt,
|
||||
volume,
|
||||
image_location,
|
||||
image_id,
|
||||
image_meta,
|
||||
fake_image_service)
|
||||
if format is 'raw' and not owner and location:
|
||||
fake_driver.create_cloned_volume.assert_called_once_with(
|
||||
volume, image_volume)
|
||||
handle_bootable.assert_called_once_with(self.ctxt, volume,
|
||||
image_id=image_id,
|
||||
image_meta=image_meta)
|
||||
else:
|
||||
self.assertFalse(fake_driver.create_cloned_volume.called)
|
||||
mock_cleanup_cg.assert_called_once_with(volume)
|
||||
|
||||
def test_create_from_image_volume_in_qcow2_format(self):
|
||||
self.test_create_from_image_volume(format='qcow2')
|
||||
|
||||
|
@ -823,8 +823,19 @@ class CreateVolumeFromSpecTask(flow_utils.CinderTask):
|
||||
os.path.exists(CONF.image_conversion_dir)):
|
||||
os.makedirs(CONF.image_conversion_dir)
|
||||
try:
|
||||
image_utils.check_available_space(CONF.image_conversion_dir,
|
||||
image_meta['size'], image_id)
|
||||
# cinder should not check free space in conversion directory
|
||||
# if it's creating volume from image snapshot (Bug1683228).
|
||||
# If image disk format is other than raw, cinder should
|
||||
# convert it (this means free space check will be needed).
|
||||
if ('cinder' in CONF.allowed_direct_url_schemes and
|
||||
image_meta.get('disk_format') == 'raw'):
|
||||
LOG.debug("Creating volume from image snapshot. "
|
||||
"Skipping free space check on image "
|
||||
"convert path.")
|
||||
else:
|
||||
image_utils.check_available_space(
|
||||
CONF.image_conversion_dir,
|
||||
image_meta['size'], image_id)
|
||||
except exception.ImageTooBig as err:
|
||||
with excutils.save_and_reraise_exception():
|
||||
self.message.create(
|
||||
|
Loading…
Reference in New Issue
Block a user