def remove_image_list(self, image_list_identifier): """Remove all images linked to an image_list_identifier.""" self.update_image_list_identifiers() if image_list_identifier not in self.appliances: # raise NotIdentifierFound exception LOG.error("No image with the image_list_identifier:" "%s" % image_list_identifier) return None vo_name = self.appliances[image_list_identifier][0]['APPLIANCE_VO'] project_name = self.mapping.get_project_from_vo(vo_name) if not project_name: LOG.error("Cannot get the project name mapped the " "VO '%s'" % vo_name) return None domain_name = self.mapping.get_domain_from_project(project_name) glance = openstack_client.get_glance_client(project_name, domain_name) if not glance: LOG.error("Cannot get a glance client for the " "project '%s'" % project_name) return None LOG.debug("Deleting all images with the Image List Identifier: " "'%s'" % image_list_identifier) for image in self.appliances[image_list_identifier]: LOG.info("Deleting image '%s'" % image['id']) glance.images.delete(image['id']) self.appliances.pop(image_list_identifier) return image_list_identifier
def update_image_list_identifiers(self): """Update the identifier list.""" appliances = {} for project_name in self.mapping.get_projects(): LOG.debug("Retrieving image list identifiers for " "project %s" % (project_name)) domain_name = self.mapping.get_domain_from_project(project_name) glance = openstack_client.get_glance_client( project_name, domain_name) if not glance: LOG.error("Not authorized to manage images from the " "project: %s" % project_name) continue try: img_generator = glance.images.list() image_list = list(img_generator) except Exception as err: LOG.error("Not authorized to retrieve the image list from " "the project: %s" % project_name) LOG.exception(err) continue for image in image_list: if IMAGE_LIST_ID_TAG in image: if ((IMAGE_STATUS_TAG not in image) or (image[IMAGE_STATUS_TAG] != 'EOL')): if image[IMAGE_LIST_ID_TAG] not in appliances: appliances[image[IMAGE_LIST_ID_TAG]] = [] LOG.debug( "Appending image with id %s to image list with " "id %s" % (image[IMAGE_ID_TAG], image[IMAGE_LIST_ID_TAG])) appliances[image[IMAGE_LIST_ID_TAG]].append(image) self.appliances = appliances
def cleanup_appliances(self): """Try to remove all appliances marked for removal.""" LOG.info("Cleaning up appliances") for project_name in self.mapping.get_projects(): domain_name = self.mapping.get_domain_from_project(project_name) glance = openstack_client.get_glance_client( project_name, domain_name) if not glance: LOG.error("Not authorized to manage images from the " "project: %s" % project_name) continue try: img_generator = glance.images.list() image_list = list(img_generator) except Exception as err: LOG.error("Not authorized to retrieve the image list from " "the project: %s" % project_name) LOG.exception(err) continue for image in image_list: if IMAGE_LIST_ID_TAG in image: if (IMAGE_STATUS_TAG in image and image[IMAGE_STATUS_TAG] == 'EOL'): try: LOG.debug("Deleting image '%s'" % image['id']) glance.images.delete(image['id']) LOG.debug("Image '%s' successfully " "deleted" % image['id']) except Exception as err: LOG.error("Cannot delete image '%s'" % image['id']) LOG.error(err)
def mark_appliance_for_removal(self, appliance): """Mark an appliance in glance for removal.""" marked_images = [] LOG.info("Marking appliance '%s' for removal" % appliance.identifier) project_name = self.mapping.get_project_from_vo(appliance.vo) if not project_name: LOG.error("Cannot get a project name mapped to the " "VO '%s'" % appliance.vo) return None domain_name = self.mapping.get_domain_from_project(project_name) glance = openstack_client.get_glance_client(project_name, domain_name) if not glance: LOG.error("Cannot get a glance client for the " "project '%s'" % project_name) return None glance_images = utils.find_images(glance, appliance.identifier, appliance.image_list_identifier) if not glance_images: LOG.error("Cannot mark image for removal: image not found") return None properties = {} properties[IMAGE_STATUS_TAG] = 'EOL' for image in glance_images: LOG.debug("Marking image for removal: '%s'" % image.id) marked_images.append(image.id) glance.images.update(image.id, visibility='private', **properties) return marked_images
def mark_appliance_as_active(self, appliance, image_id): """Mark an appliance in glance as active.""" LOG.info("Marking image '%s' as active" % image_id) project_name = self.mapping.get_project_from_vo(appliance.vo) if not project_name: LOG.error("Cannot get a project name mapped to the " "VO '%s'" % appliance.vo) return None domain_name = self.mapping.get_domain_from_project(project_name) glance = openstack_client.get_glance_client(project_name, domain_name) if not glance: LOG.error("Cannot get a glance client for the " "project '%s'" % project_name) return None glance_image = utils.find_image(glance, image_id) if not glance_image: LOG.error("Cannot mark image as active: image not found") return None properties = {} properties[IMAGE_STATUS_TAG] = 'ACTIVE' LOG.debug("Marking image as active: '%s'" % glance_image.id) glance.images.update(glance_image.id, visibility='private', **properties) return True
def add_appliance(self, appliance): """Add an appliance to glance.""" project_name = self.mapping.get_project_from_vo(appliance.vo) if not project_name: LOG.error("Cannot get a project name mapped to the " "vo '%s'" % appliance.vo) return None domain_name = self.mapping.get_domain_from_project(project_name) glance = openstack_client.get_glance_client(project_name, domain_name) if not glance: LOG.error("Cannot get a glance client for the " "project '%s'" % project_name) return None LOG.info('Adding appliance: ' + appliance.title) LOG.debug("Image access mode: " "%s" % appliance.image.Mode.Name(appliance.image.mode)) if appliance.image.Mode.Name(appliance.image.mode) == 'REMOTE': remote_image = True filename = utils.retrieve_image(appliance) if not filename: LOG.error("The appliance '%s' could not be retrieved from " "Cloudkeeper" % appliance.identifier) return None else: filename = appliance.image.location remote_image = False if not filename: LOG.error("The image filename has not set been set " "in the appliance '%s'." % appliance.identifier) return None image_format = appliance.image.Format.Name(appliance.image.format) try: image_data = open(filename, 'rb') except IOError as err: LOG.error("Cannot open image file: '%s'" % filename) LOG.exception(err) return None appliance.ClearField('image') properties = utils.extract_appliance_properties(appliance) min_ram = utils.convert_ram(int(properties.get("APPLIANCE_RAM", "0"))) properties[IMAGE_STATUS_TAG] = 'ACTIVE' LOG.debug("Creating image '%s' (format: '%s', " "properties %s)" % (appliance.title, str.lower(image_format), properties)) glance_image = glance.images.create( name=appliance.title, disk_format=str.lower(image_format), container_format="bare", visibility=CONF.image_visibility, min_ram=min_ram) glance.images.upload(glance_image.id, image_data) glance.images.update(glance_image.id, **properties) image_data.close() if remote_image: LOG.debug("Deleting retrieved image: '%s'" % (filename)) os.unlink(filename) return glance_image.id