X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=snaps%2Fopenstack%2Futils%2Fglance_utils.py;h=ca9c4908c5adcd8a23870c4a44bc9a98d1878f4d;hb=bd5f0b53df5b76e2e5fa0ee73a81478f43e28b7a;hp=6d90d3e9a04b890eefba3938865ae3e7effd0d79;hpb=1a0967b4e23c2d985b8c02dc9f23bd6c3afa86a3;p=snaps.git diff --git a/snaps/openstack/utils/glance_utils.py b/snaps/openstack/utils/glance_utils.py index 6d90d3e..ca9c490 100644 --- a/snaps/openstack/utils/glance_utils.py +++ b/snaps/openstack/utils/glance_utils.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016 Cable Television Laboratories, Inc. ("CableLabs") +# Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs") # and others. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,15 +13,22 @@ # See the License for the specific language governing permissions and # limitations under the License. import logging +import os +import uuid from snaps import file_utils from glanceclient.client import Client + +from snaps.domain.image import Image from snaps.openstack.utils import keystone_utils __author__ = 'spisarski' logger = logging.getLogger('glance_utils') +VERSION_1 = 1.0 +VERSION_2 = 2.0 + """ Utilities for basic neutron API calls """ @@ -35,23 +42,43 @@ def glance_client(os_creds): return Client(version=os_creds.image_api_version, session=keystone_utils.keystone_session(os_creds)) -def get_image(nova, glance, image_name): +def get_image(glance, image_name=None): """ Returns an OpenStack image object for a given name - :param nova: the Nova client :param glance: the Glance client :param image_name: the image name to lookup :return: the image object or None """ - try: - image_dict = nova.images.find(name=image_name) - if image_dict: - return glance.images.get(image_dict.id) - except: - pass + images = glance.images.list() + 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) + 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 +def get_image_status(glance, image): + """ + Returns a new OpenStack Image object for a given OpenStack image object + :param glance: the Glance client + :param image: the domain Image object + :return: the OpenStack Image object + """ + if glance.version == VERSION_1: + os_image = glance.images.get(image.id) + return os_image.status + elif glance.version == VERSION_2: + os_image = glance.images.get(image.id) + return os_image['status'] + else: + raise Exception('Unsupported glance client version') + + def create_image(glance, image_settings): """ Creates and returns OpenStack image object with an external URL @@ -60,13 +87,88 @@ def create_image(glance, image_settings): :return: the OpenStack image object :raise Exception if using a file and it cannot be found """ + if glance.version == VERSION_1: + return __create_image_v1(glance, image_settings) + elif glance.version == VERSION_2: + return __create_image_v2(glance, image_settings) + else: + raise Exception('Unsupported glance client version') + + +def __create_image_v1(glance, image_settings): + """ + Creates and returns OpenStack image object with an external URL + :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 + """ + created_image = None + if image_settings.url: - return glance.images.create(name=image_settings.name, disk_format=image_settings.format, - container_format="bare", location=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) - return glance.images.create(name=image_settings.name, disk_format=image_settings.format, - container_format="bare", data=image_file) + 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) + else: + created_image = glance.images.create( + name=image_settings.name, disk_format=image_settings.format, container_format="bare", data=image_file) + + return Image(name=image_settings.name, image_id=created_image.id, size=created_image.size, + properties=created_image.properties) + + +def __create_image_v2(glance, image_settings): + """ + Creates and returns OpenStack image object with an external URL + :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 + """ + cleanup_file = False + if image_settings.image_file: + 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 + else: + raise Exception('Filename or URL of image not configured') + + created_image = None + try: + kwargs = dict() + kwargs['name'] = image_settings.name + kwargs['disk_format'] = image_settings.format + kwargs['container_format'] = 'bare' + if image_settings.extra_properties: + 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: + logger.error('Unexpected exception creating image. Rolling back') + if created_image: + delete_image(glance, created_image) + raise e + finally: + if cleanup_file: + 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')) def delete_image(glance, image): @@ -75,4 +177,9 @@ def delete_image(glance, image): :param glance: the glance client :param image: the image to delete """ - glance.images.delete(image) + 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')