Skip to content

Commit

Permalink
Merge pull request #14 from Pansanel/cleanup
Browse files Browse the repository at this point in the history
New cleanup feature to support CEPH storage backend
  • Loading branch information
Pansanel authored Feb 15, 2018
2 parents c46b6e0 + fc5112d commit a96570f
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 13 deletions.
1 change: 1 addition & 0 deletions cloudkeeper_os/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@
APPLIANCE_INT_VALUES = ['ram', 'core', 'expiration_date']
IMAGE_ID_TAG = 'APPLIANCE_ID'
IMAGE_LIST_ID_TAG = 'APPLIANCE_IMAGE_LIST_ID'
IMAGE_STATUS_TAG = 'APPLIANCE_STATUS'
57 changes: 46 additions & 11 deletions cloudkeeper_os/imagemanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
IMAGE_ID_TAG = constants.IMAGE_ID_TAG
IMAGE_LIST_ID_TAG = constants.IMAGE_LIST_ID_TAG
APPLIANCE_INT_VALUES = constants.APPLIANCE_INT_VALUES
IMAGE_STATUS_TAG = constants.IMAGE_STATUS_TAG


class ApplianceManager(object):
Expand Down Expand Up @@ -88,6 +89,8 @@ def add_appliance(self, appliance):
properties = utils.extract_appliance_properties(appliance)
min_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),
Expand Down Expand Up @@ -115,17 +118,17 @@ def update_appliance(self, appliance):
"""Update an appliance stored in glance
"""
LOG.info("Updating image: '%s'" % appliance.identifier)
LOG.debug("Deleting old release of the appliance")
old_image_id = self.remove_appliance(appliance)
LOG.debug("The glance image '%s' has been deleted" % old_image_id)
LOG.debug("Marking appliance for removal")
old_image_id = self.mark_appliance_for_removal(appliance)
LOG.debug("The glance image '%s' has been marked" % old_image_id)
LOG.debug("Creating new release of the appliance")
image_id = self.add_appliance(appliance)
LOG.debug("The glance image '%s' has been created" % image_id)
return image_id


def remove_appliance(self, appliance):
"""Remove an appliance in glance
def mark_appliance_for_removal(self, appliance):
"""Mark an appliance in glance for removal
"""
project_name = self.mapping.get_project_from_vo(appliance.vo)
if not project_name:
Expand All @@ -142,13 +145,44 @@ def remove_appliance(self, appliance):
glance_image = utils.find_image(glance, appliance.identifier,
appliance.image_list_identifier)
if not glance_image:
LOG.info("Cannot delete image: image not found")
LOG.info("Cannot mark image for removal: image not found")
return None

LOG.info("Deleting image: '%s'" % glance_image.id)
glance.images.delete(glance_image.id)
LOG.info("Marking image for removal: '%s'" % glance_image.id)
properties = {}
properties[IMAGE_STATUS_TAG] = 'EOL'
glance.images.update(glance_image.id, visibility='private', **properties)

return glance_image.id

def cleanup_appliances(self):
"""Try to remove all appliances marked for removal
"""
for project_name in self.mapping.get_projects():
glance = openstack_client.get_glance_client(project_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("Trying to delete image '%s'" % image['id'])
glance.images.delete(image['id'])
LOG.debug("Succesfully deleted image '%s'" % image['id'])
except Exception as err:
LOG.debug("Cannot cleanup image '%s'" % image['id'])
LOG.debug(err)

class ImageListManager(object):
"""A class for managing image lists
Expand Down Expand Up @@ -181,9 +215,10 @@ def update_image_list_identifiers(self):

for image in image_list:
if IMAGE_LIST_ID_TAG in image:
if image[IMAGE_LIST_ID_TAG] not in appliances:
appliances[image[IMAGE_LIST_ID_TAG]] = []
appliances[image[IMAGE_LIST_ID_TAG]].append(image)
if IMAGE_STATUS_TAG in image and image[IMAGE_STATUS_TAG] != 'EOL':
if image[IMAGE_LIST_ID_TAG] not in appliances:
appliances[image[IMAGE_LIST_ID_TAG]] = []
appliances[image[IMAGE_LIST_ID_TAG]].append(image)

self.appliances = appliances

Expand Down
9 changes: 7 additions & 2 deletions cloudkeeper_os/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ def PreAction(self, request, context):
return cloudkeeper_pb2.Empty()

def PostAction(self, request, context):
"""Cleanup of images marked for removal
"""
LOG.info("Cleaning up appliances marked for removal")
manager = imagemanager.ApplianceManager()
manager.cleanup_appliances()
metadata = (
('status', 'SUCCESS'),
)
Expand Down Expand Up @@ -98,9 +103,9 @@ def RemoveAppliance(self, request, context):
metadata = (
('status', 'SUCCESS'),
)
LOG.info("Removing appliance: %s" % request.identifier)
LOG.info("Marking appliances for removal: %s" % request.identifier)
manager = imagemanager.ApplianceManager()
if not manager.remove_appliance(request):
if not manager.mark_appliance_for_removal(request):
metadata = (
('status', 'ERROR'),
)
Expand Down

0 comments on commit a96570f

Please sign in to comment.