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:
parent
1a1107ad73
commit
3ef3864785
@ -2546,7 +2546,8 @@ class OpenStackCloud(object):
|
|||||||
md5=None, sha256=None,
|
md5=None, sha256=None,
|
||||||
disk_format=None, container_format=None,
|
disk_format=None, container_format=None,
|
||||||
disable_vendor_agent=True,
|
disable_vendor_agent=True,
|
||||||
wait=False, timeout=3600, **kwargs):
|
wait=False, timeout=3600,
|
||||||
|
allow_duplicates=False, **kwargs):
|
||||||
"""Upload an image to Glance.
|
"""Upload an image to Glance.
|
||||||
|
|
||||||
:param str name: Name of the image to create. If it is a pathname
|
: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
|
true - however, be aware that one of the upload
|
||||||
methods is always synchronous.
|
methods is always synchronous.
|
||||||
:param timeout: Seconds to wait for image creation. None is forever.
|
: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
|
Additional kwargs will be passed to the image creation as additional
|
||||||
metadata for the image.
|
metadata for the image.
|
||||||
@ -2603,12 +2606,15 @@ class OpenStackCloud(object):
|
|||||||
container_format = 'bare'
|
container_format = 'bare'
|
||||||
if not md5 or not sha256:
|
if not md5 or not sha256:
|
||||||
(md5, sha256) = self._get_file_hashes(filename)
|
(md5, sha256) = self._get_file_hashes(filename)
|
||||||
current_image = self.get_image(name)
|
if allow_duplicates:
|
||||||
if (current_image and current_image.get(IMAGE_MD5_KEY, '') == md5
|
current_image = None
|
||||||
and current_image.get(IMAGE_SHA256_KEY, '') == sha256):
|
else:
|
||||||
self.log.debug(
|
current_image = self.get_image(name)
|
||||||
"image {name} exists and is up to date".format(name=name))
|
if (current_image and current_image.get(IMAGE_MD5_KEY, '') == md5
|
||||||
return current_image
|
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_MD5_KEY] = md5
|
||||||
kwargs[IMAGE_SHA256_KEY] = sha256
|
kwargs[IMAGE_SHA256_KEY] = sha256
|
||||||
kwargs[IMAGE_OBJECT_KEY] = '/'.join([container, name])
|
kwargs[IMAGE_OBJECT_KEY] = '/'.join([container, name])
|
||||||
|
@ -69,3 +69,60 @@ class TestImage(base.BaseFunctionalTestCase):
|
|||||||
self.addCleanup(os.remove, output)
|
self.addCleanup(os.remove, output)
|
||||||
self.assertTrue(filecmp.cmp(test_image.name, output),
|
self.assertTrue(filecmp.cmp(test_image.name, output),
|
||||||
"Downloaded contents don't match created image")
|
"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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user