)]}'
{"glance/api/v2/images.py":[{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"efec00d676a72e3656bb44be134210613eaf00ad","unresolved":false,"context_lines":[{"line_number":364,"context_line":""},{"line_number":365,"context_line":"    @utils.mutating"},{"line_number":366,"context_line":"    def delete_from_store(self, req, store_id, image_id):"},{"line_number":367,"context_line":"        image_repo \u003d self.gateway.get_repo(req.context)"},{"line_number":368,"context_line":"        try:"},{"line_number":369,"context_line":"            image \u003d image_repo.get(image_id)"},{"line_number":370,"context_line":"        except exception.NotAuthenticated as e:"}],"source_content_type":"text/x-python","patch_set":1,"id":"3fa7e38b_00baa209","line":367,"updated":"2019-12-12 05:17:55.000000000","message":"We should check if multiple backends is enabled or not first and if it is not enabled then we should reject the request.","commit_id":"0718ef4baa09b47a92c07fb62e128a7a1f3ccae1"},{"author":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"change_message_id":"d2650f89ea3bb4a66890bf159cf619ea1627d140","unresolved":false,"context_lines":[{"line_number":364,"context_line":""},{"line_number":365,"context_line":"    @utils.mutating"},{"line_number":366,"context_line":"    def delete_from_store(self, req, store_id, image_id):"},{"line_number":367,"context_line":"        image_repo \u003d self.gateway.get_repo(req.context)"},{"line_number":368,"context_line":"        try:"},{"line_number":369,"context_line":"            image \u003d image_repo.get(image_id)"},{"line_number":370,"context_line":"        except exception.NotAuthenticated as e:"}],"source_content_type":"text/x-python","patch_set":1,"id":"3fa7e38b_afa299f9","line":367,"in_reply_to":"3fa7e38b_00baa209","updated":"2019-12-12 12:22:50.000000000","message":"Yes, what should we return or should we expose the endpoint at all (returning 404 Not Found) when that\u0027s the case?","commit_id":"0718ef4baa09b47a92c07fb62e128a7a1f3ccae1"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"988339148c5efb3937d655c099aa340d3d90ad65","unresolved":false,"context_lines":[{"line_number":364,"context_line":""},{"line_number":365,"context_line":"    @utils.mutating"},{"line_number":366,"context_line":"    def delete_from_store(self, req, store_id, image_id):"},{"line_number":367,"context_line":"        image_repo \u003d self.gateway.get_repo(req.context)"},{"line_number":368,"context_line":"        try:"},{"line_number":369,"context_line":"            image \u003d image_repo.get(image_id)"},{"line_number":370,"context_line":"        except exception.NotAuthenticated as e:"}],"source_content_type":"text/x-python","patch_set":1,"id":"3fa7e38b_da2c714b","line":367,"in_reply_to":"3fa7e38b_afa299f9","updated":"2019-12-12 13:42:11.000000000","message":"Not exposing the endpoint sounds a good idea.","commit_id":"0718ef4baa09b47a92c07fb62e128a7a1f3ccae1"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"369d8b8af26a38d41730f4681c9a9a2e2fd7ed82","unresolved":false,"context_lines":[{"line_number":639,"context_line":"                    \"invisible.\")"},{"line_number":640,"context_line":"            raise webob.exc.HTTPForbidden(explanation\u003dmsg)"},{"line_number":641,"context_line":""},{"line_number":642,"context_line":"        if image.status not in (\u0027active\u0027):"},{"line_number":643,"context_line":"            msg \u003d _(\"It\u0027s not allowed to remove locations if image status is \""},{"line_number":644,"context_line":"                    \"%s.\") % image.status"},{"line_number":645,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":646,"context_line":""},{"line_number":647,"context_line":"        if len(image.locations) \u003d\u003d 1:"},{"line_number":648,"context_line":"            LOG.debug(\"User forbidden to remove last location of image %s\","},{"line_number":649,"context_line":"                      image.image_id)"},{"line_number":650,"context_line":"            msg \u003d _(\"Cannot remove last location in the image.\")"},{"line_number":651,"context_line":"            raise exception.Forbidden(msg)"},{"line_number":652,"context_line":"        pos \u003d self._get_locations_op_pos(path_pos,"},{"line_number":653,"context_line":"                                         len(image.locations), False)"},{"line_number":654,"context_line":"        if pos is None:"},{"line_number":655,"context_line":"            msg \u003d _(\"Invalid position for removing a location.\")"},{"line_number":656,"context_line":"            raise webob.exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":657,"context_line":"        try:"},{"line_number":658,"context_line":"            # NOTE(zhiyan): this actually deletes the location"},{"line_number":659,"context_line":"            # from the backend store."},{"line_number":660,"context_line":"            image.locations.pop(pos)"},{"line_number":661,"context_line":"        # TODO(jokke): Fix this, we should catch what store throws and"},{"line_number":662,"context_line":"        # provide definitely something else than IternalServerError to user."},{"line_number":663,"context_line":"        except Exception as e:"}],"source_content_type":"text/x-python","patch_set":1,"id":"3fa7e38b_2858f8f6","line":660,"range":{"start_line":642,"start_character":8,"end_line":660,"end_character":36},"updated":"2019-12-11 08:30:26.000000000","message":"can we move this code to common place and use it instead of duplicating the same?","commit_id":"0718ef4baa09b47a92c07fb62e128a7a1f3ccae1"},{"author":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"change_message_id":"93079399d70d4a063f183c5fa95c0ff89ba2e023","unresolved":false,"context_lines":[{"line_number":639,"context_line":"                    \"invisible.\")"},{"line_number":640,"context_line":"            raise webob.exc.HTTPForbidden(explanation\u003dmsg)"},{"line_number":641,"context_line":""},{"line_number":642,"context_line":"        if image.status not in (\u0027active\u0027):"},{"line_number":643,"context_line":"            msg \u003d _(\"It\u0027s not allowed to remove locations if image status is \""},{"line_number":644,"context_line":"                    \"%s.\") % image.status"},{"line_number":645,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":646,"context_line":""},{"line_number":647,"context_line":"        if len(image.locations) \u003d\u003d 1:"},{"line_number":648,"context_line":"            LOG.debug(\"User forbidden to remove last location of image %s\","},{"line_number":649,"context_line":"                      image.image_id)"},{"line_number":650,"context_line":"            msg \u003d _(\"Cannot remove last location in the image.\")"},{"line_number":651,"context_line":"            raise exception.Forbidden(msg)"},{"line_number":652,"context_line":"        pos \u003d self._get_locations_op_pos(path_pos,"},{"line_number":653,"context_line":"                                         len(image.locations), False)"},{"line_number":654,"context_line":"        if pos is None:"},{"line_number":655,"context_line":"            msg \u003d _(\"Invalid position for removing a location.\")"},{"line_number":656,"context_line":"            raise webob.exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":657,"context_line":"        try:"},{"line_number":658,"context_line":"            # NOTE(zhiyan): this actually deletes the location"},{"line_number":659,"context_line":"            # from the backend store."},{"line_number":660,"context_line":"            image.locations.pop(pos)"},{"line_number":661,"context_line":"        # TODO(jokke): Fix this, we should catch what store throws and"},{"line_number":662,"context_line":"        # provide definitely something else than IternalServerError to user."},{"line_number":663,"context_line":"        except Exception as e:"}],"source_content_type":"text/x-python","patch_set":1,"id":"3fa7e38b_983a90ca","line":660,"range":{"start_line":642,"start_character":8,"end_line":660,"end_character":36},"in_reply_to":"3fa7e38b_2858f8f6","updated":"2019-12-11 17:43:59.000000000","message":"I\u0027m not sure what are you looking for. You want to move \u0027image.locations.pop(pos)\u0027 as oneliner to it\u0027s own fuction and duplicate the local function call instead of duplicating this call as none of the other logic is the same?","commit_id":"0718ef4baa09b47a92c07fb62e128a7a1f3ccae1"},{"author":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"change_message_id":"d2650f89ea3bb4a66890bf159cf619ea1627d140","unresolved":false,"context_lines":[{"line_number":639,"context_line":"                    \"invisible.\")"},{"line_number":640,"context_line":"            raise webob.exc.HTTPForbidden(explanation\u003dmsg)"},{"line_number":641,"context_line":""},{"line_number":642,"context_line":"        if image.status not in (\u0027active\u0027):"},{"line_number":643,"context_line":"            msg \u003d _(\"It\u0027s not allowed to remove locations if image status is \""},{"line_number":644,"context_line":"                    \"%s.\") % image.status"},{"line_number":645,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":646,"context_line":""},{"line_number":647,"context_line":"        if len(image.locations) \u003d\u003d 1:"},{"line_number":648,"context_line":"            LOG.debug(\"User forbidden to remove last location of image %s\","},{"line_number":649,"context_line":"                      image.image_id)"},{"line_number":650,"context_line":"            msg \u003d _(\"Cannot remove last location in the image.\")"},{"line_number":651,"context_line":"            raise exception.Forbidden(msg)"},{"line_number":652,"context_line":"        pos \u003d self._get_locations_op_pos(path_pos,"},{"line_number":653,"context_line":"                                         len(image.locations), False)"},{"line_number":654,"context_line":"        if pos is None:"},{"line_number":655,"context_line":"            msg \u003d _(\"Invalid position for removing a location.\")"},{"line_number":656,"context_line":"            raise webob.exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":657,"context_line":"        try:"},{"line_number":658,"context_line":"            # NOTE(zhiyan): this actually deletes the location"},{"line_number":659,"context_line":"            # from the backend store."},{"line_number":660,"context_line":"            image.locations.pop(pos)"},{"line_number":661,"context_line":"        # TODO(jokke): Fix this, we should catch what store throws and"},{"line_number":662,"context_line":"        # provide definitely something else than IternalServerError to user."},{"line_number":663,"context_line":"        except Exception as e:"}],"source_content_type":"text/x-python","patch_set":1,"id":"3fa7e38b_74e0f4f8","line":660,"range":{"start_line":642,"start_character":8,"end_line":660,"end_character":36},"in_reply_to":"3fa7e38b_60bfd6fb","updated":"2019-12-12 12:22:50.000000000","message":"No sorry, gerrit hid most of the highlight and I missed that.\n\nThe benefit is much less than one would expect. If we moved L:642-651 under it\u0027s own function we would need to either move the exception raising out of there and deal with that in these two places anyways or place the function under try-catch-reraise to avoid logging traces when ever those happens","commit_id":"0718ef4baa09b47a92c07fb62e128a7a1f3ccae1"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"988339148c5efb3937d655c099aa340d3d90ad65","unresolved":false,"context_lines":[{"line_number":639,"context_line":"                    \"invisible.\")"},{"line_number":640,"context_line":"            raise webob.exc.HTTPForbidden(explanation\u003dmsg)"},{"line_number":641,"context_line":""},{"line_number":642,"context_line":"        if image.status not in (\u0027active\u0027):"},{"line_number":643,"context_line":"            msg \u003d _(\"It\u0027s not allowed to remove locations if image status is \""},{"line_number":644,"context_line":"                    \"%s.\") % image.status"},{"line_number":645,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":646,"context_line":""},{"line_number":647,"context_line":"        if len(image.locations) \u003d\u003d 1:"},{"line_number":648,"context_line":"            LOG.debug(\"User forbidden to remove last location of image %s\","},{"line_number":649,"context_line":"                      image.image_id)"},{"line_number":650,"context_line":"            msg \u003d _(\"Cannot remove last location in the image.\")"},{"line_number":651,"context_line":"            raise exception.Forbidden(msg)"},{"line_number":652,"context_line":"        pos \u003d self._get_locations_op_pos(path_pos,"},{"line_number":653,"context_line":"                                         len(image.locations), False)"},{"line_number":654,"context_line":"        if pos is None:"},{"line_number":655,"context_line":"            msg \u003d _(\"Invalid position for removing a location.\")"},{"line_number":656,"context_line":"            raise webob.exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":657,"context_line":"        try:"},{"line_number":658,"context_line":"            # NOTE(zhiyan): this actually deletes the location"},{"line_number":659,"context_line":"            # from the backend store."},{"line_number":660,"context_line":"            image.locations.pop(pos)"},{"line_number":661,"context_line":"        # TODO(jokke): Fix this, we should catch what store throws and"},{"line_number":662,"context_line":"        # provide definitely something else than IternalServerError to user."},{"line_number":663,"context_line":"        except Exception as e:"}],"source_content_type":"text/x-python","patch_set":1,"id":"3fa7e38b_7ae0ddf8","line":660,"range":{"start_line":642,"start_character":8,"end_line":660,"end_character":36},"in_reply_to":"3fa7e38b_74e0f4f8","updated":"2019-12-12 13:42:11.000000000","message":"Make sense.","commit_id":"0718ef4baa09b47a92c07fb62e128a7a1f3ccae1"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"efec00d676a72e3656bb44be134210613eaf00ad","unresolved":false,"context_lines":[{"line_number":639,"context_line":"                    \"invisible.\")"},{"line_number":640,"context_line":"            raise webob.exc.HTTPForbidden(explanation\u003dmsg)"},{"line_number":641,"context_line":""},{"line_number":642,"context_line":"        if image.status not in (\u0027active\u0027):"},{"line_number":643,"context_line":"            msg \u003d _(\"It\u0027s not allowed to remove locations if image status is \""},{"line_number":644,"context_line":"                    \"%s.\") % image.status"},{"line_number":645,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":646,"context_line":""},{"line_number":647,"context_line":"        if len(image.locations) \u003d\u003d 1:"},{"line_number":648,"context_line":"            LOG.debug(\"User forbidden to remove last location of image %s\","},{"line_number":649,"context_line":"                      image.image_id)"},{"line_number":650,"context_line":"            msg \u003d _(\"Cannot remove last location in the image.\")"},{"line_number":651,"context_line":"            raise exception.Forbidden(msg)"},{"line_number":652,"context_line":"        pos \u003d self._get_locations_op_pos(path_pos,"},{"line_number":653,"context_line":"                                         len(image.locations), False)"},{"line_number":654,"context_line":"        if pos is None:"},{"line_number":655,"context_line":"            msg \u003d _(\"Invalid position for removing a location.\")"},{"line_number":656,"context_line":"            raise webob.exc.HTTPBadRequest(explanation\u003dmsg)"},{"line_number":657,"context_line":"        try:"},{"line_number":658,"context_line":"            # NOTE(zhiyan): this actually deletes the location"},{"line_number":659,"context_line":"            # from the backend store."},{"line_number":660,"context_line":"            image.locations.pop(pos)"},{"line_number":661,"context_line":"        # TODO(jokke): Fix this, we should catch what store throws and"},{"line_number":662,"context_line":"        # provide definitely something else than IternalServerError to user."},{"line_number":663,"context_line":"        except Exception as e:"}],"source_content_type":"text/x-python","patch_set":1,"id":"3fa7e38b_60bfd6fb","line":660,"range":{"start_line":642,"start_character":8,"end_line":660,"end_character":36},"in_reply_to":"3fa7e38b_983a90ca","updated":"2019-12-12 05:17:55.000000000","message":"Sorry for confusion,\n\nI was saying we can create one private method something like _image_location_validation and move above two checks (#642 and #647) in that method.","commit_id":"0718ef4baa09b47a92c07fb62e128a7a1f3ccae1"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"a3dfb3f275b8483a88c3bc0819f0d7dfdeb8ae75","unresolved":false,"context_lines":[{"line_number":421,"context_line":"            # we definitely do not want to throw 500 and leave the record"},{"line_number":422,"context_line":"            # around. There is no harm finishing this function twice once the"},{"line_number":423,"context_line":"            # data is gone and it will also address any race conditions."},{"line_number":424,"context_line":"            pass"},{"line_number":425,"context_line":"        except Exception as e:"},{"line_number":426,"context_line":"            raise webob.exc.HTTPInternalServerError("},{"line_number":427,"context_line":"                explanation\u003dencodeutils.exception_to_unicode(e))"}],"source_content_type":"text/x-python","patch_set":9,"id":"3fa7e38b_cacff988","line":424,"updated":"2020-01-06 15:34:35.000000000","message":"This doesn\u0027t avoid the race condition.  Took me a while, but I think I have a test showing this.  The test will fail on this code but will pass if this line is changed to \u0027return\u0027.\n\nThat being said, I think return isn\u0027t the correct thing to do here. I think we should go ahead and return some kind of 4xx, probably a HTTPConflict with message something like \"Image location already in process of being deleted\".  (This would distinguish this situation from the 404 being returned at line 377.)\n\nI\u0027ll upload the test for us to look at and make sure it\u0027s doing what I think it is.","commit_id":"69ce28f80696a6b136766d45b239364b7c45bffa"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"d25654184f57541f5537f63a9b9a4d1095930d87","unresolved":false,"context_lines":[{"line_number":388,"context_line":"                    \"deleting the image instead.\")"},{"line_number":389,"context_line":"            raise webob.exc.HTTPForbidden(explanation\u003dmsg)"},{"line_number":390,"context_line":""},{"line_number":391,"context_line":"        if store_id not in CONF.enabled_backends:"},{"line_number":392,"context_line":"            msg \u003d (_(\"The selected store %s is not available on this node.\") %"},{"line_number":393,"context_line":"                   store_id)"},{"line_number":394,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":395,"context_line":""},{"line_number":396,"context_line":"        try:"},{"line_number":397,"context_line":"            # NOTE(jokke): Here we go through the locations list and act on"}],"source_content_type":"text/x-python","patch_set":13,"id":"3fa7e38b_d271d178","line":394,"range":{"start_line":391,"start_character":8,"end_line":394,"end_character":57},"updated":"2020-01-08 09:54:40.000000000","message":"NIT:\nsorry for late comment but can we move it at the top before fetching image?","commit_id":"31b2fe530bb9b277b9c16e0b246f3bed898a09d6"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"5e3ea799ee391850904f43f2767694062114f761","unresolved":false,"context_lines":[{"line_number":396,"context_line":"        try:"},{"line_number":397,"context_line":"            # NOTE(jokke): Here we go through the locations list and act on"},{"line_number":398,"context_line":"            # the first hit. image.locations.pop() will actually remove the"},{"line_number":399,"context_line":"            # data from the backend as well as remove the location from db."},{"line_number":400,"context_line":"            for pos, loc in enumerate(image.locations):"},{"line_number":401,"context_line":"                if loc[\u0027metadata\u0027].get(\u0027store\u0027) \u003d\u003d store_id:"},{"line_number":402,"context_line":"                    image.locations.pop(pos)"}],"source_content_type":"text/x-python","patch_set":14,"id":"3fa7e38b_5bdf2037","line":399,"range":{"start_line":399,"start_character":36,"end_line":399,"end_character":75},"updated":"2020-01-09 21:50:39.000000000","message":"I don\u0027t think this is accurate -- the location gets removed from the image object being carried around in memory, but I don\u0027t think it actually gets updated in the DB until line 423?","commit_id":"0f2a4e10fc102285812ee7d4860be9218a515573"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"5e3ea799ee391850904f43f2767694062114f761","unresolved":false,"context_lines":[{"line_number":415,"context_line":"                   {\"id\": image_id,"},{"line_number":416,"context_line":"                    \"exc\": e.msg})"},{"line_number":417,"context_line":"            LOG.warn(msg)"},{"line_number":418,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":419,"context_line":"        except Exception as e:"},{"line_number":420,"context_line":"            raise webob.exc.HTTPInternalServerError("},{"line_number":421,"context_line":"                explanation\u003dencodeutils.exception_to_unicode(e))"}],"source_content_type":"text/x-python","patch_set":14,"id":"3fa7e38b_f6fb81bb","line":418,"updated":"2020-01-09 21:50:39.000000000","message":"I suggest leaving location.py unchanged and instead catch the glance_store.exceptions.NotFound in this chain of exception handlers.  We are making the inference that since the location existed when we got the image at line 376, but now it cannot be found in the backend, the data must have been deleted by another call.  The location.pop() has raised an exception, so we don\u0027t want to call save() at line 423.  (We can\u0027t simply remove the location ourselves because location.remove() calls location.pop(), so remove() will also fail with a NotFound.)\n\nI think the right thing to do here is to go ahead and raise webob.exc.HTTPNotFound (so that line 423 is not called).  If I issue 5 DELETE requests on a resource, I\u0027d expect (in the best case) to get one 2xx and four 404s.  So I think we should rely on the call that actually was able to delete the data to complete and return a 204, and this thread here should return a 404 (\"Data for image %(id) cannot be found in store %(store_id)\") without making any changes to the system.","commit_id":"0f2a4e10fc102285812ee7d4860be9218a515573"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"6c67f091f928dfc978da2c7f1ff497076a57412c","unresolved":false,"context_lines":[{"line_number":382,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003dmsg)"},{"line_number":383,"context_line":""},{"line_number":384,"context_line":"        if image.status not in (\u0027active\u0027):"},{"line_number":385,"context_line":"            msg \u003d _(\"It\u0027s not allowed to remove locations if image status is \""},{"line_number":386,"context_line":"                    \"%s.\") % image.status"},{"line_number":387,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":388,"context_line":""},{"line_number":389,"context_line":"        if len(image.locations) \u003d\u003d 1:"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_879d0b0b","line":386,"range":{"start_line":385,"start_character":0,"end_line":386,"end_character":41},"updated":"2020-01-14 14:32:03.000000000","message":"See my comment on the previous PS.  I think we should reword this to talk about stores and image data.","commit_id":"3d6a97f6d4da6c4e209bdec016238533f1e920cf"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"5feafd23668905d8186190a0b58d9b302d989325","unresolved":false,"context_lines":[{"line_number":382,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003dmsg)"},{"line_number":383,"context_line":""},{"line_number":384,"context_line":"        if image.status not in (\u0027active\u0027):"},{"line_number":385,"context_line":"            msg \u003d _(\"It\u0027s not allowed to remove locations if image status is \""},{"line_number":386,"context_line":"                    \"%s.\") % image.status"},{"line_number":387,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":388,"context_line":""},{"line_number":389,"context_line":"        if len(image.locations) \u003d\u003d 1:"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_8e6a0380","line":386,"range":{"start_line":385,"start_character":0,"end_line":386,"end_character":41},"in_reply_to":"3fa7e38b_6bc9b978","updated":"2020-01-14 16:11:27.000000000","message":"It was an \"outside\" comment on the review page:\n\nReading through the exception responses, I think there is too much \"location\" talk.  We want users to deal with stores and image data (because we\u0027d like to get to the point eventually where image locations aren\u0027t exposed to users at all).  So, for instance, the error message at line 392 should probably read, \"Cannot delete image data from the only store containing it.  Consider deleting the image instead.\"  The message at line 385 should be something like \"Cannot delete image data from a store when the image status is %s\".\n\nThe request we are processing is DELETE /v2/stores/store_id/image_id -- nothing about locations there.","commit_id":"3d6a97f6d4da6c4e209bdec016238533f1e920cf"},{"author":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"change_message_id":"ac883a2a8f20d5023b32cc12e209544a31b68b2d","unresolved":false,"context_lines":[{"line_number":382,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003dmsg)"},{"line_number":383,"context_line":""},{"line_number":384,"context_line":"        if image.status not in (\u0027active\u0027):"},{"line_number":385,"context_line":"            msg \u003d _(\"It\u0027s not allowed to remove locations if image status is \""},{"line_number":386,"context_line":"                    \"%s.\") % image.status"},{"line_number":387,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":388,"context_line":""},{"line_number":389,"context_line":"        if len(image.locations) \u003d\u003d 1:"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_6bc9b978","line":386,"range":{"start_line":385,"start_character":0,"end_line":386,"end_character":41},"in_reply_to":"3fa7e38b_879d0b0b","updated":"2020-01-14 15:56:23.000000000","message":"Sorry, went through every previous PS and couldn\u0027t find anything here.\n\nNot sure if that would help anyone to move away from the well established \"locations\" we have been using for years and everyone is familiar with.\n\nLets see what Abhishek, Sean and others thinks as well. The messages are trivial change to do.","commit_id":"3d6a97f6d4da6c4e209bdec016238533f1e920cf"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"70e1c73b3918437a55be8b03b3b7097c11f660f8","unresolved":false,"context_lines":[{"line_number":382,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003dmsg)"},{"line_number":383,"context_line":""},{"line_number":384,"context_line":"        if image.status not in (\u0027active\u0027):"},{"line_number":385,"context_line":"            msg \u003d _(\"It\u0027s not allowed to remove locations if image status is \""},{"line_number":386,"context_line":"                    \"%s.\") % image.status"},{"line_number":387,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":388,"context_line":""},{"line_number":389,"context_line":"        if len(image.locations) \u003d\u003d 1:"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_2763c9ad","line":386,"range":{"start_line":385,"start_character":0,"end_line":386,"end_character":41},"in_reply_to":"3fa7e38b_8e6a0380","updated":"2020-01-16 15:28:01.000000000","message":"As the title suggests delete image from single store, we should reflect the same from the log/error messages as well. Also for this feature locations are not exposed to end users so it makes more sense to talk about particular image and store.","commit_id":"3d6a97f6d4da6c4e209bdec016238533f1e920cf"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"6c67f091f928dfc978da2c7f1ff497076a57412c","unresolved":false,"context_lines":[{"line_number":389,"context_line":"        if len(image.locations) \u003d\u003d 1:"},{"line_number":390,"context_line":"            LOG.debug(\"User forbidden to remove last location of image %s\","},{"line_number":391,"context_line":"                      image.image_id)"},{"line_number":392,"context_line":"            msg \u003d _(\"Cannot remove last location in the image. Consider \""},{"line_number":393,"context_line":"                    \"deleting the image instead.\")"},{"line_number":394,"context_line":"            raise webob.exc.HTTPForbidden(explanation\u003dmsg)"},{"line_number":395,"context_line":""},{"line_number":396,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_e78b9fbe","line":393,"range":{"start_line":392,"start_character":0,"end_line":393,"end_character":50},"updated":"2020-01-14 14:32:03.000000000","message":"Same here.","commit_id":"3d6a97f6d4da6c4e209bdec016238533f1e920cf"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"6c67f091f928dfc978da2c7f1ff497076a57412c","unresolved":false,"context_lines":[{"line_number":396,"context_line":"        try:"},{"line_number":397,"context_line":"            # NOTE(jokke): Here we go through the locations list and act on"},{"line_number":398,"context_line":"            # the first hit. image.locations.pop() will actually remove the"},{"line_number":399,"context_line":"            # data from the backend as well as remove the location from db."},{"line_number":400,"context_line":"            for pos, loc in enumerate(image.locations):"},{"line_number":401,"context_line":"                if loc[\u0027metadata\u0027].get(\u0027store\u0027) \u003d\u003d store_id:"},{"line_number":402,"context_line":"                    image.locations.pop(pos)"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_e2fb8dbc","line":399,"range":{"start_line":399,"start_character":67,"end_line":399,"end_character":74},"updated":"2020-01-14 14:32:03.000000000","message":"\"from the list\" (db isn\u0027t changed until image.save())","commit_id":"3d6a97f6d4da6c4e209bdec016238533f1e920cf"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"6c67f091f928dfc978da2c7f1ff497076a57412c","unresolved":false,"context_lines":[{"line_number":417,"context_line":"            LOG.debug(\"The Image data for %(iid)s was not found in store\""},{"line_number":418,"context_line":"                      \"%(sid)s, removed location metadata.\" %"},{"line_number":419,"context_line":"                      {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id})"},{"line_number":420,"context_line":"            msg \u003d _(\u0027The image data was not in the store, removing metadata\u0027)"},{"line_number":421,"context_line":"            raise webob.exc.HTTPGone(explanation\u003dmsg)"},{"line_number":422,"context_line":"        except glance_store.exceptions.InUseByStore as e:"},{"line_number":423,"context_line":"            msg \u003d (_(\"Image %(id)s\u0027s location could not be deleted \""}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_a22115a4","line":420,"range":{"start_line":420,"start_character":20,"end_line":420,"end_character":77},"updated":"2020-01-14 14:32:03.000000000","message":"Might as be very specific since we have the info available.  I suggest something like \"The Image data for %(iid)s was not found in store %(sid)s.  The Image record has been updated to reflect this.\"","commit_id":"3d6a97f6d4da6c4e209bdec016238533f1e920cf"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"6c67f091f928dfc978da2c7f1ff497076a57412c","unresolved":false,"context_lines":[{"line_number":425,"context_line":"                   {\"id\": image_id,"},{"line_number":426,"context_line":"                    \"exc\": e.msg})"},{"line_number":427,"context_line":"            LOG.warn(msg)"},{"line_number":428,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":429,"context_line":"        except Exception as e:"},{"line_number":430,"context_line":"            raise webob.exc.HTTPInternalServerError("},{"line_number":431,"context_line":"                explanation\u003dencodeutils.exception_to_unicode(e))"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_62ec7d28","line":428,"range":{"start_line":428,"start_character":41,"end_line":428,"end_character":56},"updated":"2020-01-14 14:32:03.000000000","message":"Two things here: (1) I don\u0027t think we should expose the exception message to the end user, and (2) we should express this in terms of store and image data for the end user: \"The data for image %(id) cannot be deleted from store %(sid) because it is in use\"","commit_id":"3d6a97f6d4da6c4e209bdec016238533f1e920cf"},{"author":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"change_message_id":"8479e7c2314f376c3af570477830e82a5155580b","unresolved":false,"context_lines":[{"line_number":425,"context_line":"                   {\"id\": image_id,"},{"line_number":426,"context_line":"                    \"exc\": e.msg})"},{"line_number":427,"context_line":"            LOG.warn(msg)"},{"line_number":428,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":429,"context_line":"        except Exception as e:"},{"line_number":430,"context_line":"            raise webob.exc.HTTPInternalServerError("},{"line_number":431,"context_line":"                explanation\u003dencodeutils.exception_to_unicode(e))"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_a2afa77a","line":428,"range":{"start_line":428,"start_character":41,"end_line":428,"end_character":56},"in_reply_to":"3fa7e38b_62ec7d28","updated":"2020-01-16 16:09:35.000000000","message":"Actually the exception message is perfect here if we want to avoid talking about the location:\nclass InUseByStore(GlanceStoreException):\n     message \u003d _(\"The image cannot be deleted because it is in use through \"\n                 \"the backend store outside of Glance.\")","commit_id":"3d6a97f6d4da6c4e209bdec016238533f1e920cf"},{"author":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"change_message_id":"ac883a2a8f20d5023b32cc12e209544a31b68b2d","unresolved":false,"context_lines":[{"line_number":425,"context_line":"                   {\"id\": image_id,"},{"line_number":426,"context_line":"                    \"exc\": e.msg})"},{"line_number":427,"context_line":"            LOG.warn(msg)"},{"line_number":428,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":429,"context_line":"        except Exception as e:"},{"line_number":430,"context_line":"            raise webob.exc.HTTPInternalServerError("},{"line_number":431,"context_line":"                explanation\u003dencodeutils.exception_to_unicode(e))"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_a83fb7dd","line":428,"range":{"start_line":428,"start_character":41,"end_line":428,"end_character":56},"in_reply_to":"3fa7e38b_62ec7d28","updated":"2020-01-14 15:56:23.000000000","message":"In this case I disagree. This is consistent with the response we give in the very same situation from image delete Lines 488-491. We do this quite a bit.\n\nI agree that we probably should change these, but that should be separate discussion across the API rather than introduce inconsistency at this point.","commit_id":"3d6a97f6d4da6c4e209bdec016238533f1e920cf"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"5feafd23668905d8186190a0b58d9b302d989325","unresolved":false,"context_lines":[{"line_number":425,"context_line":"                   {\"id\": image_id,"},{"line_number":426,"context_line":"                    \"exc\": e.msg})"},{"line_number":427,"context_line":"            LOG.warn(msg)"},{"line_number":428,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":429,"context_line":"        except Exception as e:"},{"line_number":430,"context_line":"            raise webob.exc.HTTPInternalServerError("},{"line_number":431,"context_line":"                explanation\u003dencodeutils.exception_to_unicode(e))"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_ee9a9773","line":428,"range":{"start_line":428,"start_character":41,"end_line":428,"end_character":56},"in_reply_to":"3fa7e38b_a83fb7dd","updated":"2020-01-14 16:11:27.000000000","message":"Agree about keeping the responses consistent; still think we should talk in terms of store/data rather than location.","commit_id":"3d6a97f6d4da6c4e209bdec016238533f1e920cf"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"70e1c73b3918437a55be8b03b3b7097c11f660f8","unresolved":false,"context_lines":[{"line_number":425,"context_line":"                   {\"id\": image_id,"},{"line_number":426,"context_line":"                    \"exc\": e.msg})"},{"line_number":427,"context_line":"            LOG.warn(msg)"},{"line_number":428,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":429,"context_line":"        except Exception as e:"},{"line_number":430,"context_line":"            raise webob.exc.HTTPInternalServerError("},{"line_number":431,"context_line":"                explanation\u003dencodeutils.exception_to_unicode(e))"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_27f8a9bf","line":428,"range":{"start_line":428,"start_character":41,"end_line":428,"end_character":56},"in_reply_to":"3fa7e38b_ee9a9773","updated":"2020-01-16 15:28:01.000000000","message":"ditto, we should talk about specific store instead of location.","commit_id":"3d6a97f6d4da6c4e209bdec016238533f1e920cf"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"0c9fd35aedd38a5e76dcb416df605b31b76609b8","unresolved":false,"context_lines":[{"line_number":377,"context_line":"        except exception.NotAuthenticated as e:"},{"line_number":378,"context_line":"            raise webob.exc.HTTPUnauthorized(explanation\u003de.msg)"},{"line_number":379,"context_line":"        except exception.NotFound as e:"},{"line_number":380,"context_line":"            msg \u003d (_(\"Failed to find image %(image_id)s\") %"},{"line_number":381,"context_line":"                   {\u0027image_id\u0027: image_id})"},{"line_number":382,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003dmsg)"},{"line_number":383,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"3fa7e38b_98d453ec","line":380,"range":{"start_line":380,"start_character":58,"end_line":380,"end_character":59},"updated":"2020-01-17 05:09:19.000000000","message":"Recently we merged a patch to fix string interpolation to delay by logging [1].\n\n[1] https://review.opendev.org/#/c/341995/3","commit_id":"5ed4a861cdcdc426c08ed4d91cf96bead1ec0b48"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"0f3124f8f575c59a6447abb905335b8bc0244862","unresolved":false,"context_lines":[{"line_number":382,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003dmsg)"},{"line_number":383,"context_line":""},{"line_number":384,"context_line":"        if image.status !\u003d \u0027active\u0027:"},{"line_number":385,"context_line":"            msg \u003d _(\"It\u0027s not allowed to remove image form store if image \""},{"line_number":386,"context_line":"                    \"status is not \u0027active\u0027\")"},{"line_number":387,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":388,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"3fa7e38b_b41593e8","line":385,"range":{"start_line":385,"start_character":48,"end_line":385,"end_character":64},"updated":"2020-01-17 14:43:49.000000000","message":"typo: should be \u0027from\u0027\nBut I suggest replacing with \"image data from a store\"","commit_id":"5ed4a861cdcdc426c08ed4d91cf96bead1ec0b48"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"d3cc01d43e2c7aaffe0834741ce2031c19ffacb5","unresolved":false,"context_lines":[{"line_number":382,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003dmsg)"},{"line_number":383,"context_line":""},{"line_number":384,"context_line":"        if image.status !\u003d \u0027active\u0027:"},{"line_number":385,"context_line":"            msg \u003d _(\"It\u0027s not allowed to remove image form store if image \""},{"line_number":386,"context_line":"                    \"status is not \u0027active\u0027\")"},{"line_number":387,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":388,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"1fa4df85_ecc6ed49","line":385,"range":{"start_line":385,"start_character":48,"end_line":385,"end_character":64},"in_reply_to":"3fa7e38b_b41593e8","updated":"2020-03-04 05:06:28.000000000","message":"Done","commit_id":"5ed4a861cdcdc426c08ed4d91cf96bead1ec0b48"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"0f3124f8f575c59a6447abb905335b8bc0244862","unresolved":false,"context_lines":[{"line_number":389,"context_line":"        if len(image.locations) \u003d\u003d 1:"},{"line_number":390,"context_line":"            LOG.debug(\"User forbidden to remove last location of image %s\","},{"line_number":391,"context_line":"                      image_id)"},{"line_number":392,"context_line":"            msg \u003d _(\"Cannot remove image from it\u0027s last store. Consider \""},{"line_number":393,"context_line":"                    \"deleting the image instead.\")"},{"line_number":394,"context_line":"            raise webob.exc.HTTPForbidden(explanation\u003dmsg)"},{"line_number":395,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"3fa7e38b_f4c9cb79","line":392,"range":{"start_line":392,"start_character":46,"end_line":392,"end_character":50},"updated":"2020-01-17 14:43:49.000000000","message":"should be \"its\".  But I\u0027d suggest this message instead:\n\n\"Cannot delete image data from the only store containing it. Consider deleting the image instead.\"","commit_id":"5ed4a861cdcdc426c08ed4d91cf96bead1ec0b48"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"d3cc01d43e2c7aaffe0834741ce2031c19ffacb5","unresolved":false,"context_lines":[{"line_number":389,"context_line":"        if len(image.locations) \u003d\u003d 1:"},{"line_number":390,"context_line":"            LOG.debug(\"User forbidden to remove last location of image %s\","},{"line_number":391,"context_line":"                      image_id)"},{"line_number":392,"context_line":"            msg \u003d _(\"Cannot remove image from it\u0027s last store. Consider \""},{"line_number":393,"context_line":"                    \"deleting the image instead.\")"},{"line_number":394,"context_line":"            raise webob.exc.HTTPForbidden(explanation\u003dmsg)"},{"line_number":395,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"1fa4df85_acd555e7","line":392,"range":{"start_line":392,"start_character":46,"end_line":392,"end_character":50},"in_reply_to":"3fa7e38b_f4c9cb79","updated":"2020-03-04 05:06:28.000000000","message":"Done","commit_id":"5ed4a861cdcdc426c08ed4d91cf96bead1ec0b48"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"0c9fd35aedd38a5e76dcb416df605b31b76609b8","unresolved":false,"context_lines":[{"line_number":403,"context_line":"                    image.locations.pop(pos)"},{"line_number":404,"context_line":"                    break"},{"line_number":405,"context_line":"            else:"},{"line_number":406,"context_line":"                msg \u003d (_(\"Image %(iid)s is not stored in store %(sid)s.\") %"},{"line_number":407,"context_line":"                       {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id})"},{"line_number":408,"context_line":"                raise exception.Invalid(msg)"},{"line_number":409,"context_line":"        except exception.Forbidden as e:"}],"source_content_type":"text/x-python","patch_set":17,"id":"3fa7e38b_58001b6a","line":406,"range":{"start_line":406,"start_character":74,"end_line":406,"end_character":75},"updated":"2020-01-17 05:09:19.000000000","message":"ditto","commit_id":"5ed4a861cdcdc426c08ed4d91cf96bead1ec0b48"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"0c9fd35aedd38a5e76dcb416df605b31b76609b8","unresolved":false,"context_lines":[{"line_number":416,"context_line":"            # is gone."},{"line_number":417,"context_line":"            image_repo.save(image)"},{"line_number":418,"context_line":"            LOG.debug(\"The Image data for %(iid)s was not found in store\""},{"line_number":419,"context_line":"                      \"%(sid)s, removed location metadata.\" %"},{"line_number":420,"context_line":"                      {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id})"},{"line_number":421,"context_line":"            msg \u003d _(\"The image data was not found in the store, removed \""},{"line_number":422,"context_line":"                    \"the store listed in the metadata\")"}],"source_content_type":"text/x-python","patch_set":17,"id":"3fa7e38b_78039776","line":419,"range":{"start_line":419,"start_character":60,"end_line":419,"end_character":61},"updated":"2020-01-17 05:09:19.000000000","message":"ditto","commit_id":"5ed4a861cdcdc426c08ed4d91cf96bead1ec0b48"},{"author":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"change_message_id":"65d98eb9e11d4fa744f6d55e8a201b15c15d3edc","unresolved":false,"context_lines":[{"line_number":416,"context_line":"            # is gone."},{"line_number":417,"context_line":"            image_repo.save(image)"},{"line_number":418,"context_line":"            LOG.debug(\"The Image data for %(iid)s was not found in store\""},{"line_number":419,"context_line":"                      \"%(sid)s, removed location metadata.\" %"},{"line_number":420,"context_line":"                      {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id})"},{"line_number":421,"context_line":"            msg \u003d _(\"The image data was not found in the store, removed \""},{"line_number":422,"context_line":"                    \"the store listed in the metadata\")"}],"source_content_type":"text/x-python","patch_set":17,"id":"3fa7e38b_747e3b6e","line":419,"range":{"start_line":419,"start_character":60,"end_line":419,"end_character":61},"in_reply_to":"3fa7e38b_78039776","updated":"2020-01-17 14:15:23.000000000","message":"This and the one below is actually logged, won\u0027t work on the two above. This is what we get by thinking few postponed string operations over consistency is going to save the world.","commit_id":"5ed4a861cdcdc426c08ed4d91cf96bead1ec0b48"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"0f3124f8f575c59a6447abb905335b8bc0244862","unresolved":false,"context_lines":[{"line_number":418,"context_line":"            LOG.debug(\"The Image data for %(iid)s was not found in store\""},{"line_number":419,"context_line":"                      \"%(sid)s, removed location metadata.\" %"},{"line_number":420,"context_line":"                      {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id})"},{"line_number":421,"context_line":"            msg \u003d _(\"The image data was not found in the store, removed \""},{"line_number":422,"context_line":"                    \"the store listed in the metadata\")"},{"line_number":423,"context_line":"            raise webob.exc.HTTPGone(explanation\u003dmsg)"},{"line_number":424,"context_line":"        except glance_store.exceptions.InUseByStore as e:"},{"line_number":425,"context_line":"            msg \u003d _LW(\u0027Cannot delete Image %(iid)s from store %(sid)s as it \u0027"}],"source_content_type":"text/x-python","patch_set":17,"id":"3fa7e38b_148a671d","line":422,"range":{"start_line":421,"start_character":20,"end_line":422,"end_character":54},"updated":"2020-01-17 14:43:49.000000000","message":"Since we have the info, I think it would be more user-friendly to be specific here:\n\n\"The Image data for %(iid)s was not found in store %(sid)s. The Image record has been updated to reflect this.\"","commit_id":"5ed4a861cdcdc426c08ed4d91cf96bead1ec0b48"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"d3cc01d43e2c7aaffe0834741ce2031c19ffacb5","unresolved":false,"context_lines":[{"line_number":418,"context_line":"            LOG.debug(\"The Image data for %(iid)s was not found in store\""},{"line_number":419,"context_line":"                      \"%(sid)s, removed location metadata.\" %"},{"line_number":420,"context_line":"                      {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id})"},{"line_number":421,"context_line":"            msg \u003d _(\"The image data was not found in the store, removed \""},{"line_number":422,"context_line":"                    \"the store listed in the metadata\")"},{"line_number":423,"context_line":"            raise webob.exc.HTTPGone(explanation\u003dmsg)"},{"line_number":424,"context_line":"        except glance_store.exceptions.InUseByStore as e:"},{"line_number":425,"context_line":"            msg \u003d _LW(\u0027Cannot delete Image %(iid)s from store %(sid)s as it \u0027"}],"source_content_type":"text/x-python","patch_set":17,"id":"1fa4df85_8cf3b99e","line":422,"range":{"start_line":421,"start_character":20,"end_line":422,"end_character":54},"in_reply_to":"3fa7e38b_148a671d","updated":"2020-03-04 05:06:28.000000000","message":"Done","commit_id":"5ed4a861cdcdc426c08ed4d91cf96bead1ec0b48"},{"author":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"change_message_id":"cd692cce7ccaee5345af17ae427d44d27b21ba0e","unresolved":false,"context_lines":[{"line_number":418,"context_line":"            LOG.debug(\"The Image data for %(iid)s was not found in store\""},{"line_number":419,"context_line":"                      \"%(sid)s, removed location metadata.\" %"},{"line_number":420,"context_line":"                      {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id})"},{"line_number":421,"context_line":"            msg \u003d _(\"The image data was not found in the store, removed \""},{"line_number":422,"context_line":"                    \"the store listed in the metadata\")"},{"line_number":423,"context_line":"            raise webob.exc.HTTPGone(explanation\u003dmsg)"},{"line_number":424,"context_line":"        except glance_store.exceptions.InUseByStore as e:"},{"line_number":425,"context_line":"            msg \u003d _LW(\u0027Cannot delete Image %(iid)s from store %(sid)s as it \u0027"}],"source_content_type":"text/x-python","patch_set":17,"id":"3fa7e38b_65bbd6bd","line":422,"range":{"start_line":421,"start_character":20,"end_line":422,"end_character":54},"in_reply_to":"3fa7e38b_148a671d","updated":"2020-02-28 11:44:25.000000000","message":"We pretty much never respond with the request data (image IDs, metadata fields, etc.) unless it looks like typo","commit_id":"5ed4a861cdcdc426c08ed4d91cf96bead1ec0b48"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"0f3124f8f575c59a6447abb905335b8bc0244862","unresolved":false,"context_lines":[{"line_number":422,"context_line":"                    \"the store listed in the metadata\")"},{"line_number":423,"context_line":"            raise webob.exc.HTTPGone(explanation\u003dmsg)"},{"line_number":424,"context_line":"        except glance_store.exceptions.InUseByStore as e:"},{"line_number":425,"context_line":"            msg \u003d _LW(\u0027Cannot delete Image %(iid)s from store %(sid)s as it \u0027"},{"line_number":426,"context_line":"                      \u0027is in use.\u0027) % {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id}"},{"line_number":427,"context_line":"            LOG.warn(msg)"},{"line_number":428,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003de.msg)"},{"line_number":429,"context_line":"        except Exception as e:"}],"source_content_type":"text/x-python","patch_set":17,"id":"3fa7e38b_3493e350","line":426,"range":{"start_line":425,"start_character":23,"end_line":426,"end_character":34},"updated":"2020-01-17 14:43:49.000000000","message":"I think this message could be more precise:\n\"The data for image %(id) cannot be deleted from store %(sid) because it is in use\"","commit_id":"5ed4a861cdcdc426c08ed4d91cf96bead1ec0b48"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"0c9fd35aedd38a5e76dcb416df605b31b76609b8","unresolved":false,"context_lines":[{"line_number":423,"context_line":"            raise webob.exc.HTTPGone(explanation\u003dmsg)"},{"line_number":424,"context_line":"        except glance_store.exceptions.InUseByStore as e:"},{"line_number":425,"context_line":"            msg \u003d _LW(\u0027Cannot delete Image %(iid)s from store %(sid)s as it \u0027"},{"line_number":426,"context_line":"                      \u0027is in use.\u0027) % {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id}"},{"line_number":427,"context_line":"            LOG.warn(msg)"},{"line_number":428,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003de.msg)"},{"line_number":429,"context_line":"        except Exception as e:"}],"source_content_type":"text/x-python","patch_set":17,"id":"3fa7e38b_18faa376","line":426,"range":{"start_line":426,"start_character":35,"end_line":426,"end_character":37},"updated":"2020-01-17 05:09:19.000000000","message":"ditto","commit_id":"5ed4a861cdcdc426c08ed4d91cf96bead1ec0b48"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"d3cc01d43e2c7aaffe0834741ce2031c19ffacb5","unresolved":false,"context_lines":[{"line_number":422,"context_line":"                    \"the store listed in the metadata\")"},{"line_number":423,"context_line":"            raise webob.exc.HTTPGone(explanation\u003dmsg)"},{"line_number":424,"context_line":"        except glance_store.exceptions.InUseByStore as e:"},{"line_number":425,"context_line":"            msg \u003d _LW(\u0027Cannot delete Image %(iid)s from store %(sid)s as it \u0027"},{"line_number":426,"context_line":"                      \u0027is in use.\u0027) % {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id}"},{"line_number":427,"context_line":"            LOG.warn(msg)"},{"line_number":428,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003de.msg)"},{"line_number":429,"context_line":"        except Exception as e:"}],"source_content_type":"text/x-python","patch_set":17,"id":"1fa4df85_8c4899cc","line":426,"range":{"start_line":425,"start_character":23,"end_line":426,"end_character":34},"in_reply_to":"3fa7e38b_3493e350","updated":"2020-03-04 05:06:28.000000000","message":"Done","commit_id":"5ed4a861cdcdc426c08ed4d91cf96bead1ec0b48"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"0f3124f8f575c59a6447abb905335b8bc0244862","unresolved":false,"context_lines":[{"line_number":425,"context_line":"            msg \u003d _LW(\u0027Cannot delete Image %(iid)s from store %(sid)s as it \u0027"},{"line_number":426,"context_line":"                      \u0027is in use.\u0027) % {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id}"},{"line_number":427,"context_line":"            LOG.warn(msg)"},{"line_number":428,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003de.msg)"},{"line_number":429,"context_line":"        except Exception as e:"},{"line_number":430,"context_line":"            raise webob.exc.HTTPInternalServerError("},{"line_number":431,"context_line":"                explanation\u003dencodeutils.exception_to_unicode(e))"}],"source_content_type":"text/x-python","patch_set":17,"id":"3fa7e38b_b4bfd3a9","line":428,"range":{"start_line":428,"start_character":53,"end_line":428,"end_character":58},"updated":"2020-01-17 14:43:49.000000000","message":"I\u0027d suggest using the msg that\u0027s logged here instead of the generic response--it give the user more information in the response.","commit_id":"5ed4a861cdcdc426c08ed4d91cf96bead1ec0b48"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"d3cc01d43e2c7aaffe0834741ce2031c19ffacb5","unresolved":false,"context_lines":[{"line_number":425,"context_line":"            msg \u003d _LW(\u0027Cannot delete Image %(iid)s from store %(sid)s as it \u0027"},{"line_number":426,"context_line":"                      \u0027is in use.\u0027) % {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id}"},{"line_number":427,"context_line":"            LOG.warn(msg)"},{"line_number":428,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003de.msg)"},{"line_number":429,"context_line":"        except Exception as e:"},{"line_number":430,"context_line":"            raise webob.exc.HTTPInternalServerError("},{"line_number":431,"context_line":"                explanation\u003dencodeutils.exception_to_unicode(e))"}],"source_content_type":"text/x-python","patch_set":17,"id":"1fa4df85_6c175da5","line":428,"range":{"start_line":428,"start_character":53,"end_line":428,"end_character":58},"in_reply_to":"3fa7e38b_b4bfd3a9","updated":"2020-03-04 05:06:28.000000000","message":"Done","commit_id":"5ed4a861cdcdc426c08ed4d91cf96bead1ec0b48"},{"author":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"change_message_id":"cd692cce7ccaee5345af17ae427d44d27b21ba0e","unresolved":false,"context_lines":[{"line_number":455,"context_line":"                      {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id})"},{"line_number":456,"context_line":"            msg \u003d _(\"The image data for %(iid)s was not found in the store \""},{"line_number":457,"context_line":"                    \"%(sid)s. The image record has been updated to reflect \""},{"line_number":458,"context_line":"                    \"this.\") % {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id}"},{"line_number":459,"context_line":"            raise webob.exc.HTTPGone(explanation\u003dmsg)"},{"line_number":460,"context_line":"        except glance_store.exceptions.InUseByStore as e:"},{"line_number":461,"context_line":"            msg \u003d _LW(\u0027The data for Image %(iid)s cannot be deleted from \u0027"}],"source_content_type":"text/x-python","patch_set":18,"id":"1fa4df85_46003d68","line":458,"range":{"start_line":458,"start_character":31,"end_line":458,"end_character":65},"updated":"2020-02-28 11:44:25.000000000","message":"Across our API we only flag the IDs on the response if the ID does not exists. We should not start polluting the response messages with valid IDs now.\n\nIt\u0027s important to log the Ids for operator who has no idea what resource was been accessed otherwise. The user has full context of what resource they are interfacing with.","commit_id":"5a0609d4cd17cced77c1599ed91f2c39b4389723"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"783a32d4ed5f91a6726f94d41c0606e860ae979b","unresolved":false,"context_lines":[{"line_number":455,"context_line":"                      {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id})"},{"line_number":456,"context_line":"            msg \u003d _(\"The image data for %(iid)s was not found in the store \""},{"line_number":457,"context_line":"                    \"%(sid)s. The image record has been updated to reflect \""},{"line_number":458,"context_line":"                    \"this.\") % {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id}"},{"line_number":459,"context_line":"            raise webob.exc.HTTPGone(explanation\u003dmsg)"},{"line_number":460,"context_line":"        except glance_store.exceptions.InUseByStore as e:"},{"line_number":461,"context_line":"            msg \u003d _LW(\u0027The data for Image %(iid)s cannot be deleted from \u0027"}],"source_content_type":"text/x-python","patch_set":18,"id":"1fa4df85_cff09a6a","line":458,"range":{"start_line":458,"start_character":31,"end_line":458,"end_character":65},"in_reply_to":"1fa4df85_46003d68","updated":"2020-03-02 23:06:10.000000000","message":"I disagree.  The (store_id, image_id) tuple indicates a resource that does not exist, so on your analogy with the nonexistent image ID, we should include them in the message.","commit_id":"5a0609d4cd17cced77c1599ed91f2c39b4389723"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"1a480a4de89cdec40044ce2b2fee4919e464267e","unresolved":false,"context_lines":[{"line_number":445,"context_line":"            raise webob.exc.HTTPForbidden(explanation\u003de.msg)"},{"line_number":446,"context_line":"        except exception.Invalid as e:"},{"line_number":447,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003de.msg)"},{"line_number":448,"context_line":"        except glance_store.exceptions.NotFound as e:"},{"line_number":449,"context_line":"            # NOTE(jokke): This means that the data is gone from the store."},{"line_number":450,"context_line":"            # We update the metadata and let the user know that the resource"},{"line_number":451,"context_line":"            # is gone."},{"line_number":452,"context_line":"            image_repo.save(image)"},{"line_number":453,"context_line":"            LOG.debug(\"The Image data for %(iid)s was not found in store\""},{"line_number":454,"context_line":"                      \"%(sid)s, removed location metadata.\" %"},{"line_number":455,"context_line":"                      {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id})"},{"line_number":456,"context_line":"            msg \u003d _(\"The image data for %(iid)s was not found in the store \""},{"line_number":457,"context_line":"                    \"%(sid)s. The image record has been updated to reflect \""},{"line_number":458,"context_line":"                    \"this.\") % {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id}"},{"line_number":459,"context_line":"            raise webob.exc.HTTPGone(explanation\u003dmsg)"},{"line_number":460,"context_line":"        except glance_store.exceptions.InUseByStore as e:"},{"line_number":461,"context_line":"            msg \u003d _LW(\u0027The data for Image %(iid)s cannot be deleted from \u0027"},{"line_number":462,"context_line":"                      \u0027store %(sid)s because it is in \u0027"}],"source_content_type":"text/x-python","patch_set":18,"id":"1fa4df85_d4532138","line":459,"range":{"start_line":448,"start_character":8,"end_line":459,"end_character":53},"updated":"2020-03-05 05:06:27.000000000","message":"This entire block is unreachable as actual glance_store.exceptions.NotFound is caught at [1] and never reraised from there. I have also verified that it removes the location entry (location metadata) for that image.\n\nSo we should remove this unreachable block.\n\n[1] https://github.com/openstack/glance/blob/master/glance/common/store_utils.py#L71","commit_id":"5a0609d4cd17cced77c1599ed91f2c39b4389723"},{"author":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"change_message_id":"cd692cce7ccaee5345af17ae427d44d27b21ba0e","unresolved":false,"context_lines":[{"line_number":462,"context_line":"                      \u0027store %(sid)s because it is in \u0027"},{"line_number":463,"context_line":"                      \u0027use.\u0027) % {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id}"},{"line_number":464,"context_line":"            LOG.warn(msg)"},{"line_number":465,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":466,"context_line":"        except Exception as e:"},{"line_number":467,"context_line":"            raise webob.exc.HTTPInternalServerError("},{"line_number":468,"context_line":"                explanation\u003dencodeutils.exception_to_unicode(e))"}],"source_content_type":"text/x-python","patch_set":18,"id":"1fa4df85_6611b9ac","line":465,"range":{"start_line":465,"start_character":53,"end_line":465,"end_character":56},"updated":"2020-02-28 11:44:25.000000000","message":"ditto","commit_id":"5a0609d4cd17cced77c1599ed91f2c39b4389723"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"1a480a4de89cdec40044ce2b2fee4919e464267e","unresolved":false,"context_lines":[{"line_number":462,"context_line":"                      \u0027store %(sid)s because it is in \u0027"},{"line_number":463,"context_line":"                      \u0027use.\u0027) % {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id}"},{"line_number":464,"context_line":"            LOG.warn(msg)"},{"line_number":465,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":466,"context_line":"        except Exception as e:"},{"line_number":467,"context_line":"            raise webob.exc.HTTPInternalServerError("},{"line_number":468,"context_line":"                explanation\u003dencodeutils.exception_to_unicode(e))"}],"source_content_type":"text/x-python","patch_set":18,"id":"1fa4df85_1423f9be","line":465,"range":{"start_line":465,"start_character":53,"end_line":465,"end_character":56},"in_reply_to":"1fa4df85_0ffeb236","updated":"2020-03-05 05:06:27.000000000","message":"I guess we should log image_id here and not store_id.","commit_id":"5a0609d4cd17cced77c1599ed91f2c39b4389723"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"783a32d4ed5f91a6726f94d41c0606e860ae979b","unresolved":false,"context_lines":[{"line_number":462,"context_line":"                      \u0027store %(sid)s because it is in \u0027"},{"line_number":463,"context_line":"                      \u0027use.\u0027) % {\u0027iid\u0027: image_id, \u0027sid\u0027: store_id}"},{"line_number":464,"context_line":"            LOG.warn(msg)"},{"line_number":465,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":466,"context_line":"        except Exception as e:"},{"line_number":467,"context_line":"            raise webob.exc.HTTPInternalServerError("},{"line_number":468,"context_line":"                explanation\u003dencodeutils.exception_to_unicode(e))"}],"source_content_type":"text/x-python","patch_set":18,"id":"1fa4df85_0ffeb236","line":465,"range":{"start_line":465,"start_character":53,"end_line":465,"end_character":56},"in_reply_to":"1fa4df85_6611b9ac","updated":"2020-03-02 23:06:10.000000000","message":"me too","commit_id":"5a0609d4cd17cced77c1599ed91f2c39b4389723"},{"author":{"_account_id":11904,"name":"Sean McGinnis","email":"sean.mcginnis@gmail.com","username":"SeanM"},"change_message_id":"b66e4788947955b97d1f0773fe53a1d971c58f37","unresolved":false,"context_lines":[{"line_number":411,"context_line":"            image \u003d image_repo.get(image_id)"},{"line_number":412,"context_line":"        except exception.NotAuthenticated as e:"},{"line_number":413,"context_line":"            raise webob.exc.HTTPUnauthorized(explanation\u003de.msg)"},{"line_number":414,"context_line":"        except exception.NotFound as e:"},{"line_number":415,"context_line":"            msg \u003d (_(\"Failed to find image %(image_id)s\") %"},{"line_number":416,"context_line":"                   {\u0027image_id\u0027: image_id})"},{"line_number":417,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003dmsg)"}],"source_content_type":"text/x-python","patch_set":19,"id":"1fa4df85_cd9ec6b7","line":414,"range":{"start_line":414,"start_character":33,"end_line":414,"end_character":38},"updated":"2020-03-12 14:19:16.000000000","message":"Looks like e isn\u0027t used, so this could be removed.","commit_id":"85eebe3119aeac4508c2904aefa4ab35cb5edb9d"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"fdb40e740ecc253b3b35ec6c8353f54040af1fb3","unresolved":false,"context_lines":[{"line_number":411,"context_line":"            image \u003d image_repo.get(image_id)"},{"line_number":412,"context_line":"        except exception.NotAuthenticated as e:"},{"line_number":413,"context_line":"            raise webob.exc.HTTPUnauthorized(explanation\u003de.msg)"},{"line_number":414,"context_line":"        except exception.NotFound as e:"},{"line_number":415,"context_line":"            msg \u003d (_(\"Failed to find image %(image_id)s\") %"},{"line_number":416,"context_line":"                   {\u0027image_id\u0027: image_id})"},{"line_number":417,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003dmsg)"}],"source_content_type":"text/x-python","patch_set":19,"id":"1fa4df85_a6b91fea","line":414,"range":{"start_line":414,"start_character":33,"end_line":414,"end_character":38},"in_reply_to":"1fa4df85_cd9ec6b7","updated":"2020-03-13 08:13:37.000000000","message":"Done","commit_id":"85eebe3119aeac4508c2904aefa4ab35cb5edb9d"},{"author":{"_account_id":11904,"name":"Sean McGinnis","email":"sean.mcginnis@gmail.com","username":"SeanM"},"change_message_id":"b66e4788947955b97d1f0773fe53a1d971c58f37","unresolved":false,"context_lines":[{"line_number":452,"context_line":"                     \"because it is in use: %(exc)s\") %"},{"line_number":453,"context_line":"                   {\"id\": image_id,"},{"line_number":454,"context_line":"                    \"exc\": e.msg})"},{"line_number":455,"context_line":"            LOG.warn(msg)"},{"line_number":456,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":457,"context_line":"        except Exception as e:"},{"line_number":458,"context_line":"            raise webob.exc.HTTPInternalServerError("}],"source_content_type":"text/x-python","patch_set":19,"id":"1fa4df85_8df68ef9","line":455,"range":{"start_line":455,"start_character":16,"end_line":455,"end_character":20},"updated":"2020-03-12 14:19:16.000000000","message":"I\u0027d like to avoid adding warn() since with the python logging package that was deprecated ages ago. Oslo.logging still has it, so this works, but best to avoid so if and when that gets cleaned up from oslo.logging we don\u0027t have to fix it here.\n\nThat said, we have plenty of other instances of it in this repo, so we will need to do some cleanup anyway.","commit_id":"85eebe3119aeac4508c2904aefa4ab35cb5edb9d"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"fdb40e740ecc253b3b35ec6c8353f54040af1fb3","unresolved":false,"context_lines":[{"line_number":452,"context_line":"                     \"because it is in use: %(exc)s\") %"},{"line_number":453,"context_line":"                   {\"id\": image_id,"},{"line_number":454,"context_line":"                    \"exc\": e.msg})"},{"line_number":455,"context_line":"            LOG.warn(msg)"},{"line_number":456,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":457,"context_line":"        except Exception as e:"},{"line_number":458,"context_line":"            raise webob.exc.HTTPInternalServerError("}],"source_content_type":"text/x-python","patch_set":19,"id":"1fa4df85_46938b5d","line":455,"range":{"start_line":455,"start_character":16,"end_line":455,"end_character":20},"in_reply_to":"1fa4df85_8df68ef9","updated":"2020-03-13 08:13:37.000000000","message":"Done","commit_id":"85eebe3119aeac4508c2904aefa4ab35cb5edb9d"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"401ef50edb63185bfc894d386d13faeef94b385e","unresolved":false,"context_lines":[{"line_number":451,"context_line":"            msg \u003d (\"The data for Image %(id)s could not be deleted \""},{"line_number":452,"context_line":"                   \"because it is in use: %(exc)s\", {\"id\": image_id,"},{"line_number":453,"context_line":"                                                     \"exc\": e.msg})"},{"line_number":454,"context_line":"            LOG.warning(msg)"},{"line_number":455,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":456,"context_line":"        except Exception as e:"},{"line_number":457,"context_line":"            raise webob.exc.HTTPInternalServerError("}],"source_content_type":"text/x-python","patch_set":20,"id":"1fa4df85_3a8e9cd0","line":454,"range":{"start_line":454,"start_character":24,"end_line":454,"end_character":27},"updated":"2020-03-13 12:40:11.000000000","message":"see comment on line 74 of store_utils","commit_id":"1702a0a853ea0845091f70edb2c0b618838cd5a7"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"e72913536a00cdb85f03cce2139a1f0d6307669a","unresolved":false,"context_lines":[{"line_number":451,"context_line":"            msg \u003d (\"The data for Image %(id)s could not be deleted \""},{"line_number":452,"context_line":"                   \"because it is in use: %(exc)s\", {\"id\": image_id,"},{"line_number":453,"context_line":"                                                     \"exc\": e.msg})"},{"line_number":454,"context_line":"            LOG.warning(msg)"},{"line_number":455,"context_line":"            raise webob.exc.HTTPConflict(explanation\u003dmsg)"},{"line_number":456,"context_line":"        except Exception as e:"},{"line_number":457,"context_line":"            raise webob.exc.HTTPInternalServerError("}],"source_content_type":"text/x-python","patch_set":20,"id":"1fa4df85_59e125d0","line":454,"range":{"start_line":454,"start_character":24,"end_line":454,"end_character":27},"in_reply_to":"1fa4df85_3a8e9cd0","updated":"2020-03-13 14:47:23.000000000","message":"Done","commit_id":"1702a0a853ea0845091f70edb2c0b618838cd5a7"}],"glance/common/store_utils.py":[{"author":{"_account_id":11904,"name":"Sean McGinnis","email":"sean.mcginnis@gmail.com","username":"SeanM"},"change_message_id":"b66e4788947955b97d1f0773fe53a1d971c58f37","unresolved":false,"context_lines":[{"line_number":68,"context_line":"                                                   location[\u0027id\u0027], \u0027deleted\u0027)"},{"line_number":69,"context_line":"        return ret"},{"line_number":70,"context_line":"    except store_api.NotFound:"},{"line_number":71,"context_line":"        msg \u003d _(\"The image data for %(iid)s was not found in the store. \""},{"line_number":72,"context_line":"                \"The image record has been updated to reflect \""},{"line_number":73,"context_line":"                \"this.\") % {\u0027iid\u0027: image_id}"},{"line_number":74,"context_line":"        LOG.warn(msg)"}],"source_content_type":"text/x-python","patch_set":19,"id":"1fa4df85_add02a55","line":71,"range":{"start_line":71,"start_character":14,"end_line":71,"end_character":16},"updated":"2020-03-12 14:19:16.000000000","message":"Log only messages should not be translated.","commit_id":"85eebe3119aeac4508c2904aefa4ab35cb5edb9d"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"fdb40e740ecc253b3b35ec6c8353f54040af1fb3","unresolved":false,"context_lines":[{"line_number":68,"context_line":"                                                   location[\u0027id\u0027], \u0027deleted\u0027)"},{"line_number":69,"context_line":"        return ret"},{"line_number":70,"context_line":"    except store_api.NotFound:"},{"line_number":71,"context_line":"        msg \u003d _(\"The image data for %(iid)s was not found in the store. \""},{"line_number":72,"context_line":"                \"The image record has been updated to reflect \""},{"line_number":73,"context_line":"                \"this.\") % {\u0027iid\u0027: image_id}"},{"line_number":74,"context_line":"        LOG.warn(msg)"}],"source_content_type":"text/x-python","patch_set":19,"id":"1fa4df85_c6ba1be0","line":71,"range":{"start_line":71,"start_character":14,"end_line":71,"end_character":16},"in_reply_to":"1fa4df85_add02a55","updated":"2020-03-13 08:13:37.000000000","message":"Done","commit_id":"85eebe3119aeac4508c2904aefa4ab35cb5edb9d"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"9ee3c67a23e6ffd28f38a5bc1f57195242615641","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        msg \u003d (\"The image data for %(iid)s was not found in the store. \""},{"line_number":72,"context_line":"               \"The image record has been updated to reflect \""},{"line_number":73,"context_line":"               \"this.\", {\u0027iid\u0027: image_id})"},{"line_number":74,"context_line":"        LOG.warn(msg)"},{"line_number":75,"context_line":"    except store_api.StoreDeleteNotSupported as e:"},{"line_number":76,"context_line":"        LOG.warn(encodeutils.exception_to_unicode(e))"},{"line_number":77,"context_line":"    except store_api.UnsupportedBackend:"}],"source_content_type":"text/x-python","patch_set":20,"id":"1fa4df85_faf32472","line":74,"range":{"start_line":74,"start_character":17,"end_line":74,"end_character":20},"updated":"2020-03-13 12:38:09.000000000","message":"You\u0027re passing a tuple here as the first argument instead of a string.  I don\u0027t think it will cause an exception, but the message will look weird.\n\nThis will work if you unpack the tuple in the call:\n\n  LOG.warn(*msg)","commit_id":"1702a0a853ea0845091f70edb2c0b618838cd5a7"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"9bba7dc67cc877e810640c7e5b10d62e77a8d73e","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        msg \u003d (\"The image data for %(iid)s was not found in the store. \""},{"line_number":72,"context_line":"               \"The image record has been updated to reflect \""},{"line_number":73,"context_line":"               \"this.\", {\u0027iid\u0027: image_id})"},{"line_number":74,"context_line":"        LOG.warn(msg)"},{"line_number":75,"context_line":"    except store_api.StoreDeleteNotSupported as e:"},{"line_number":76,"context_line":"        LOG.warn(encodeutils.exception_to_unicode(e))"},{"line_number":77,"context_line":"    except store_api.UnsupportedBackend:"}],"source_content_type":"text/x-python","patch_set":20,"id":"1fa4df85_f397ca39","line":74,"range":{"start_line":74,"start_character":17,"end_line":74,"end_character":20},"in_reply_to":"1fa4df85_99c1dd31","updated":"2020-03-13 19:45:44.000000000","message":"I actually kind of like this pattern, defining the message as a tuple of (str, dict) and then using the * operator to unpack it when sending it to the log.  But that\u0027s an optimization you can make (or not) when you clean up that logging in a follow-up patch.  I don\u0027t want to hold this patch up.","commit_id":"1702a0a853ea0845091f70edb2c0b618838cd5a7"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"e72913536a00cdb85f03cce2139a1f0d6307669a","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        msg \u003d (\"The image data for %(iid)s was not found in the store. \""},{"line_number":72,"context_line":"               \"The image record has been updated to reflect \""},{"line_number":73,"context_line":"               \"this.\", {\u0027iid\u0027: image_id})"},{"line_number":74,"context_line":"        LOG.warn(msg)"},{"line_number":75,"context_line":"    except store_api.StoreDeleteNotSupported as e:"},{"line_number":76,"context_line":"        LOG.warn(encodeutils.exception_to_unicode(e))"},{"line_number":77,"context_line":"    except store_api.UnsupportedBackend:"}],"source_content_type":"text/x-python","patch_set":20,"id":"1fa4df85_99c1dd31","line":74,"range":{"start_line":74,"start_character":17,"end_line":74,"end_character":20},"in_reply_to":"1fa4df85_faf32472","updated":"2020-03-13 14:47:23.000000000","message":"Done","commit_id":"1702a0a853ea0845091f70edb2c0b618838cd5a7"}],"glance/location.py":[{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"3d28f7e74986a563868f9f960da46ddf633f1fdd","unresolved":false,"context_lines":[{"line_number":237,"context_line":"                        self.image_proxy,"},{"line_number":238,"context_line":"                        [location])"},{"line_number":239,"context_line":""},{"line_number":240,"context_line":"    def pop(self, i\u003d-1):"},{"line_number":241,"context_line":"        location \u003d self.value.pop(i)"},{"line_number":242,"context_line":"        try:"},{"line_number":243,"context_line":"            self.image_proxy.store_utils.delete_image_location_from_backend("},{"line_number":244,"context_line":"                self.image_proxy.context,"},{"line_number":245,"context_line":"                self.image_proxy.image.image_id,"},{"line_number":246,"context_line":"                location)"},{"line_number":247,"context_line":"        except Exception:"},{"line_number":248,"context_line":"            with excutils.save_and_reraise_exception():"},{"line_number":249,"context_line":"                self.value.insert(i, location)"},{"line_number":250,"context_line":"        return location"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"    def count(self, location):"},{"line_number":253,"context_line":"        return self.value.count(location)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3fa7e38b_e307971c","line":250,"range":{"start_line":240,"start_character":0,"end_line":250,"end_character":23},"updated":"2020-01-02 22:52:14.000000000","message":"I\u0027m worried about a race condition in this function.  The delete_image_location_from_backend() call will take some time, so if we get two DELETE /v2/stores/store_id/image_id close together, they could both hit this code because each of their image proxies will still have the location present in the list.  They hit here and the first one may succeed but the second could get a not found exception from glance_store, and then it will put the location back at line 249 and reraise the exception.\n\nIt may not be a problem as long as the location isn\u0027t saved back to the DB.  The delete_from_store() code on this patch looks like it would just raise a webob exception and not save, so that seems right, but I think we may need to reassess the exceptions that are being caught in delete_from_store() so that this case doesn\u0027t raise a 500.","commit_id":"f29a1997733aea5a4c791b01f4292804e0f33f90"},{"author":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"change_message_id":"c3fe0fe4e9c10dcc4117c4d5f7d607761386d1a1","unresolved":false,"context_lines":[{"line_number":237,"context_line":"                        self.image_proxy,"},{"line_number":238,"context_line":"                        [location])"},{"line_number":239,"context_line":""},{"line_number":240,"context_line":"    def pop(self, i\u003d-1):"},{"line_number":241,"context_line":"        location \u003d self.value.pop(i)"},{"line_number":242,"context_line":"        try:"},{"line_number":243,"context_line":"            self.image_proxy.store_utils.delete_image_location_from_backend("},{"line_number":244,"context_line":"                self.image_proxy.context,"},{"line_number":245,"context_line":"                self.image_proxy.image.image_id,"},{"line_number":246,"context_line":"                location)"},{"line_number":247,"context_line":"        except Exception:"},{"line_number":248,"context_line":"            with excutils.save_and_reraise_exception():"},{"line_number":249,"context_line":"                self.value.insert(i, location)"},{"line_number":250,"context_line":"        return location"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"    def count(self, location):"},{"line_number":253,"context_line":"        return self.value.count(location)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3fa7e38b_f2c43b96","line":250,"range":{"start_line":240,"start_character":0,"end_line":250,"end_character":23},"in_reply_to":"3fa7e38b_e307971c","updated":"2020-01-03 10:42:25.000000000","message":"What ever the end result is 500 is not the right response. I addressed that in the next PS by just passing on store NotFound which addresses both, the race case should one happen and it also addresses a case where say, the store is corrupt and there is no data anymore and we need to get rid of the records in the db.","commit_id":"f29a1997733aea5a4c791b01f4292804e0f33f90"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"5e3ea799ee391850904f43f2767694062114f761","unresolved":false,"context_lines":[{"line_number":249,"context_line":"            # half way there. As the expectation is that the data is not"},{"line_number":250,"context_line":"            # in the store at this point anyways, lets just return and"},{"line_number":251,"context_line":"            # pretend like we did it."},{"line_number":252,"context_line":"            return location"},{"line_number":253,"context_line":"        except Exception:"},{"line_number":254,"context_line":"            with excutils.save_and_reraise_exception():"},{"line_number":255,"context_line":"                self.value.insert(i, location)"}],"source_content_type":"text/x-python","patch_set":14,"id":"3fa7e38b_db9550e4","line":252,"updated":"2020-01-09 21:50:39.000000000","message":"I\u0027ll think about this some more, but this function is weird enough as it is without hiding this exception.  I think we should leave this code the way it is and handle the exception in the calling code.  (I think it will make debugging easier.)","commit_id":"0f2a4e10fc102285812ee7d4860be9218a515573"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"6c67f091f928dfc978da2c7f1ff497076a57412c","unresolved":false,"context_lines":[{"line_number":247,"context_line":"        except store.exceptions.NotFound:"},{"line_number":248,"context_line":"            # NOTE(jokke): If glance_store returns us NotFound, we\u0027re"},{"line_number":249,"context_line":"            # half way there. Lets pass the info to the caller but not"},{"line_number":250,"context_line":"            # insert the location back to the list."},{"line_number":251,"context_line":"            with excutils.save_and_reraise_exception():"},{"line_number":252,"context_line":"                pass"},{"line_number":253,"context_line":"        except Exception:"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_87cf4b27","line":250,"updated":"2020-01-14 14:32:03.000000000","message":"Let\u0027s revise the comment to be completely clear why we are doing this (and that we\u0027re doing it on purpose!).  Something like:\n\nNOTE(jokke): This can happen if the data was deleted by an operator from the backend, or a race condition from multiple delete-from-store requests.  The old way to deal with this was that the user could just delete the image when the data is gone, but with multi-store, that is no longer a good option.  So we intentionally leave the location popped (in other words, the pop() succeeds) but we also reraise the NotFound so that the calling code knows what happened.","commit_id":"3d6a97f6d4da6c4e209bdec016238533f1e920cf"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"70e1c73b3918437a55be8b03b3b7097c11f660f8","unresolved":false,"context_lines":[{"line_number":247,"context_line":"        except store.exceptions.NotFound:"},{"line_number":248,"context_line":"            # NOTE(jokke): If glance_store returns us NotFound, we\u0027re"},{"line_number":249,"context_line":"            # half way there. Lets pass the info to the caller but not"},{"line_number":250,"context_line":"            # insert the location back to the list."},{"line_number":251,"context_line":"            with excutils.save_and_reraise_exception():"},{"line_number":252,"context_line":"                pass"},{"line_number":253,"context_line":"        except Exception:"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_e787f110","line":250,"in_reply_to":"3fa7e38b_87cf4b27","updated":"2020-01-16 15:28:01.000000000","message":"+1","commit_id":"3d6a97f6d4da6c4e209bdec016238533f1e920cf"}],"releasenotes/notes/delete_from_store-a1d9b9bd5cf27546.yaml":[{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"6c67f091f928dfc978da2c7f1ff497076a57412c","unresolved":false,"context_lines":[{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    As part of the multi-store efforts this release introduces deletion from"},{"line_number":5,"context_line":"    single store. Through new \u0027/v2/stores\u0027 endpoint the API user can request"},{"line_number":6,"context_line":"    image to be deleted from single store instead of deleting the whole image."},{"line_number":7,"context_line":"    This feature can be used to clean up store metadata in cases where the"},{"line_number":8,"context_line":"    image data has for some reason disappeared from the store already, except"},{"line_number":9,"context_line":"    410 Gone HTTP response."}],"source_content_type":"text/x-yaml","patch_set":15,"id":"3fa7e38b_c2ba11df","line":6,"updated":"2020-01-14 14:32:03.000000000","message":"nit: \"image data\"","commit_id":"3d6a97f6d4da6c4e209bdec016238533f1e920cf"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"6c67f091f928dfc978da2c7f1ff497076a57412c","unresolved":false,"context_lines":[{"line_number":4,"context_line":"    As part of the multi-store efforts this release introduces deletion from"},{"line_number":5,"context_line":"    single store. Through new \u0027/v2/stores\u0027 endpoint the API user can request"},{"line_number":6,"context_line":"    image to be deleted from single store instead of deleting the whole image."},{"line_number":7,"context_line":"    This feature can be used to clean up store metadata in cases where the"},{"line_number":8,"context_line":"    image data has for some reason disappeared from the store already, except"},{"line_number":9,"context_line":"    410 Gone HTTP response."}],"source_content_type":"text/x-yaml","patch_set":15,"id":"3fa7e38b_42c7013f","line":9,"range":{"start_line":7,"start_character":4,"end_line":9,"end_character":27},"updated":"2020-01-14 14:32:03.000000000","message":"Maybe: This feature can be used to clean up store metadata in cases where the image data has been removed directly from a particular backend independently of Glance.  In this case, the request will return a HTTP 410 (Gone) response and the store will no longer appear in the ``stores`` list in the image-show response.","commit_id":"3d6a97f6d4da6c4e209bdec016238533f1e920cf"},{"author":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"change_message_id":"ac883a2a8f20d5023b32cc12e209544a31b68b2d","unresolved":false,"context_lines":[{"line_number":4,"context_line":"    As part of the multi-store efforts this release introduces deletion from"},{"line_number":5,"context_line":"    single store. Through new \u0027/v2/stores\u0027 endpoint the API user can request"},{"line_number":6,"context_line":"    image to be deleted from single store instead of deleting the whole image."},{"line_number":7,"context_line":"    This feature can be used to clean up store metadata in cases where the"},{"line_number":8,"context_line":"    image data has for some reason disappeared from the store already, except"},{"line_number":9,"context_line":"    410 Gone HTTP response."}],"source_content_type":"text/x-yaml","patch_set":15,"id":"3fa7e38b_8e3203f3","line":9,"range":{"start_line":7,"start_character":4,"end_line":9,"end_character":27},"in_reply_to":"3fa7e38b_42c7013f","updated":"2020-01-14 15:56:23.000000000","message":"I absolutely refuse to even hint that the expected usecase would be deliberate admin action rather than system failure like you make it sound.","commit_id":"3d6a97f6d4da6c4e209bdec016238533f1e920cf"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"70e1c73b3918437a55be8b03b3b7097c11f660f8","unresolved":false,"context_lines":[{"line_number":4,"context_line":"    As part of the multi-store efforts this release introduces deletion from"},{"line_number":5,"context_line":"    single store. Through new \u0027/v2/stores\u0027 endpoint the API user can request"},{"line_number":6,"context_line":"    image to be deleted from single store instead of deleting the whole image."},{"line_number":7,"context_line":"    This feature can be used to clean up store metadata in cases where the"},{"line_number":8,"context_line":"    image data has for some reason disappeared from the store already, except"},{"line_number":9,"context_line":"    410 Gone HTTP response."}],"source_content_type":"text/x-yaml","patch_set":15,"id":"3fa7e38b_c7d755f4","line":9,"range":{"start_line":7,"start_character":4,"end_line":9,"end_character":27},"in_reply_to":"3fa7e38b_4ea3ab9c","updated":"2020-01-16 15:28:01.000000000","message":"IMO original wording makes sense to me","commit_id":"3d6a97f6d4da6c4e209bdec016238533f1e920cf"},{"author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"change_message_id":"5feafd23668905d8186190a0b58d9b302d989325","unresolved":false,"context_lines":[{"line_number":4,"context_line":"    As part of the multi-store efforts this release introduces deletion from"},{"line_number":5,"context_line":"    single store. Through new \u0027/v2/stores\u0027 endpoint the API user can request"},{"line_number":6,"context_line":"    image to be deleted from single store instead of deleting the whole image."},{"line_number":7,"context_line":"    This feature can be used to clean up store metadata in cases where the"},{"line_number":8,"context_line":"    image data has for some reason disappeared from the store already, except"},{"line_number":9,"context_line":"    410 Gone HTTP response."}],"source_content_type":"text/x-yaml","patch_set":15,"id":"3fa7e38b_4ea3ab9c","line":9,"range":{"start_line":7,"start_character":4,"end_line":9,"end_character":27},"in_reply_to":"3fa7e38b_8e3203f3","updated":"2020-01-14 16:11:27.000000000","message":"I assume you\u0027re joking.\n\nIf the problem is system failure, then we absolutely should not be deleting the location because when recovery occurs, the data will be there but the reference to it in Glance will not.","commit_id":"3d6a97f6d4da6c4e209bdec016238533f1e920cf"}]}
