Cloning image fails results duplicate cache entry

When creating a volume with image whose cache
entry is already present,results in duplicate
cache entry when create_clone_image() fails.

Closes-Bug: #1552734
Change-Id: I0708c333fa94bb44e66f64b2b7cc3bc0dbe8a409
This commit is contained in:
Vishakha Agarwal 2018-05-10 11:14:40 +05:30
parent d2b3e1011e
commit a74f7f0cd0
2 changed files with 36 additions and 3 deletions

View File

@ -37,7 +37,6 @@ from cinder.tests.unit import volume as base
import cinder.volume import cinder.volume
from cinder.volume import manager as vol_manager from cinder.volume import manager as vol_manager
QUOTAS = quota.QUOTAS QUOTAS = quota.QUOTAS
NON_EXISTENT_IMAGE_ID = '003f540f-ec6b-4293-a3f9-7c68646b0f5c' NON_EXISTENT_IMAGE_ID = '003f540f-ec6b-4293-a3f9-7c68646b0f5c'
@ -61,10 +60,10 @@ class CopyVolumeToImageTestCase(base.BaseVolumeTestCase):
super(CopyVolumeToImageTestCase, self).setUp() super(CopyVolumeToImageTestCase, self).setUp()
self.dst_fd, self.dst_path = tempfile.mkstemp() self.dst_fd, self.dst_path = tempfile.mkstemp()
self.addCleanup(os.unlink, self.dst_path) self.addCleanup(os.unlink, self.dst_path)
os.close(self.dst_fd) os.close(self.dst_fd)
self.mock_object(self.volume.driver, 'local_path', self.mock_object(self.volume.driver, 'local_path',
self.fake_local_path) self.fake_local_path)
self.mock_cache = mock.MagicMock()
self.image_id = '70a599e0-31e7-49b7-b260-868f441e862b' self.image_id = '70a599e0-31e7-49b7-b260-868f441e862b'
self.image_meta = { self.image_meta = {
'id': self.image_id, 'id': self.image_id,
@ -330,6 +329,31 @@ class CopyVolumeToImageTestCase(base.BaseVolumeTestCase):
self.assertNotIn('locations', image) self.assertNotIn('locations', image)
self.assertTrue(mock_delete.called) self.assertTrue(mock_delete.called)
@mock.patch('cinder.volume.manager.'
'VolumeManager._clone_image_volume')
@mock.patch('cinder.volume.manager.'
'VolumeManager._create_image_cache_volume_entry')
def test_create_image_cache_volume_entry(self,
mock_cache_entry,
mock_clone_image_volume):
image_id = self.image_id
image_meta = self.image_meta
self.mock_cache.get_entry.return_value = mock_cache_entry
if mock_cache_entry:
# Entry is in cache, so basically don't do anything.
# Make sure we didn't try and create a cache entry
self.assertFalse(self.mock_cache.ensure_space.called)
self.assertFalse(self.mock_cache.create_cache_entry.called)
else:
result = self.volume._create_image_cache_volume_entry(
self.context, mock_clone_image_volume, image_id, image_meta)
self.assertNotEqual(False, result)
cache_entry = self.image_volume_cache.get_entry(
self.context, mock_clone_image_volume, image_id, image_meta)
self.assertIsNotNone(cache_entry)
class ImageVolumeCacheTestCase(base.BaseVolumeTestCase): class ImageVolumeCacheTestCase(base.BaseVolumeTestCase):

View File

@ -1370,6 +1370,16 @@ class VolumeManager(manager.CleanableManager,
This assumes that the image has already been downloaded and stored This assumes that the image has already been downloaded and stored
in the volume described by the volume_ref. in the volume described by the volume_ref.
""" """
cache_entry = self.image_volume_cache.get_entry(ctx,
volume_ref,
image_id,
image_meta)
if cache_entry:
LOG.debug('Cache entry already exists with image ID %'
'(image_id)s',
{'image_id': image_id})
return
image_volume = None image_volume = None
try: try:
if not self.image_volume_cache.ensure_space(ctx, volume_ref): if not self.image_volume_cache.ensure_space(ctx, volume_ref):
@ -1388,7 +1398,6 @@ class VolumeManager(manager.CleanableManager,
'%(image_id)s will not create cache entry.', '%(image_id)s will not create cache entry.',
{'image_id': image_id}) {'image_id': image_id})
return return
self.image_volume_cache.create_cache_entry( self.image_volume_cache.create_cache_entry(
ctx, ctx,
image_volume, image_volume,