)]}'
{"doc/s3api/conf/ceph-known-failures-tempauth.yaml":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e02516d56f2a7deaabaae134148c937f6c8e2310","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":17,"id":"3fa7e38b_1b49d630","updated":"2019-11-21 00:20:35.000000000","message":"I think this conflict didn\u0027t get resolved correctly...","commit_id":"4de259a85e8acf5fa162b689aaca86c007f72863"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"6e35dbb7170e33137b460a94429b91504ce3cfa4","unresolved":false,"context_lines":[{"line_number":266,"context_line":"  s3tests_boto3.functional.test_s3.test_versioning_multi_object_delete_with_marker: {status: KNOWN}"},{"line_number":267,"context_line":"  s3tests_boto3.functional.test_s3.test_versioning_multi_object_delete_with_marker_create: {status: KNOWN}"},{"line_number":268,"context_line":"  s3tests_boto3.functional.test_s3.test_versioning_obj_create_read_remove_head: {status: KNOWN}"},{"line_number":269,"context_line":"  s3tests_boto3.functional.test_s3.test_versioning_obj_plain_null_version_overwrite: {status: KNOWN}"}],"source_content_type":"text/x-yaml","patch_set":30,"id":"3fa7e38b_c808f328","line":269,"range":{"start_line":269,"start_character":35,"end_line":269,"end_character":54},"updated":"2019-12-17 10:23:51.000000000","message":"why are these tests not \"removed\"? are they just not supported at this time? should we be adding support for them now? later?","commit_id":"48c8e1aca3b50f10b1d3375c572ce23fe73688ec"}],"swift/common/middleware/s3api/acl_handlers.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9150447d5a0a3acd7c7b70a1c5b1f1c8859aa068","unresolved":false,"context_lines":[{"line_number":228,"context_line":"        return self.req.get_acl_response(app, \u0027POST\u0027)"},{"line_number":229,"context_line":""},{"line_number":230,"context_line":""},{"line_number":231,"context_line":"class VersioningAclHandler(BucketAclHandler):"},{"line_number":232,"context_line":"    def POST(self, app):"},{"line_number":233,"context_line":"        return self._handle_acl(app, \u0027POST\u0027)"},{"line_number":234,"context_line":""}],"source_content_type":"text/x-python","patch_set":45,"id":"3fa7e38b_afcc2b62","line":231,"updated":"2020-01-22 13:35:41.000000000","message":"I\u0027m still scratching my head over this one -- backing it out (and the base_klass addition above) tests still seem to pass? I applied http://paste.openstack.org/show/788664/, running with s3_acl enabled","commit_id":"f64e3452f5b27d9a628755af272647801894220e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9150447d5a0a3acd7c7b70a1c5b1f1c8859aa068","unresolved":false,"context_lines":[{"line_number":474,"context_line":"    # Versioning"},{"line_number":475,"context_line":"    (\u0027PUT\u0027, \u0027POST\u0027, \u0027container\u0027):"},{"line_number":476,"context_line":"    {\u0027Permission\u0027: \u0027WRITE\u0027},"},{"line_number":477,"context_line":"    (\u0027DELETE\u0027, \u0027POST\u0027, \u0027container\u0027):"},{"line_number":478,"context_line":"    {\u0027Permission\u0027: \u0027WRITE\u0027},"},{"line_number":479,"context_line":"    (\u0027DELETE\u0027, \u0027GET\u0027, \u0027container\u0027):"},{"line_number":480,"context_line":"    {\u0027Permission\u0027: \u0027READ\u0027},"},{"line_number":481,"context_line":"    (\u0027DELETE\u0027, \u0027GET\u0027, \u0027object\u0027):"},{"line_number":482,"context_line":"    {\u0027Permission\u0027: \u0027READ\u0027},"},{"line_number":483,"context_line":"}"}],"source_content_type":"text/x-python","patch_set":45,"id":"3fa7e38b_5a145342","line":482,"range":{"start_line":477,"start_character":4,"end_line":482,"end_character":27},"updated":"2020-01-22 13:35:41.000000000","message":"Are these necessary/correct? I seemed to have clean func and s3api tests after something like\n\ndiff --git a/swift/common/middleware/s3api/acl_handlers.py b/swift/common/middleware/s3api/acl_handlers.py\nindex c717f1801..5dca09b46 100644\n--- a/swift/common/middleware/s3api/acl_handlers.py\n+++ b/swift/common/middleware/s3api/acl_handlers.py\n@@ -468,10 +468,10 @@ ACL_MAP \u003d {\n     # Versioning\n     (\u0027PUT\u0027, \u0027POST\u0027, \u0027container\u0027):\n     {\u0027Permission\u0027: \u0027WRITE\u0027},\n-    (\u0027DELETE\u0027, \u0027POST\u0027, \u0027container\u0027):\n-    {\u0027Permission\u0027: \u0027WRITE\u0027},\n     (\u0027DELETE\u0027, \u0027GET\u0027, \u0027container\u0027):\n-    {\u0027Permission\u0027: \u0027READ\u0027},\n-    (\u0027DELETE\u0027, \u0027GET\u0027, \u0027object\u0027):\n-    {\u0027Permission\u0027: \u0027READ\u0027},\n+    {\u0027Permission\u0027: \u0027WRITE\u0027},\n }\n\nI would\u0027a kind\u0027a expected that anything involving a DELETE should require WRITE access...\n\nAnd really, I\u0027m not even clear on where the new GET is coming from -- but dropping that *does* cause failures...","commit_id":"f64e3452f5b27d9a628755af272647801894220e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"54c4cf41440a91e483e2737c511ec2a6bd9a22a1","unresolved":false,"context_lines":[{"line_number":228,"context_line":"        return self.req.get_acl_response(app, \u0027POST\u0027)"},{"line_number":229,"context_line":""},{"line_number":230,"context_line":""},{"line_number":231,"context_line":"class VersioningAclHandler(BucketAclHandler):"},{"line_number":232,"context_line":"    def POST(self, app):"},{"line_number":233,"context_line":"        return self._handle_acl(app, \u0027POST\u0027)"},{"line_number":234,"context_line":""}],"source_content_type":"text/x-python","patch_set":46,"id":"3fa7e38b_1f055868","line":231,"updated":"2020-01-23 05:55:49.000000000","message":"Oh -- I thought I\u0027d deleted this :-/","commit_id":"021a81ea6aaa4b0dede315f66b1b52dcef75b699"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"42afe5f7eb6242d7e293d039781d20c9ab9123de","unresolved":false,"context_lines":[{"line_number":228,"context_line":"        return self.req.get_acl_response(app, \u0027POST\u0027)"},{"line_number":229,"context_line":""},{"line_number":230,"context_line":""},{"line_number":231,"context_line":"class VersioningAclHandler(BucketAclHandler):"},{"line_number":232,"context_line":"    def POST(self, app):"},{"line_number":233,"context_line":"        return self._handle_acl(app, \u0027POST\u0027)"},{"line_number":234,"context_line":""}],"source_content_type":"text/x-python","patch_set":46,"id":"3fa7e38b_a2f5f2cd","line":231,"in_reply_to":"3fa7e38b_1f055868","updated":"2020-01-24 19:03:14.000000000","message":"Done","commit_id":"021a81ea6aaa4b0dede315f66b1b52dcef75b699"}],"swift/common/middleware/s3api/controllers/bucket.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3ba60134e6f3b579c4b35c94dbe09c30dd8dbbf4","unresolved":false,"context_lines":[{"line_number":357,"context_line":""},{"line_number":358,"context_line":"    def _add_objects_to_result(self, req, elem, objects, encoding_type,"},{"line_number":359,"context_line":"                               listing_type, fetch_owner):"},{"line_number":360,"context_line":"        for o in objects:"},{"line_number":361,"context_line":"            if \u0027subdir\u0027 in o:"},{"line_number":362,"context_line":"                self._add_subdir(elem, o, encoding_type)"},{"line_number":363,"context_line":"            else:"},{"line_number":364,"context_line":"                self._add_object(req, elem, o, encoding_type, listing_type,"},{"line_number":365,"context_line":"                                 fetch_owner)"},{"line_number":366,"context_line":""},{"line_number":367,"context_line":"    @public"},{"line_number":368,"context_line":"    def GET(self, req):"}],"source_content_type":"text/x-python","patch_set":2,"id":"5faad753_5f8e1328","line":365,"range":{"start_line":360,"start_character":8,"end_line":365,"end_character":45},"updated":"2019-09-06 06:04:55.000000000","message":"Hmm. This is a definite change from before -- we used to consciously do two passes, more like\n\n for o in objects:\n     if \u0027subdir\u0027 not in o:\n         self._add_object(...)\n for o in objects:\n     if \u0027subdir\u0027 in o:\n         self._add_subdir(...)\n\n\nWas this intentional? What does AWS do?\n\nFWIW, docs have some examples like https://docs.aws.amazon.com/AmazonS3/latest/API/v2-RESTBucketGET.html#v2-RESTBucketGET-responses-examples-ex3 but they don\u0027t quite seem clear on the matter... At least they confirm we should have\n\n  \u003cCommonPrefixes\u003e\n    \u003cPrefix\u003ephotos/2006/February/\u003c/Prefix\u003e\n  \u003c/CommonPrefixes\u003e\n  \u003cCommonPrefixes\u003e\n    \u003cPrefix\u003ephotos/2006/January/\u003c/Prefix\u003e\n  \u003c/CommonPrefixes\u003e\n\ninstead of\n\n  \u003cCommonPrefixes\u003e\n    \u003cPrefix\u003ephotos/2006/February/\u003c/Prefix\u003e\n    \u003cPrefix\u003ephotos/2006/January/\u003c/Prefix\u003e\n  \u003c/CommonPrefixes\u003e\n\nthough. Good news is, awscli (and therefore boto3) seems happy to eat either; they seem to have their own opinions about how to order such things.","commit_id":"b3f4e0e13d5e855db4f46a1741da388360734af9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"c1663ac8c653ce79ddb941a1a499d930769c9fa4","unresolved":false,"context_lines":[{"line_number":357,"context_line":""},{"line_number":358,"context_line":"    def _add_objects_to_result(self, req, elem, objects, encoding_type,"},{"line_number":359,"context_line":"                               listing_type, fetch_owner):"},{"line_number":360,"context_line":"        for o in objects:"},{"line_number":361,"context_line":"            if \u0027subdir\u0027 in o:"},{"line_number":362,"context_line":"                self._add_subdir(elem, o, encoding_type)"},{"line_number":363,"context_line":"            else:"},{"line_number":364,"context_line":"                self._add_object(req, elem, o, encoding_type, listing_type,"},{"line_number":365,"context_line":"                                 fetch_owner)"},{"line_number":366,"context_line":""},{"line_number":367,"context_line":"    @public"},{"line_number":368,"context_line":"    def GET(self, req):"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_1d75d995","line":365,"range":{"start_line":360,"start_character":8,"end_line":365,"end_character":45},"in_reply_to":"5faad753_5f8e1328","updated":"2019-09-18 18:03:28.000000000","message":"I don\u0027t understand the difference.  Are you saying you\u0027re sure that the same objects in the listing would produce a different response on aws/old-code and the new code wrong/bad?  Would it be possible to demonstrate this with a failing test?","commit_id":"b3f4e0e13d5e855db4f46a1741da388360734af9"}],"swift/common/middleware/s3api/controllers/multi_delete.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"262bbc5f18e5f1558471b6b5920bcbe866d11940","unresolved":false,"context_lines":[{"line_number":111,"context_line":"            \u0027X-Container-Sysmeta-Versions-Location\u0027,"},{"line_number":112,"context_line":"            req.container_name + VERSIONING_SUFFIX)"},{"line_number":113,"context_line":"        if any(o[1] for o in delete_list) and not version_target_bucket:"},{"line_number":114,"context_line":"            # TODO: how to express versioning suspended multi-delete response??"},{"line_number":115,"context_line":"            pass"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"        symlink_key_cache \u003d {}"}],"source_content_type":"text/x-python","patch_set":2,"id":"5faad753_ba44f5b8","line":114,"updated":"2019-11-16 22:18:22.000000000","message":"I\u0027d expect that multidelete should work very very similarly to a bunch of client-deletes... though I suppose with the concurrency factor, deleting both the current version *and* the prior one gets messy...\n\nRegardless of that, though, I think suspended-versioning is a red herring -- even with it suspended, you need to be able to clear out old versions, and the way to do that is the version-aware delete. Whether that\u0027s a single delete or a multidelete shouldn\u0027t matter.\n\nOne thing that *is* worth mentioning, though, is that I\u0027m pretty sure we need to be sure to differentiate between\n\n version \u003d\u003d None\n version \u003d\u003d \u0027null\u0027\n version \u003d\u003d \u003csome timestamp\u003e","commit_id":"b3f4e0e13d5e855db4f46a1741da388360734af9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f7deeeac77e0bd7a9ac5bb563f16664bc5c7ec7d","unresolved":false,"context_lines":[{"line_number":37,"context_line":"        for key, version in delete_list:"},{"line_number":38,"context_line":"            if version is not None:"},{"line_number":39,"context_line":"                # TODO: how to return versionId on bucket does not exist error?"},{"line_number":40,"context_line":"                raise S3NotImplemented()"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"            error_elem \u003d SubElement(elem, \u0027Error\u0027)"},{"line_number":43,"context_line":"            SubElement(error_elem, \u0027Key\u0027).text \u003d key"}],"source_content_type":"text/x-python","patch_set":28,"id":"3fa7e38b_4f8b3e68","line":40,"updated":"2019-12-06 19:12:15.000000000","message":"Hmm... pretty sure we want something like\n\n if version is not None:\n     SubElement(error_elem, \u0027VersionId\u0027).text \u003d version\n\ndown below.","commit_id":"eefd4aada4dba21f8b3a1d7306277d718bef6805"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"6e35dbb7170e33137b460a94429b91504ce3cfa4","unresolved":false,"context_lines":[{"line_number":113,"context_line":"            req.environ \u003d copy.copy(base_req.environ)"},{"line_number":114,"context_line":"            req.object_name \u003d key"},{"line_number":115,"context_line":"            if version:"},{"line_number":116,"context_line":"                req.params \u003d {\u0027version-id\u0027: version, \u0027symlink\u0027: \u0027get\u0027}"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"            try:"},{"line_number":119,"context_line":"                try:"}],"source_content_type":"text/x-python","patch_set":30,"id":"3fa7e38b_a8d7b722","line":116,"range":{"start_line":116,"start_character":44,"end_line":116,"end_character":51},"updated":"2019-12-17 10:23:51.000000000","message":"version should always be `null` correct?","commit_id":"48c8e1aca3b50f10b1d3375c572ce23fe73688ec"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"6e35dbb7170e33137b460a94429b91504ce3cfa4","unresolved":false,"context_lines":[{"line_number":113,"context_line":"            req.environ \u003d copy.copy(base_req.environ)"},{"line_number":114,"context_line":"            req.object_name \u003d key"},{"line_number":115,"context_line":"            if version:"},{"line_number":116,"context_line":"                req.params \u003d {\u0027version-id\u0027: version, \u0027symlink\u0027: \u0027get\u0027}"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"            try:"},{"line_number":119,"context_line":"                try:"}],"source_content_type":"text/x-python","patch_set":30,"id":"3fa7e38b_08d36b39","line":116,"range":{"start_line":116,"start_character":53,"end_line":116,"end_character":69},"updated":"2019-12-17 10:23:51.000000000","message":"why is the symlink\u003dget needed here? I\u0027ve noticed this pattern is repeated for DELETE requests throughout the patch, but I\u0027m not sure I understand the reason yet, neither object_versioning or symlink middleware seem to treat delete requets differently with `symlink\u003dget`, what am i missing?","commit_id":"48c8e1aca3b50f10b1d3375c572ce23fe73688ec"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9150447d5a0a3acd7c7b70a1c5b1f1c8859aa068","unresolved":false,"context_lines":[{"line_number":118,"context_line":"            try:"},{"line_number":119,"context_line":"                try:"},{"line_number":120,"context_line":"                    query \u003d req.gen_multipart_manifest_delete_query("},{"line_number":121,"context_line":"                        self.app, version\u003dversion)"},{"line_number":122,"context_line":"                except NoSuchKey:"},{"line_number":123,"context_line":"                    query \u003d {}"},{"line_number":124,"context_line":"                if version:"}],"source_content_type":"text/x-python","patch_set":45,"id":"3fa7e38b_da1fe308","line":121,"updated":"2020-01-22 13:35:41.000000000","message":"Note to self: check behavior of version-aware vs version-unaware DELETEs against MPUs...","commit_id":"f64e3452f5b27d9a628755af272647801894220e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9150447d5a0a3acd7c7b70a1c5b1f1c8859aa068","unresolved":false,"context_lines":[{"line_number":153,"context_line":"                pass"},{"line_number":154,"context_line":"            except ErrorResponse as e:"},{"line_number":155,"context_line":"                return key, {\u0027code\u0027: e.__class__.__name__, \u0027message\u0027: e._msg}"},{"line_number":156,"context_line":"            except Exception:"},{"line_number":157,"context_line":"                self.logger.exception("},{"line_number":158,"context_line":"                    \u0027Unexpected Error handling DELETE of %r %r\u0027 % ("},{"line_number":159,"context_line":"                        req.container_name, key))"}],"source_content_type":"text/x-python","patch_set":45,"id":"3fa7e38b_badf8736","line":156,"updated":"2020-01-22 13:35:41.000000000","message":"Really makes me wonder what could trip this... and what *did* trip this that made us add it.","commit_id":"f64e3452f5b27d9a628755af272647801894220e"}],"swift/common/middleware/s3api/controllers/obj.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3ba60134e6f3b579c4b35c94dbe09c30dd8dbbf4","unresolved":false,"context_lines":[{"line_number":186,"context_line":"                # if the object is already marked as deleted, just delete it"},{"line_number":187,"context_line":"                resp \u003d req.get_response(self.app, query\u003dquery)"},{"line_number":188,"context_line":"            else:"},{"line_number":189,"context_line":"                self.logger.info(\"we know what we\u0027re doing\")"},{"line_number":190,"context_line":"                resp \u003d req.get_response(self.app, query\u003dquery, headers\u003d{"},{"line_number":191,"context_line":"                    \u0027X-Backend-Versioning-Mode-Override\u0027: \u0027stack\u0027})"},{"line_number":192,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_82b864c7","line":189,"range":{"start_line":189,"start_character":34,"end_line":189,"end_character":58},"updated":"2019-09-06 06:04:55.000000000","message":"Well *that* seems optimistic ;-)","commit_id":"b3f4e0e13d5e855db4f46a1741da388360734af9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"c1663ac8c653ce79ddb941a1a499d930769c9fa4","unresolved":false,"context_lines":[{"line_number":186,"context_line":"                # if the object is already marked as deleted, just delete it"},{"line_number":187,"context_line":"                resp \u003d req.get_response(self.app, query\u003dquery)"},{"line_number":188,"context_line":"            else:"},{"line_number":189,"context_line":"                self.logger.info(\"we know what we\u0027re doing\")"},{"line_number":190,"context_line":"                resp \u003d req.get_response(self.app, query\u003dquery, headers\u003d{"},{"line_number":191,"context_line":"                    \u0027X-Backend-Versioning-Mode-Override\u0027: \u0027stack\u0027})"},{"line_number":192,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_1d839955","line":189,"range":{"start_line":189,"start_character":34,"end_line":189,"end_character":58},"in_reply_to":"7faddb67_82b864c7","updated":"2019-09-18 18:03:28.000000000","message":"HAHAH!  this was probably 13-14 debug lines in while I trying to trace code failing a functional test\n\nI\u0027ve since found that once I have the s3 tests passing it\u0027s easier to re-write them as unittests before I start trying to develop equivalent s3api features.","commit_id":"b3f4e0e13d5e855db4f46a1741da388360734af9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f56e9fa493c9b3a306cdbcc0b428e87824e581c9","unresolved":false,"context_lines":[{"line_number":166,"context_line":"                query[\u0027version-id\u0027] \u003d req.params[\u0027versionId\u0027]"},{"line_number":167,"context_line":"                query[\u0027symlink\u0027] \u003d \u0027get\u0027"},{"line_number":168,"context_line":""},{"line_number":169,"context_line":"            resp \u003d req.get_response(self.app, query\u003dquery)"},{"line_number":170,"context_line":"            if query.get(\u0027multipart-manifest\u0027) and resp.status_int \u003d\u003d HTTP_OK:"},{"line_number":171,"context_line":"                for chunk in resp.app_iter:"},{"line_number":172,"context_line":"                    pass  # drain the bulk-deleter response"}],"source_content_type":"text/x-python","patch_set":14,"id":"3fa7e38b_783a6298","line":169,"updated":"2019-11-19 20:32:23.000000000","message":"If there was someway to tell if resp had just removed the current version (i.e. wrote a tombstone over the is_latest link) it would reasonable here to do a listing and a PUT?version-id\u003d\u003cversion-at-top-of-stack\u003e","commit_id":"ece155a09d6b2fe7024c5377e4891a174aacd2e3"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"6e35dbb7170e33137b460a94429b91504ce3cfa4","unresolved":false,"context_lines":[{"line_number":184,"context_line":"        return resp"},{"line_number":185,"context_line":""},{"line_number":186,"context_line":"    @public"},{"line_number":187,"context_line":"    def DELETE(self, req):"},{"line_number":188,"context_line":"        \"\"\""},{"line_number":189,"context_line":"        Handle DELETE Object request"},{"line_number":190,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":30,"id":"3fa7e38b_d1f2da05","line":187,"updated":"2019-12-17 10:23:51.000000000","message":"I noticed the DELETE response is currently missing a body similar to s3, for example:\n\n  $ aws s3api delete-object --bucket s3api-td-policies --key hw\n  {\n      \"VersionId\": \"X5.Bhu79SQvesOwYDRtoNRsJgL6lTNmr\", \n      \"DeleteMarker\": true\n  }\n\n  $ aws s3api delete-object --bucket td-s3api-test --key hw --version-id null\n  {\n      \"VersionId\": \"null\"\n  }","commit_id":"48c8e1aca3b50f10b1d3375c572ce23fe73688ec"}],"swift/common/middleware/s3api/controllers/versioning.py":[{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"6e35dbb7170e33137b460a94429b91504ce3cfa4","unresolved":false,"context_lines":[{"line_number":82,"context_line":"            req.headers[\u0027X-Versions-Enabled\u0027] \u003d \u0027true\u0027"},{"line_number":83,"context_line":"        else:"},{"line_number":84,"context_line":"            req.headers[\u0027X-Versions-Enabled\u0027] \u003d \u0027false\u0027"},{"line_number":85,"context_line":"        # Set the container back to what it originally was"},{"line_number":86,"context_line":"        req.get_response(self.app, \u0027POST\u0027)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        return HTTPOk()"}],"source_content_type":"text/x-python","patch_set":30,"id":"3fa7e38b_e8b28fe8","line":85,"range":{"start_line":85,"start_character":10,"end_line":85,"end_character":58},"updated":"2019-12-17 10:23:51.000000000","message":"not sure I understand this comment","commit_id":"48c8e1aca3b50f10b1d3375c572ce23fe73688ec"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9150447d5a0a3acd7c7b70a1c5b1f1c8859aa068","unresolved":false,"context_lines":[{"line_number":46,"context_line":"            \u0027True\u0027: \u0027Enabled\u0027,"},{"line_number":47,"context_line":"            \u0027False\u0027: \u0027Suspended\u0027,"},{"line_number":48,"context_line":"            None: None,"},{"line_number":49,"context_line":"        }[sysmeta.get(\u0027versions-enabled\u0027)]"},{"line_number":50,"context_line":"        elem \u003d Element(\u0027VersioningConfiguration\u0027)"},{"line_number":51,"context_line":"        if status:"},{"line_number":52,"context_line":"            SubElement(elem, \u0027Status\u0027).text \u003d status"}],"source_content_type":"text/x-python","patch_set":45,"id":"3fa7e38b_95aa9cd0","line":49,"range":{"start_line":49,"start_character":9,"end_line":49,"end_character":10},"updated":"2020-01-22 13:35:41.000000000","message":"Makes me a little nervous about KeyErrors, though I suppose it ought to be fine... Maybe more obvious like\n\n elem \u003d ...\n if sysmeta.get(\u0027versions-enabled\u0027):\n     SubElement(elem, \u0027Status\u0027).text \u003d (\n         \u0027Enabled\u0027 if config_true_value(sysmeta[\u0027versions-enabled\u0027])\n         else \u0027Suspended\u0027)\n body \u003d ...\n\nthough?","commit_id":"f64e3452f5b27d9a628755af272647801894220e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"54c4cf41440a91e483e2737c511ec2a6bd9a22a1","unresolved":false,"context_lines":[{"line_number":46,"context_line":"            \u0027True\u0027: \u0027Enabled\u0027,"},{"line_number":47,"context_line":"            \u0027False\u0027: \u0027Suspended\u0027,"},{"line_number":48,"context_line":"            None: None,"},{"line_number":49,"context_line":"        }[sysmeta.get(\u0027versions-enabled\u0027)]"},{"line_number":50,"context_line":"        elem \u003d Element(\u0027VersioningConfiguration\u0027)"},{"line_number":51,"context_line":"        if status:"},{"line_number":52,"context_line":"            SubElement(elem, \u0027Status\u0027).text \u003d status"}],"source_content_type":"text/x-python","patch_set":45,"id":"3fa7e38b_3f0a9477","line":49,"range":{"start_line":49,"start_character":9,"end_line":49,"end_character":10},"in_reply_to":"3fa7e38b_95aa9cd0","updated":"2020-01-23 05:55:49.000000000","message":"Done","commit_id":"f64e3452f5b27d9a628755af272647801894220e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9150447d5a0a3acd7c7b70a1c5b1f1c8859aa068","unresolved":false,"context_lines":[{"line_number":82,"context_line":"            req.headers[\u0027X-Versions-Enabled\u0027] \u003d \u0027true\u0027"},{"line_number":83,"context_line":"        else:"},{"line_number":84,"context_line":"            req.headers[\u0027X-Versions-Enabled\u0027] \u003d \u0027false\u0027"},{"line_number":85,"context_line":"        # Set the container back to what it originally was"},{"line_number":86,"context_line":"        req.get_response(self.app, \u0027POST\u0027)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        return HTTPOk()"}],"source_content_type":"text/x-python","patch_set":45,"id":"3fa7e38b_3538889d","line":85,"range":{"start_line":85,"start_character":8,"end_line":85,"end_character":58},"updated":"2020-01-22 13:35:41.000000000","message":"I\u0027m not sure what this comment is trying to say...","commit_id":"f64e3452f5b27d9a628755af272647801894220e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"54c4cf41440a91e483e2737c511ec2a6bd9a22a1","unresolved":false,"context_lines":[{"line_number":82,"context_line":"            req.headers[\u0027X-Versions-Enabled\u0027] \u003d \u0027true\u0027"},{"line_number":83,"context_line":"        else:"},{"line_number":84,"context_line":"            req.headers[\u0027X-Versions-Enabled\u0027] \u003d \u0027false\u0027"},{"line_number":85,"context_line":"        # Set the container back to what it originally was"},{"line_number":86,"context_line":"        req.get_response(self.app, \u0027POST\u0027)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        return HTTPOk()"}],"source_content_type":"text/x-python","patch_set":45,"id":"3fa7e38b_df226002","line":85,"range":{"start_line":85,"start_character":8,"end_line":85,"end_character":58},"in_reply_to":"3fa7e38b_3538889d","updated":"2020-01-23 05:55:49.000000000","message":"Done","commit_id":"f64e3452f5b27d9a628755af272647801894220e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"54c4cf41440a91e483e2737c511ec2a6bd9a22a1","unresolved":false,"context_lines":[{"line_number":75,"context_line":""},{"line_number":76,"context_line":"        # Set up versioning"},{"line_number":77,"context_line":"        # NB: object_versioning responsible for ensuring its container exists"},{"line_number":78,"context_line":"        req.headers[\u0027X-Versions-Enabled\u0027] \u003d str(status \u003d\u003d \u0027Enabled\u0027).lower()"},{"line_number":79,"context_line":"        req.get_response(self.app, \u0027POST\u0027)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"        return HTTPOk()"}],"source_content_type":"text/x-python","patch_set":46,"id":"3fa7e38b_ff1f1cb5","line":78,"range":{"start_line":78,"start_character":69,"end_line":78,"end_character":76},"updated":"2020-01-23 05:55:49.000000000","message":"Or we could drop the .lower() and update some tests. *shrug*","commit_id":"021a81ea6aaa4b0dede315f66b1b52dcef75b699"}],"swift/common/middleware/s3api/s3request.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"262bbc5f18e5f1558471b6b5920bcbe866d11940","unresolved":false,"context_lines":[{"line_number":892,"context_line":"            elif query[0][0] \u003d\u003d \u0027versionId\u0027:"},{"line_number":893,"context_line":"                version_id \u003d query[0][1]"},{"line_number":894,"context_line":"            else:"},{"line_number":895,"context_line":"                # XXX Not sure if this is reachable/valid request?"},{"line_number":896,"context_line":"                raise S3NotImplemented(\u0027%s is not supported\u0027 % query[0][0])"},{"line_number":897,"context_line":"            self.headers[\u0027X-Amz-Copy-Source\u0027] \u003d src_path"},{"line_number":898,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"5faad753_1c5f3b42","line":895,"updated":"2019-11-16 22:18:22.000000000","message":"No, definitely not reachable. First block covers no query params, second block covers more than one query param *and* one query param but not versionId. Only case left is one query param that is versionId. Maybe it\u0027ll be more clear as something like\n\n if not query:\n     version_id \u003d None\n elif len(query) \u003d\u003d 1 and query[0][0] \u003d\u003d \u0027versionId\u0027:\n     version_id \u003d query[0][1]\n else:\n     raise InvalidArgument(...)\n\n(ie, make it so the catch-all raises the exception)","commit_id":"b3f4e0e13d5e855db4f46a1741da388360734af9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"cf76c5c950611eaa0e633b8a639372247f4d88a6","unresolved":false,"context_lines":[{"line_number":1278,"context_line":"                    if \u0027swift.infocache\u0027 in env:"},{"line_number":1279,"context_line":"                        # cause, why not!?"},{"line_number":1280,"context_line":"                        self.environ[\u0027swift.infocache\u0027] \u003d \\"},{"line_number":1281,"context_line":"                            env[\u0027swift.infocache\u0027]"},{"line_number":1282,"context_line":"                    return NoSuchKey(obj)"},{"line_number":1283,"context_line":"                return NoSuchBucket(container)"},{"line_number":1284,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"3fa7e38b_3a1265fe","line":1281,"updated":"2019-11-22 23:03:15.000000000","message":"Why aren\u0027t these already the same thing? Presumably because we go make env manually somewhere -- could we do soemthing like\n\n env[\u0027swift.info_cache\u0027] \u003d self.environ.setdefault(\u0027swift.info_cache\u0027, {})\n\nthere instead?","commit_id":"b30120fac78cf614d8425e1caf714ec4ab0fcdf9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"eda785ace6feb91622f798645173b4c13c0fe6aa","unresolved":false,"context_lines":[{"line_number":1278,"context_line":"                    if \u0027swift.infocache\u0027 in env:"},{"line_number":1279,"context_line":"                        # cause, why not!?"},{"line_number":1280,"context_line":"                        self.environ[\u0027swift.infocache\u0027] \u003d \\"},{"line_number":1281,"context_line":"                            env[\u0027swift.infocache\u0027]"},{"line_number":1282,"context_line":"                    return NoSuchKey(obj)"},{"line_number":1283,"context_line":"                return NoSuchBucket(container)"},{"line_number":1284,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"3fa7e38b_cc17d145","line":1281,"in_reply_to":"3fa7e38b_3a1265fe","updated":"2019-11-26 14:03:35.000000000","message":"yes, the env was being copied in to_swift_req, presumably self.environ.infocache wasn\u0027t yet populated because we hadn\u0027t made any get_info requests yet...\n\nBut your suggestion worked great, and looks more robust to me!","commit_id":"b30120fac78cf614d8425e1caf714ec4ab0fcdf9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9150447d5a0a3acd7c7b70a1c5b1f1c8859aa068","unresolved":false,"context_lines":[{"line_number":889,"context_line":"            elif query[0][1] !\u003d \u0027null\u0027:"},{"line_number":890,"context_line":"                # TODO: once we support versioning, we\u0027ll need to translate"},{"line_number":891,"context_line":"                # src_path to the proper location in the versions container"},{"line_number":892,"context_line":"                raise S3NotImplemented(\u0027Versioning is not yet supported\u0027)"},{"line_number":893,"context_line":"            self.headers[\u0027X-Amz-Copy-Source\u0027] \u003d src_path"},{"line_number":894,"context_line":""},{"line_number":895,"context_line":"        src_path \u003d unquote(src_path)"}],"source_content_type":"text/x-python","patch_set":45,"id":"3fa7e38b_c1aa93d1","side":"PARENT","line":892,"range":{"start_line":892,"start_character":16,"end_line":892,"end_character":73},"updated":"2020-01-22 13:35:41.000000000","message":"Makes me think I may not have been thorough enough in trying to support *not* having object_versioning available...","commit_id":"9c728e9984aad9c53a71de1998cac781fda55ab1"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9150447d5a0a3acd7c7b70a1c5b1f1c8859aa068","unresolved":false,"context_lines":[{"line_number":883,"context_line":"            # version_id \u003d None"},{"line_number":884,"context_line":"            query \u003d {}"},{"line_number":885,"context_line":"        elif len(parsed) \u003d\u003d 1 and parsed[0][0] \u003d\u003d \u0027versionId\u0027:"},{"line_number":886,"context_line":"            # version_id \u003d parsed[0][1]"},{"line_number":887,"context_line":"            query \u003d {\u0027version-id\u0027: parsed[0][1]}"},{"line_number":888,"context_line":"        else:"},{"line_number":889,"context_line":"            raise InvalidArgument(\u0027X-Amz-Copy-Source\u0027,"}],"source_content_type":"text/x-python","patch_set":45,"id":"3fa7e38b_e1346fe1","line":886,"range":{"start_line":886,"start_character":12,"end_line":886,"end_character":39},"updated":"2020-01-22 13:35:41.000000000","message":"I think these version_id comments were left over from a prior patchset...","commit_id":"f64e3452f5b27d9a628755af272647801894220e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"54c4cf41440a91e483e2737c511ec2a6bd9a22a1","unresolved":false,"context_lines":[{"line_number":883,"context_line":"            # version_id \u003d None"},{"line_number":884,"context_line":"            query \u003d {}"},{"line_number":885,"context_line":"        elif len(parsed) \u003d\u003d 1 and parsed[0][0] \u003d\u003d \u0027versionId\u0027:"},{"line_number":886,"context_line":"            # version_id \u003d parsed[0][1]"},{"line_number":887,"context_line":"            query \u003d {\u0027version-id\u0027: parsed[0][1]}"},{"line_number":888,"context_line":"        else:"},{"line_number":889,"context_line":"            raise InvalidArgument(\u0027X-Amz-Copy-Source\u0027,"}],"source_content_type":"text/x-python","patch_set":45,"id":"3fa7e38b_9f1868ce","line":886,"range":{"start_line":886,"start_character":12,"end_line":886,"end_character":39},"in_reply_to":"3fa7e38b_e1346fe1","updated":"2020-01-23 05:55:49.000000000","message":"Done","commit_id":"f64e3452f5b27d9a628755af272647801894220e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9150447d5a0a3acd7c7b70a1c5b1f1c8859aa068","unresolved":false,"context_lines":[{"line_number":916,"context_line":"                                 \"attributes.\")"},{"line_number":917,"context_line":"        # We\u0027ve done some normalizing; write back so it\u0027s ready for"},{"line_number":918,"context_line":"        # to_swift_req"},{"line_number":919,"context_line":"        self.headers[\u0027X-Amz-Copy-Source\u0027] \u003d src_path"},{"line_number":920,"context_line":"        if query:"},{"line_number":921,"context_line":"            self.headers[\u0027X-Amz-Copy-Source\u0027] +\u003d \\"},{"line_number":922,"context_line":"                \u0027?versionId\u003d\u0027 + query[\u0027version-id\u0027]"}],"source_content_type":"text/x-python","patch_set":45,"id":"3fa7e38b_61eabf0e","line":919,"range":{"start_line":919,"start_character":44,"end_line":919,"end_character":52},"updated":"2020-01-22 13:35:41.000000000","message":"Shouldn\u0027t this get quoted?","commit_id":"f64e3452f5b27d9a628755af272647801894220e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"54c4cf41440a91e483e2737c511ec2a6bd9a22a1","unresolved":false,"context_lines":[{"line_number":916,"context_line":"                                 \"attributes.\")"},{"line_number":917,"context_line":"        # We\u0027ve done some normalizing; write back so it\u0027s ready for"},{"line_number":918,"context_line":"        # to_swift_req"},{"line_number":919,"context_line":"        self.headers[\u0027X-Amz-Copy-Source\u0027] \u003d src_path"},{"line_number":920,"context_line":"        if query:"},{"line_number":921,"context_line":"            self.headers[\u0027X-Amz-Copy-Source\u0027] +\u003d \\"},{"line_number":922,"context_line":"                \u0027?versionId\u003d\u0027 + query[\u0027version-id\u0027]"}],"source_content_type":"text/x-python","patch_set":45,"id":"3fa7e38b_bf152497","line":919,"range":{"start_line":919,"start_character":44,"end_line":919,"end_character":52},"in_reply_to":"3fa7e38b_61eabf0e","updated":"2020-01-23 05:55:49.000000000","message":"Done","commit_id":"f64e3452f5b27d9a628755af272647801894220e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9150447d5a0a3acd7c7b70a1c5b1f1c8859aa068","unresolved":false,"context_lines":[{"line_number":1295,"context_line":"                    HTTP_REQUEST_ENTITY_TOO_LARGE: EntityTooLarge,"},{"line_number":1296,"context_line":"                    HTTP_LENGTH_REQUIRED: MissingContentLength,"},{"line_number":1297,"context_line":"                    HTTP_REQUEST_TIMEOUT: RequestTimeout,"},{"line_number":1298,"context_line":"                    HTTP_PRECONDITION_FAILED: PreconditionFailed,"},{"line_number":1299,"context_line":"                },"},{"line_number":1300,"context_line":"                \u0027POST\u0027: {"},{"line_number":1301,"context_line":"                    HTTP_NOT_FOUND: not_found_handler,"}],"source_content_type":"text/x-python","patch_set":45,"id":"3fa7e38b_c16ff390","line":1298,"updated":"2020-01-22 13:35:41.000000000","message":"What condition are we expecting here? Swift\u0027s interpretation of a 412 doesn\u0027t always match the RFCs\u0027 ideas of a 412, so I\u0027m not sure this is an accurate translation...","commit_id":"f64e3452f5b27d9a628755af272647801894220e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9150447d5a0a3acd7c7b70a1c5b1f1c8859aa068","unresolved":false,"context_lines":[{"line_number":1457,"context_line":"        query \u003d {} if version is None else {"},{"line_number":1458,"context_line":"            \u0027version-id\u0027: version, \u0027symlink\u0027: \u0027get\u0027}"},{"line_number":1459,"context_line":"        resp \u003d self.get_response(app, \u0027HEAD\u0027, obj\u003dobj, query\u003dquery)"},{"line_number":1460,"context_line":"        return {\u0027multipart-manifest\u0027: \u0027delete\u0027} if resp.is_slo else {}"},{"line_number":1461,"context_line":""},{"line_number":1462,"context_line":"    def set_acl_handler(self, handler):"},{"line_number":1463,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":45,"id":"3fa7e38b_c11db310","line":1460,"updated":"2020-01-22 13:35:41.000000000","message":"So if we\u0027re doing a version-unaware delete... the HEAD follows the symlink and we see the SLO-ness... and we go clean up the segments? :-(","commit_id":"f64e3452f5b27d9a628755af272647801894220e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"54c4cf41440a91e483e2737c511ec2a6bd9a22a1","unresolved":false,"context_lines":[{"line_number":1454,"context_line":"            obj \u003d self.object_name"},{"line_number":1455,"context_line":"        query \u003d {} if version is None else {"},{"line_number":1456,"context_line":"            \u0027version-id\u0027: version, \u0027symlink\u0027: \u0027get\u0027}"},{"line_number":1457,"context_line":"        resp \u003d self.get_response(app, \u0027HEAD\u0027, obj\u003dobj, query\u003dquery)"},{"line_number":1458,"context_line":"        return {\u0027multipart-manifest\u0027: \u0027delete\u0027} if resp.is_slo else {}"},{"line_number":1459,"context_line":""},{"line_number":1460,"context_line":"    def set_acl_handler(self, handler):"}],"source_content_type":"text/x-python","patch_set":46,"id":"3fa7e38b_ff64fc4e","line":1457,"updated":"2020-01-23 05:55:49.000000000","message":"Yup; no bueno:\n\n$ aws s3 mb s3://bucket\nmake_bucket: bucket\n$ aws s3api put-bucket-versioning --versioning-configuration Status\u003dEnabled --bucket bucket\n$ dd if\u003d/dev/zero of\u003d100MiB bs\u003d1M count\u003d100\n100+0 records in\n100+0 records out\n104857600 bytes (105 MB, 100 MiB) copied, 0.372389 s, 282 MB/s\n$ aws s3 cp 100MiB s3://bucket\nupload: ./100MiB to s3://bucket/100MiB\n$ aws s3 rm s3://bucket/100MiB\ndelete: s3://bucket/100MiB\n$ aws s3api list-object-versions --bucket bucket\n{\n    \"Versions\": [\n        {\n            \"ETag\": \"\\\"0c4af570340e15f2be9924e70bc34257-13\\\"\",\n            \"Size\": 104857600,\n            \"StorageClass\": \"STANDARD\",\n            \"Key\": \"100MiB\",\n            \"VersionId\": \"1579758402.14019\",\n            \"IsLatest\": false,\n            \"LastModified\": \"2020-01-23T05:46:42.140Z\",\n            \"Owner\": {\n                \"DisplayName\": \"test:tester\",\n                \"ID\": \"test:tester\"\n            }\n        }\n    ],\n    \"DeleteMarkers\": [\n        {\n            \"Owner\": {\n                \"DisplayName\": \"test:tester\",\n                \"ID\": \"test:tester\"\n            },\n            \"Key\": \"100MiB\",\n            \"VersionId\": \"1579758416.24209\",\n            \"IsLatest\": true,\n            \"LastModified\": \"2020-01-23T05:46:56.242Z\"\n        }\n    ]\n}\n$ aws s3api head-object --bucket bucket --key 100MiB --version-id 1579758402.14019\n{\n    \"LastModified\": \"Thu, 23 Jan 2020 05:46:43 GMT\",\n    \"ContentLength\": 104857600,\n    \"ETag\": \"\\\"0c4af570340e15f2be9924e70bc34257-13\\\"\",\n    \"VersionId\": \"1579758402.14019\",\n    \"ContentType\": \"application/octet-stream\",\n    \"Metadata\": {}\n}\n$ aws s3api get-object --bucket bucket --key 100MiB --version-id 1579758402.14019 \u003e( cat )\n \nAn error occurred (InternalError) when calling the GetObject operation (reached max retries: 4): unexpected status code 409","commit_id":"021a81ea6aaa4b0dede315f66b1b52dcef75b699"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"42afe5f7eb6242d7e293d039781d20c9ab9123de","unresolved":false,"context_lines":[{"line_number":1454,"context_line":"            obj \u003d self.object_name"},{"line_number":1455,"context_line":"        query \u003d {} if version is None else {"},{"line_number":1456,"context_line":"            \u0027version-id\u0027: version, \u0027symlink\u0027: \u0027get\u0027}"},{"line_number":1457,"context_line":"        resp \u003d self.get_response(app, \u0027HEAD\u0027, obj\u003dobj, query\u003dquery)"},{"line_number":1458,"context_line":"        return {\u0027multipart-manifest\u0027: \u0027delete\u0027} if resp.is_slo else {}"},{"line_number":1459,"context_line":""},{"line_number":1460,"context_line":"    def set_acl_handler(self, handler):"}],"source_content_type":"text/x-python","patch_set":46,"id":"3fa7e38b_020ba6d3","line":1457,"in_reply_to":"3fa7e38b_64c4f441","updated":"2020-01-24 19:03:14.000000000","message":"This got more complicated, needing to plumb version-id logic through bulk, too... but I think the parent patch has squared it now!","commit_id":"021a81ea6aaa4b0dede315f66b1b52dcef75b699"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"76de2e0c47a2d89f9f376ee51901feaf27a6c949","unresolved":false,"context_lines":[{"line_number":1454,"context_line":"            obj \u003d self.object_name"},{"line_number":1455,"context_line":"        query \u003d {} if version is None else {"},{"line_number":1456,"context_line":"            \u0027version-id\u0027: version, \u0027symlink\u0027: \u0027get\u0027}"},{"line_number":1457,"context_line":"        resp \u003d self.get_response(app, \u0027HEAD\u0027, obj\u003dobj, query\u003dquery)"},{"line_number":1458,"context_line":"        return {\u0027multipart-manifest\u0027: \u0027delete\u0027} if resp.is_slo else {}"},{"line_number":1459,"context_line":""},{"line_number":1460,"context_line":"    def set_acl_handler(self, handler):"}],"source_content_type":"text/x-python","patch_set":46,"id":"3fa7e38b_64c4f441","line":1457,"in_reply_to":"3fa7e38b_ff64fc4e","updated":"2020-01-23 22:20:52.000000000","message":"diff --git a/swift/common/middleware/s3api/s3request.py b/swift/common/middleware/s3api/s3request.py\nindex 54e92bbf4..017aabe7e 100644\n--- a/swift/common/middleware/s3api/s3request.py\n+++ b/swift/common/middleware/s3api/s3request.py\n@@ -1452,8 +1452,9 @@ class S3Request(swob.Request):\n             return {}\n         if not obj:\n             obj \u003d self.object_name\n-        query \u003d {} if version is None else {\n-            \u0027version-id\u0027: version, \u0027symlink\u0027: \u0027get\u0027}\n+        query \u003d {\u0027symlink\u0027: \u0027get\u0027}\n+        if version is not None:\n+            query[\u0027version-id\u0027] \u003d version\n         resp \u003d self.get_response(app, \u0027HEAD\u0027, obj\u003dobj, query\u003dquery)\n         return {\u0027multipart-manifest\u0027: \u0027delete\u0027} if resp.is_slo else {}\n\nhelps a bunch, but then we discover that ?multipart-manifest\u003ddelete doesn\u0027t play well with our new versioning. SLO needs something like\n\ndiff --git a/swift/common/middleware/slo.py b/swift/common/middleware/slo.py\nindex ef3daedd5..818af4ccc 100644\n--- a/swift/common/middleware/slo.py\n+++ b/swift/common/middleware/slo.py\n@@ -1466,6 +1466,9 @@ class StaticLargeObject(object):\n         new_env[\u0027REQUEST_METHOD\u0027] \u003d \u0027GET\u0027\n         del(new_env[\u0027wsgi.input\u0027])\n         new_env[\u0027QUERY_STRING\u0027] \u003d \u0027multipart-manifest\u003dget\u0027\n+        if \u0027version-id\u0027 in req.params:\n+            new_env[\u0027QUERY_STRING\u0027] +\u003d \\\n+                \u0027\u0026version-id\u003d\u0027 + req.params[\u0027version-id\u0027]\n         new_env[\u0027CONTENT_LENGTH\u0027] \u003d 0\n         new_env[\u0027HTTP_USER_AGENT\u0027] \u003d \\\n             \u0027%s MultipartDELETE\u0027 % new_env.get(\u0027HTTP_USER_AGENT\u0027)\n\nShouldn\u0027t be too bad to write a func test for the Swift API...","commit_id":"021a81ea6aaa4b0dede315f66b1b52dcef75b699"}],"swift/common/middleware/s3api/s3response.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9150447d5a0a3acd7c7b70a1c5b1f1c8859aa068","unresolved":false,"context_lines":[{"line_number":105,"context_line":"                # header name. We translated underscores to \u0027\u003d5F\u0027 on the way"},{"line_number":106,"context_line":"                # in, though."},{"line_number":107,"context_line":"                headers[\u0027x-amz-meta-\u0027 + _key[14:].replace(\u0027\u003d5f\u0027, \u0027_\u0027)] \u003d val"},{"line_number":108,"context_line":"            elif _key \u003d\u003d \u0027x-content-type\u0027 and \\"},{"line_number":109,"context_line":"                    val \u003d\u003d DELETE_MARKER_CONTENT_TYPE:"},{"line_number":110,"context_line":"                headers[\u0027x-amz-delete-marker\u0027] \u003d \u0027true\u0027"},{"line_number":111,"context_line":"                headers[key] \u003d val"}],"source_content_type":"text/x-python","patch_set":45,"id":"3fa7e38b_c1cb7370","line":108,"range":{"start_line":108,"start_character":26,"end_line":108,"end_character":40},"updated":"2020-01-22 13:35:41.000000000","message":"I thought this was only used with container updates...","commit_id":"f64e3452f5b27d9a628755af272647801894220e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"42afe5f7eb6242d7e293d039781d20c9ab9123de","unresolved":false,"context_lines":[{"line_number":105,"context_line":"                # header name. We translated underscores to \u0027\u003d5F\u0027 on the way"},{"line_number":106,"context_line":"                # in, though."},{"line_number":107,"context_line":"                headers[\u0027x-amz-meta-\u0027 + _key[14:].replace(\u0027\u003d5f\u0027, \u0027_\u0027)] \u003d val"},{"line_number":108,"context_line":"            elif _key \u003d\u003d \u0027x-content-type\u0027 and \\"},{"line_number":109,"context_line":"                    val \u003d\u003d DELETE_MARKER_CONTENT_TYPE:"},{"line_number":110,"context_line":"                headers[\u0027x-amz-delete-marker\u0027] \u003d \u0027true\u0027"},{"line_number":111,"context_line":"                headers[key] \u003d val"},{"line_number":112,"context_line":"            elif _key in (\u0027content-length\u0027, \u0027content-type\u0027,"},{"line_number":113,"context_line":"                          \u0027content-range\u0027, \u0027content-encoding\u0027,"},{"line_number":114,"context_line":"                          \u0027content-disposition\u0027, \u0027content-language\u0027,"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_82bd56d2","line":111,"range":{"start_line":108,"start_character":12,"end_line":111,"end_character":34},"updated":"2020-01-24 19:03:14.000000000","message":"Can remove -- this header should never be sent to a proxy.","commit_id":"7b536acc31c73438cae38312dd4b345a440cdeca"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"17d3ab47a854dd6f024995729a82191ba5d08e09","unresolved":false,"context_lines":[{"line_number":105,"context_line":"                # header name. We translated underscores to \u0027\u003d5F\u0027 on the way"},{"line_number":106,"context_line":"                # in, though."},{"line_number":107,"context_line":"                headers[\u0027x-amz-meta-\u0027 + _key[14:].replace(\u0027\u003d5f\u0027, \u0027_\u0027)] \u003d val"},{"line_number":108,"context_line":"            elif _key \u003d\u003d \u0027x-content-type\u0027 and \\"},{"line_number":109,"context_line":"                    val \u003d\u003d DELETE_MARKER_CONTENT_TYPE:"},{"line_number":110,"context_line":"                headers[\u0027x-amz-delete-marker\u0027] \u003d \u0027true\u0027"},{"line_number":111,"context_line":"                headers[key] \u003d val"},{"line_number":112,"context_line":"            elif _key in (\u0027content-length\u0027, \u0027content-type\u0027,"},{"line_number":113,"context_line":"                          \u0027content-range\u0027, \u0027content-encoding\u0027,"},{"line_number":114,"context_line":"                          \u0027content-disposition\u0027, \u0027content-language\u0027,"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_cb6b6983","line":111,"range":{"start_line":108,"start_character":12,"end_line":111,"end_character":34},"in_reply_to":"3fa7e38b_82bd56d2","updated":"2020-01-25 01:18:55.000000000","message":"Done","commit_id":"7b536acc31c73438cae38312dd4b345a440cdeca"}],"swift/common/middleware/versioned_writes/object_versioning.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"cf76c5c950611eaa0e633b8a639372247f4d88a6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":24,"id":"3fa7e38b_c936f5b4","updated":"2019-11-22 23:03:15.000000000","message":"Should we move this diff into the parent patch?","commit_id":"6efef26745700f00cd4629b4d42d14ae36fdba26"}],"test/functional/__init__.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"967c79e2ca113e40eef941f9fdf238eef3368ca2","unresolved":false,"context_lines":[{"line_number":27,"context_line":"import functools"},{"line_number":28,"context_line":"import random"},{"line_number":29,"context_line":"import base64"},{"line_number":30,"context_line":"import unittest2"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"from time import time, sleep"},{"line_number":33,"context_line":"from contextlib import closing"}],"source_content_type":"text/x-python","patch_set":50,"id":"3fa7e38b_c3210db7","line":30,"updated":"2020-01-26 00:01:45.000000000","message":"Oh, hey! https://review.opendev.org/#/c/702121/ just ripped this out!","commit_id":"7fb9b494d33a4f6fcab5208284bcbf12110d184b"}],"test/functional/s3api/test_versioning.py":[{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"6e35dbb7170e33137b460a94429b91504ce3cfa4","unresolved":false,"context_lines":[{"line_number":41,"context_line":"    def tearDown(self):"},{"line_number":42,"context_line":"        # TODO: is this necessary on AWS? or can you delete buckets while"},{"line_number":43,"context_line":"        # versioning is enabled?"},{"line_number":44,"context_line":"        elem \u003d Element(\u0027VersioningConfiguration\u0027)"},{"line_number":45,"context_line":"        SubElement(elem, \u0027Status\u0027).text \u003d \u0027Suspended\u0027"},{"line_number":46,"context_line":"        xml \u003d tostring(elem)"},{"line_number":47,"context_line":"        status, headers, body \u003d self.conn.make_request("},{"line_number":48,"context_line":"            \u0027PUT\u0027, \u0027bucket\u0027, body\u003dxml, query\u003d\u0027versioning\u0027)"},{"line_number":49,"context_line":"        self.assertEqual(status, 200)"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"        status, headers, body \u003d self.conn.make_request(\u0027DELETE\u0027, \u0027bucket\u0027)"},{"line_number":52,"context_line":"        self.assertEqual(status, 204)"}],"source_content_type":"text/x-python","patch_set":30,"id":"3fa7e38b_ceb1dbe2","line":49,"range":{"start_line":44,"start_character":8,"end_line":49,"end_character":37},"updated":"2019-12-17 10:23:51.000000000","message":"this was changed to no longer be needed, now just container and versions container need to be empty","commit_id":"48c8e1aca3b50f10b1d3375c572ce23fe73688ec"}],"test/s3api/test_versioning.py":[{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"6e35dbb7170e33137b460a94429b91504ce3cfa4","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright (c) 2019 SwiftStack, Inc."},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"# Licensed under the Apache License, Version 2.0 (the \"License\");"},{"line_number":4,"context_line":"# you may not use this file except in compliance with the License."}],"source_content_type":"text/x-python","patch_set":30,"id":"3fa7e38b_51b7ca22","line":1,"updated":"2019-12-17 10:23:51.000000000","message":"should we add some \u0027null\u0027 tests here?","commit_id":"48c8e1aca3b50f10b1d3375c572ce23fe73688ec"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"6e35dbb7170e33137b460a94429b91504ce3cfa4","unresolved":false,"context_lines":[{"line_number":55,"context_line":"        retry(enable_versioning)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def tearDown(self):"},{"line_number":58,"context_line":"        resp \u003d self.client.put_bucket_versioning("},{"line_number":59,"context_line":"            Bucket\u003dself.bucket_name,"},{"line_number":60,"context_line":"            VersioningConfiguration\u003d{\u0027Status\u0027: \u0027Suspended\u0027})"},{"line_number":61,"context_line":"        self.assertEqual(200, resp[\u0027ResponseMetadata\u0027][\u0027HTTPStatusCode\u0027])"},{"line_number":62,"context_line":"        self.clear_bucket(self.client, self.bucket_name)"},{"line_number":63,"context_line":"        super(TestObjectVersioning, self).tearDown()"},{"line_number":64,"context_line":""}],"source_content_type":"text/x-python","patch_set":30,"id":"3fa7e38b_ce9ebb05","line":61,"range":{"start_line":58,"start_character":8,"end_line":61,"end_character":73},"updated":"2019-12-17 10:23:51.000000000","message":"should no longer be needed","commit_id":"48c8e1aca3b50f10b1d3375c572ce23fe73688ec"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"6e35dbb7170e33137b460a94429b91504ce3cfa4","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        self.clear_bucket(self.client, self.bucket_name)"},{"line_number":63,"context_line":"        super(TestObjectVersioning, self).tearDown()"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    def test_setup(self):"},{"line_number":66,"context_line":"        bucket_name \u003d self.create_name(\u0027new-bucket\u0027)"},{"line_number":67,"context_line":"        resp \u003d self.client.create_bucket(Bucket\u003dbucket_name)"},{"line_number":68,"context_line":"        self.assertEqual(200, resp[\u0027ResponseMetadata\u0027][\u0027HTTPStatusCode\u0027])"}],"source_content_type":"text/x-python","patch_set":30,"id":"3fa7e38b_ceb79b85","line":65,"range":{"start_line":65,"start_character":8,"end_line":65,"end_character":18},"updated":"2019-12-17 10:23:51.000000000","message":"feels like most of this test is already executed in both setup and tearDown","commit_id":"48c8e1aca3b50f10b1d3375c572ce23fe73688ec"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"6e35dbb7170e33137b460a94429b91504ce3cfa4","unresolved":false,"context_lines":[{"line_number":146,"context_line":"        for obj in objs:"},{"line_number":147,"context_line":"            obj.pop(\u0027LastModified\u0027)"},{"line_number":148,"context_line":"            obj.pop(\u0027Owner\u0027)"},{"line_number":149,"context_line":"            obj.pop(\u0027VersionId\u0027)"},{"line_number":150,"context_line":"        self.assertEqual([{"},{"line_number":151,"context_line":"            \u0027ETag\u0027: \u0027\"%s\"\u0027 % obj_etag,"},{"line_number":152,"context_line":"            \u0027IsLatest\u0027: True,"}],"source_content_type":"text/x-python","patch_set":30,"id":"3fa7e38b_0e4cd39b","line":149,"range":{"start_line":149,"start_character":21,"end_line":149,"end_character":30},"updated":"2019-12-17 10:23:51.000000000","message":"should assert versionId is in obj...","commit_id":"48c8e1aca3b50f10b1d3375c572ce23fe73688ec"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"6e35dbb7170e33137b460a94429b91504ce3cfa4","unresolved":false,"context_lines":[{"line_number":222,"context_line":"        for obj in objs:"},{"line_number":223,"context_line":"            obj.pop(\u0027LastModified\u0027)"},{"line_number":224,"context_line":"            obj.pop(\u0027Owner\u0027)"},{"line_number":225,"context_line":"            versions.append(obj.pop(\u0027VersionId\u0027))"},{"line_number":226,"context_line":"        self.assertEqual([{"},{"line_number":227,"context_line":"            \u0027ETag\u0027: \u0027\"%s\"\u0027 % etags[0],"},{"line_number":228,"context_line":"            \u0027IsLatest\u0027: True,"}],"source_content_type":"text/x-python","patch_set":30,"id":"3fa7e38b_8e1c437c","line":225,"range":{"start_line":225,"start_character":12,"end_line":225,"end_character":48},"updated":"2019-12-17 10:23:51.000000000","message":"...actually that takes care of it, it\u0027s just not explicit","commit_id":"48c8e1aca3b50f10b1d3375c572ce23fe73688ec"}],"test/unit/common/middleware/s3api/test_multi_delete.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"42afe5f7eb6242d7e293d039781d20c9ab9123de","unresolved":false,"context_lines":[{"line_number":273,"context_line":"        status, headers, body \u003d self.call_s3api(req)"},{"line_number":274,"context_line":"        self.assertEqual(status.split()[0], \u0027200\u0027)"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"        self.maxDiff\u003dNone"},{"line_number":277,"context_line":"        self.assertEqual(self.swift.calls, ["},{"line_number":278,"context_line":"            (\u0027HEAD\u0027, \u0027/v1/AUTH_test/bucket\u0027),"},{"line_number":279,"context_line":"            (\u0027HEAD\u0027, key1),"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_c2f02edd","line":276,"updated":"2020-01-24 19:03:14.000000000","message":"Left over from debugging.","commit_id":"7b536acc31c73438cae38312dd4b345a440cdeca"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"17d3ab47a854dd6f024995729a82191ba5d08e09","unresolved":false,"context_lines":[{"line_number":273,"context_line":"        status, headers, body \u003d self.call_s3api(req)"},{"line_number":274,"context_line":"        self.assertEqual(status.split()[0], \u0027200\u0027)"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"        self.maxDiff\u003dNone"},{"line_number":277,"context_line":"        self.assertEqual(self.swift.calls, ["},{"line_number":278,"context_line":"            (\u0027HEAD\u0027, \u0027/v1/AUTH_test/bucket\u0027),"},{"line_number":279,"context_line":"            (\u0027HEAD\u0027, key1),"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_6b66f5be","line":276,"in_reply_to":"3fa7e38b_c2f02edd","updated":"2020-01-25 01:18:55.000000000","message":"Done","commit_id":"7b536acc31c73438cae38312dd4b345a440cdeca"}],"test/unit/common/middleware/s3api/test_obj.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"cf76c5c950611eaa0e633b8a639372247f4d88a6","unresolved":false,"context_lines":[{"line_number":1269,"context_line":"            (\u0027HEAD\u0027, \u0027/v1/AUTH_test\u0027),"},{"line_number":1270,"context_line":"            (\u0027HEAD\u0027, \u0027/v1/AUTH_test/bucket\u0027),"},{"line_number":1271,"context_line":"            (\u0027DELETE\u0027, \u0027/v1/AUTH_test/bucket/object\u0027),"},{"line_number":1272,"context_line":"        ], self.swift.calls)"},{"line_number":1273,"context_line":""},{"line_number":1274,"context_line":"    @s3acl"},{"line_number":1275,"context_line":"    def test_object_DELETE_multipart(self):"}],"source_content_type":"text/x-python","patch_set":25,"id":"3fa7e38b_9ab11904","line":1272,"updated":"2019-11-22 23:03:15.000000000","message":"What about the same test, but with a version-id?","commit_id":"b30120fac78cf614d8425e1caf714ec4ab0fcdf9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"eda785ace6feb91622f798645173b4c13c0fe6aa","unresolved":false,"context_lines":[{"line_number":1269,"context_line":"            (\u0027HEAD\u0027, \u0027/v1/AUTH_test\u0027),"},{"line_number":1270,"context_line":"            (\u0027HEAD\u0027, \u0027/v1/AUTH_test/bucket\u0027),"},{"line_number":1271,"context_line":"            (\u0027DELETE\u0027, \u0027/v1/AUTH_test/bucket/object\u0027),"},{"line_number":1272,"context_line":"        ], self.swift.calls)"},{"line_number":1273,"context_line":""},{"line_number":1274,"context_line":"    @s3acl"},{"line_number":1275,"context_line":"    def test_object_DELETE_multipart(self):"}],"source_content_type":"text/x-python","patch_set":25,"id":"3fa7e38b_8713f2b7","line":1272,"in_reply_to":"3fa7e38b_9ab11904","updated":"2019-11-26 14:03:35.000000000","message":"that\u0027s an interesting thought...\n\ni guess if the HEAD?version-id\u003dXXX \"check for manifest\" request 404s we can skip the DELETE?version-id\u003dXXX request","commit_id":"b30120fac78cf614d8425e1caf714ec4ab0fcdf9"}]}
