X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=snaps%2Fopenstack%2Futils%2Fglance_utils.py;h=a127ad38005ddbf8312edc125bea7c3170b0d378;hb=d5d282dd1ffab96e85332bea580689c3297a25f8;hp=d859257d0c73ed44fea8f72b7c89c8f9535a9ff3;hpb=becbbabc63b0eff15ed6979947aeb75ddf6819c9;p=snaps.git diff --git a/snaps/openstack/utils/glance_utils.py b/snaps/openstack/utils/glance_utils.py index d859257..a127ad3 100644 --- a/snaps/openstack/utils/glance_utils.py +++ b/snaps/openstack/utils/glance_utils.py @@ -39,27 +39,52 @@ def glance_client(os_creds): Creates and returns a glance client object :return: the glance client """ - return Client(version=os_creds.image_api_version, session=keystone_utils.keystone_session(os_creds)) + return Client(version=os_creds.image_api_version, + session=keystone_utils.keystone_session(os_creds), + region_name=os_creds.region_name) -def get_image(glance, image_name=None): +def get_image(glance, image_name=None, image_settings=None): """ Returns an OpenStack image object for a given name :param glance: the Glance client :param image_name: the image name to lookup + :param image_settings: the image settings used for lookups :return: the image object or None """ - images = glance.images.list() + img_filter = dict() + if image_settings: + if image_settings.exists: + img_filter = {'name': image_settings.name} + else: + img_filter = {'name': image_settings.name, + 'disk_format': image_settings.format} + elif image_name: + img_filter = {'name': image_name} + + images = glance.images.list(**{'filters': img_filter}) for image in images: if glance.version == VERSION_1: - if image.name == image_name: - image = glance.images.get(image.id) - return Image(name=image.name, image_id=image.id, size=image.size, properties=image.properties) + image = glance.images.get(image.id) + return Image(name=image.name, image_id=image.id, + size=image.size, properties=image.properties) elif glance.version == VERSION_2: - if image['name'] == image_name: - return Image(name=image['name'], image_id=image['id'], size=image['size'], - properties=image.get('properties')) - return None + return Image( + name=image['name'], image_id=image['id'], + size=image['size'], properties=image.get('properties')) + + +def get_image_by_id(glance, image_id): + """ + Returns an OpenStack image object for a given name + :param glance: the Glance client + :param image_id: the image ID to lookup + :return: the SNAPS-OO Domain Image object or None + """ + image = glance.images.get(image_id) + return Image( + name=image['name'], image_id=image['id'], + size=image['size'], properties=image.get('properties')) def get_image_status(glance, image): @@ -76,7 +101,7 @@ def get_image_status(glance, image): os_image = glance.images.get(image.id) return os_image['status'] else: - raise Exception('Unsupported glance client version') + raise GlanceException('Unsupported glance client version') def create_image(glance, image_settings): @@ -92,7 +117,7 @@ def create_image(glance, image_settings): elif glance.version == VERSION_2: return __create_image_v2(glance, image_settings) else: - raise Exception('Unsupported glance client version') + raise GlanceException('Unsupported glance client version') def __create_image_v1(glance, image_settings): @@ -101,30 +126,36 @@ def __create_image_v1(glance, image_settings): :param glance: the glance client :param image_settings: the image settings object :return: the OpenStack image object - :raise Exception if using a file and it cannot be found + :raise exceptions from the Glance client or IOError when opening a file """ - created_image = None + kwargs = { + 'name': image_settings.name, 'disk_format': image_settings.format, + 'container_format': 'bare', 'is_public': image_settings.public} - if image_settings.url: - if image_settings.extra_properties: - created_image = glance.images.create( - name=image_settings.name, disk_format=image_settings.format, container_format="bare", - location=image_settings.url, properties=image_settings.extra_properties) - else: - created_image = glance.images.create(name=image_settings.name, disk_format=image_settings.format, - container_format="bare", location=image_settings.url) - elif image_settings.image_file: - image_file = file_utils.get_file(image_settings.image_file) + image_file = None + + try: if image_settings.extra_properties: - created_image = glance.images.create( - name=image_settings.name, disk_format=image_settings.format, container_format="bare", data=image_file, - properties=image_settings.extra_properties) + kwargs['properties'] = image_settings.extra_properties + + if image_settings.url: + kwargs['location'] = image_settings.url + elif image_settings.image_file: + image_file = open(image_settings.image_file, 'rb') + kwargs['data'] = image_file else: - created_image = glance.images.create( - name=image_settings.name, disk_format=image_settings.format, container_format="bare", data=image_file) + logger.warn( + 'Unable to create image with name - %s. No file or URL', + image_settings.name) + return None - return Image(name=image_settings.name, image_id=created_image.id, size=created_image.size, - properties=created_image.properties) + created_image = glance.images.create(**kwargs) + return Image(name=image_settings.name, image_id=created_image.id, + size=created_image.size, + properties=created_image.properties) + finally: + if image_file: + image_file.close() def __create_image_v2(glance, image_settings): @@ -133,44 +164,59 @@ def __create_image_v2(glance, image_settings): :param glance: the glance client v2 :param image_settings: the image settings object :return: the OpenStack image object - :raise Exception if using a file and it cannot be found + :raise GlanceException or IOException or URLError """ - cleanup_file = False - if image_settings.image_file: + cleanup_temp_file = False + image_file = None + if image_settings.image_file is not None: image_filename = image_settings.image_file elif image_settings.url: - image_file = file_utils.download(image_settings.url, '/tmp', str(uuid.uuid4())) - image_filename = image_file.name - cleanup_file = True + file_name = str(uuid.uuid4()) + try: + image_file = file_utils.download( + image_settings.url, './tmp', file_name) + image_filename = image_file.name + except: + if image_file: + os.remove(image_file.name) + raise + + cleanup_temp_file = True else: - raise Exception('Filename or URL of image not configured') + raise GlanceException('Filename or URL of image not configured') - created_image = None + os_image = None try: kwargs = dict() kwargs['name'] = image_settings.name kwargs['disk_format'] = image_settings.format kwargs['container_format'] = 'bare' + if image_settings.public: + kwargs['visibility'] = 'public' + if image_settings.extra_properties: - for key, value in image_settings.extra_properties.iteritems(): - kwargs[key] = value + kwargs.update(image_settings.extra_properties) - created_image = glance.images.create(**kwargs) - image_file = file_utils.get_file(image_filename) - glance.images.upload(created_image['id'], image_file) - except Exception as e: + os_image = glance.images.create(**kwargs) + image_file = open(os.path.expanduser(image_filename), 'rb') + glance.images.upload(os_image['id'], image_file) + except: logger.error('Unexpected exception creating image. Rolling back') - if created_image: - delete_image(glance, created_image) - raise e + if os_image: + delete_image(glance, Image( + name=os_image['name'], image_id=os_image['id'], + size=os_image['size'], properties=os_image.get('properties'))) + raise finally: - if cleanup_file: + if image_file: + logger.debug('Closing file %s', image_file.name) + image_file.close() + if cleanup_temp_file: + logger.info('Removing file %s', image_file.name) os.remove(image_filename) - updated_image = glance.images.get(created_image['id']) - return Image(name=updated_image['name'], image_id=updated_image['id'], size=updated_image['size'], - properties=updated_image.get('properties')) + return get_image_by_id(glance, os_image['id']) def delete_image(glance, image): @@ -179,9 +225,11 @@ def delete_image(glance, image): :param glance: the glance client :param image: the image to delete """ - if glance.version == VERSION_1: - glance.images.delete(image) - elif glance.version == VERSION_2: - glance.images.delete(image.id) - else: - raise Exception('Unsupported glance client version') + logger.info('Deleting image named - %s', image.name) + glance.images.delete(image.id) + + +class GlanceException(Exception): + """ + Exception when calls to the Glance client cannot be served properly + """