summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhi Yan Liu <zhiyanl@cn.ibm.com>2014-09-12 20:02:27 +0800
committerNikhil Komawar <nikhilskomawar@gmail.com>2014-10-09 09:49:20 -0400
commitfdcc5c4519bd71b9912ad6c0c7562ef51e774523 (patch)
tree27e45c1b95630cbae9ab0f89d4c1a413bc5019e3
parent9eff67b8fff812acdbf787f2dc119761f3cf3153 (diff)
downloadglance-fdcc5c4519bd71b9912ad6c0c7562ef51e774523.tar.gz
Remove stale chunks when failed to update image to registry
For image v1 api, the operation of uploading image bits to store and the operation of updating image metadata are separaed, so when the second operation failed, the image stale chunks will be leaked in store. This change added a logic to remove those chunks if an exception happenned during the step of image metadata updating. And if glance-registry could be reached still, the image status will be changed to 'killed', this followed standard glance image status transition. Closes-bug: 1254497 Change-Id: I01e13066b48a8feb1ead0de64992e7997feafdea Signed-off-by: Zhi Yan Liu <zhiyanl@cn.ibm.com>
-rw-r--r--glance/api/v1/images.py31
1 files changed, 27 insertions, 4 deletions
diff --git a/glance/api/v1/images.py b/glance/api/v1/images.py
index 7ec3bfc59..b5070ee9d 100644
--- a/glance/api/v1/images.py
+++ b/glance/api/v1/images.py
@@ -52,6 +52,7 @@ import glance.registry.client.v1.api as registry
LOG = logging.getLogger(__name__)
_LI = gettextutils._LI
+_LW = gettextutils._LW
SUPPORTED_PARAMS = glance.api.v1.SUPPORTED_PARAMS
SUPPORTED_FILTERS = glance.api.v1.SUPPORTED_FILTERS
ACTIVE_IMMUTABLE = glance.api.v1.ACTIVE_IMMUTABLE
@@ -685,10 +686,32 @@ class Controller(controller.BaseController):
:retval Mapping of updated image data
"""
location_data = self._upload(req, image_meta)
- return self._activate(req,
- image_meta['id'],
- location_data,
- from_state='saving') if location_data else None
+ image_id = image_meta['id']
+ LOG.info(_LI("Uploaded data of image %s from request "
+ "payload successfully.") % image_id)
+
+ if location_data:
+ try:
+ image_meta = self._activate(req,
+ image_id,
+ location_data,
+ from_state='saving')
+ except Exception as e:
+ with excutils.save_and_reraise_exception():
+ if not isinstance(e, exception.Duplicate):
+ # NOTE(zhiyan): Delete image data since it has already
+ # been added to store by above _upload() call.
+ LOG.warn(_LW("Failed to activate image %s in "
+ "registry. About to delete image "
+ "bits from store and update status "
+ "to 'killed'.") % image_id)
+ upload_utils.initiate_deletion(req, location_data,
+ image_id)
+ upload_utils.safe_kill(req, image_id, 'saving')
+ else:
+ image_meta = None
+
+ return image_meta
def _get_size(self, context, image_meta, location):
# retrieve the image size from remote store (if not provided)