diff options
author | Zhi Yan Liu <zhiyanl@cn.ibm.com> | 2014-09-12 20:02:27 +0800 |
---|---|---|
committer | Nikhil Komawar <nikhilskomawar@gmail.com> | 2014-10-09 09:49:20 -0400 |
commit | fdcc5c4519bd71b9912ad6c0c7562ef51e774523 (patch) | |
tree | 27e45c1b95630cbae9ab0f89d4c1a413bc5019e3 | |
parent | 9eff67b8fff812acdbf787f2dc119761f3cf3153 (diff) | |
download | glance-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.py | 31 |
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) |