Add ability to upload duplicate images

In the basic case, avoiding re-uploading images is nice because
uploading images is a costly operation. However, there are also usecases
for uploading new images with the same name as an operator which are
quite valid. Support these by allowing for a flag that overrides the
duplicate checking logic.

Change-Id: I6a00753654d500d68750e46c5ec2423a36903552
This commit is contained in:
Monty Taylor 2016-08-01 16:19:33 -05:00
parent 1a1107ad73
commit 3ef3864785
No known key found for this signature in database
GPG Key ID: 7BAE94BC7141A594
2 changed files with 70 additions and 7 deletions

View File

@ -2546,7 +2546,8 @@ class OpenStackCloud(object):
md5=None, sha256=None,
disk_format=None, container_format=None,
disable_vendor_agent=True,
wait=False, timeout=3600, **kwargs):
wait=False, timeout=3600,
allow_duplicates=False, **kwargs):
"""Upload an image to Glance.
:param str name: Name of the image to create. If it is a pathname
@ -2578,6 +2579,8 @@ class OpenStackCloud(object):
true - however, be aware that one of the upload
methods is always synchronous.
:param timeout: Seconds to wait for image creation. None is forever.
:param allow_duplicates: If true, skips checks that enforce unique
image name. (optional, defaults to False)
Additional kwargs will be passed to the image creation as additional
metadata for the image.
@ -2603,12 +2606,15 @@ class OpenStackCloud(object):
container_format = 'bare'
if not md5 or not sha256:
(md5, sha256) = self._get_file_hashes(filename)
current_image = self.get_image(name)
if (current_image and current_image.get(IMAGE_MD5_KEY, '') == md5
and current_image.get(IMAGE_SHA256_KEY, '') == sha256):
self.log.debug(
"image {name} exists and is up to date".format(name=name))
return current_image
if allow_duplicates:
current_image = None
else:
current_image = self.get_image(name)
if (current_image and current_image.get(IMAGE_MD5_KEY, '') == md5
and current_image.get(IMAGE_SHA256_KEY, '') == sha256):
self.log.debug(
"image {name} exists and is up to date".format(name=name))
return current_image
kwargs[IMAGE_MD5_KEY] = md5
kwargs[IMAGE_SHA256_KEY] = sha256
kwargs[IMAGE_OBJECT_KEY] = '/'.join([container, name])

View File

@ -69,3 +69,60 @@ class TestImage(base.BaseFunctionalTestCase):
self.addCleanup(os.remove, output)
self.assertTrue(filecmp.cmp(test_image.name, output),
"Downloaded contents don't match created image")
def test_create_image_skip_duplicate(self):
test_image = tempfile.NamedTemporaryFile(delete=False)
test_image.write('\0' * 1024 * 1024)
test_image.close()
image_name = self.getUniqueString('image')
try:
first_image = self.demo_cloud.create_image(
name=image_name,
filename=test_image.name,
disk_format='raw',
container_format='bare',
min_disk=10,
min_ram=1024,
wait=True)
second_image = self.demo_cloud.create_image(
name=image_name,
filename=test_image.name,
disk_format='raw',
container_format='bare',
min_disk=10,
min_ram=1024,
wait=True)
self.assertEqual(first_image.id, second_image.id)
finally:
self.demo_cloud.delete_image(image_name, wait=True)
def test_create_image_force_duplicate(self):
test_image = tempfile.NamedTemporaryFile(delete=False)
test_image.write('\0' * 1024 * 1024)
test_image.close()
image_name = self.getUniqueString('image')
second_image = None
try:
first_image = self.demo_cloud.create_image(
name=image_name,
filename=test_image.name,
disk_format='raw',
container_format='bare',
min_disk=10,
min_ram=1024,
wait=True)
second_image = self.demo_cloud.create_image(
name=image_name,
filename=test_image.name,
disk_format='raw',
container_format='bare',
min_disk=10,
min_ram=1024,
allow_duplicates=True,
wait=True)
self.assertNotEqual(first_image.id, second_image.id)
finally:
if first_image:
self.demo_cloud.delete_image(first_image.id, wait=True)
if second_image:
self.demo_cloud.delete_image(second_image.id, wait=True)