)]}'
{"etc/proxy-server.conf-sample":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5c4eaf4c4023d7b724290e11e8dd3f494e1be2d2","unresolved":false,"context_lines":[{"line_number":1073,"context_line":"# deprecated. See documentation for more details."},{"line_number":1074,"context_line":"# allow_versioned_writes \u003d false"},{"line_number":1075,"context_line":"# Enables Swift object-versioning API"},{"line_number":1076,"context_line":"# allow_object_versioning \u003d false"},{"line_number":1077,"context_line":""},{"line_number":1078,"context_line":"# Note: Put after auth and before dlo and slo middlewares."},{"line_number":1079,"context_line":"# If you don\u0027t put it in the pipeline, it will be inserted for you."}],"source_content_type":"application/octet-stream","patch_set":26,"id":"3fa7e38b_6ffd3e3a","line":1076,"updated":"2019-11-14 02:25:06.000000000","message":"i think i\u0027d be happier if this was true by default, but maybe I won\u0027t care once I add it to vsaio","commit_id":"927521ef49f6e9f04f5eb7b281acde2a4818bdd7"}],"swift/common/middleware/bulk.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2c0b3ed584754862e48372e1d0a93f96a41ebc8c","unresolved":false,"context_lines":[{"line_number":360,"context_line":"                    # errors\u003d\u0027surrogateescape\u0027 when dealing with terrible"},{"line_number":361,"context_line":"                    # input like b\u0027\\xe2%98\\x83\u0027"},{"line_number":362,"context_line":"                    obj_to_delete \u003d wsgi_to_str(wsgi_unquote("},{"line_number":363,"context_line":"                        bytes_to_wsgi(obj_to_delete.strip())))"},{"line_number":364,"context_line":"                objs_to_delete.append({\u0027name\u0027: obj_to_delete})"},{"line_number":365,"context_line":"            else:"},{"line_number":366,"context_line":"                data \u003d req.body_file.read(self.max_path_length)"}],"source_content_type":"text/x-python","patch_set":78,"id":"3fa7e38b_e21a0a69","line":363,"updated":"2020-01-24 18:24:55.000000000","message":"Oh, nice -- we already expect items to be quoted... so later we could teach this to parse things like\n\n name?version-id\u003d1234\n\nto an obj_to_delete like\n\n {\u0027name\u0027: \u0027name\u0027, \u0027version_id\u0027: \u00271234\u0027}\n\nand everything should Just Work.","commit_id":"92a02a4a4c1defff6d345b739f6963b0fdbdb793"}],"swift/common/middleware/symlink.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f80d1fd38f5e2bb278fd922fcb53d8f37c856dac","unresolved":false,"context_lines":[{"line_number":655,"context_line":"                     \u0027directly to the target to apply requested metadata.\u0027"},{"line_number":656,"context_line":"            for key, value in self._response_headers:"},{"line_number":657,"context_line":"                if key.lower().startswith(\u0027x-object-sysmeta-\u0027):"},{"line_number":658,"context_line":"                    headers[key] \u003d value"},{"line_number":659,"context_line":"            raise HTTPTemporaryRedirect("},{"line_number":660,"context_line":"                body\u003derrmsg, headers\u003dheaders)"},{"line_number":661,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_582554c1","line":658,"updated":"2019-09-23 19:00:36.000000000","message":"+1, matches what the object-server does: https://github.com/openstack/swift/blob/2.22.0/swift/obj/server.py#L733-L739","commit_id":"1b4c596a5845618a86c3c12b5564f8aef0559a7f"}],"swift/common/middleware/versioned_writes/__init__.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f80d1fd38f5e2bb278fd922fcb53d8f37c856dac","unresolved":false,"context_lines":[{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    def versioning_filter(app):"},{"line_number":43,"context_line":"        return VersionedWritesMiddleware("},{"line_number":44,"context_line":"            ObjectVersioningMiddleware(app, conf), conf)"},{"line_number":45,"context_line":"    return versioning_filter"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_b32589ad","line":44,"range":{"start_line":44,"start_character":12,"end_line":44,"end_character":38},"updated":"2019-09-23 19:00:36.000000000","message":"I had it in my mind that whether the new would be included or not would depend on a config value... like, operators would need to opt-in to the new stuff...","commit_id":"1b4c596a5845618a86c3c12b5564f8aef0559a7f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    def versioning_filter(app):"},{"line_number":43,"context_line":"        return VersionedWritesMiddleware("},{"line_number":44,"context_line":"            ObjectVersioningMiddleware(app, conf), conf)"},{"line_number":45,"context_line":"    return versioning_filter"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_ac310ebe","line":44,"range":{"start_line":44,"start_character":12,"end_line":44,"end_character":38},"in_reply_to":"3fa7e38b_458f9d74","updated":"2019-12-17 01:30:58.000000000","message":"Addressed in PS5","commit_id":"1b4c596a5845618a86c3c12b5564f8aef0559a7f"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"d05656d1218c770701ff5c6d89dfd82f12dabe4e","unresolved":false,"context_lines":[{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    def versioning_filter(app):"},{"line_number":43,"context_line":"        return VersionedWritesMiddleware("},{"line_number":44,"context_line":"            ObjectVersioningMiddleware(app, conf), conf)"},{"line_number":45,"context_line":"    return versioning_filter"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_458f9d74","line":44,"range":{"start_line":44,"start_character":12,"end_line":44,"end_character":38},"in_reply_to":"3fa7e38b_b32589ad","updated":"2019-09-24 13:39:54.000000000","message":"yeah, it probably makes sense to add a config value since the middleware gets auto-inserted by the proxy. It\u0027s not like other middlewares where the \"enable\" flag is the act of adding to the pipeline.","commit_id":"1b4c596a5845618a86c3c12b5564f8aef0559a7f"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"a4dae93583669488e0452de4193879519d988c11","unresolved":false,"context_lines":[{"line_number":19,"context_line":":class:`~swift.common.middleware.versioned_writes.object_versioning."},{"line_number":20,"context_line":"ObjectVersioningMiddleware`."},{"line_number":21,"context_line":"\"\"\""},{"line_number":22,"context_line":"from swift.common.middleware.versioned_writes. \\"},{"line_number":23,"context_line":"    legacy import CLIENT_VERSIONS_LOC, CLIENT_HISTORY_LOC, \\"},{"line_number":24,"context_line":"    VersionedWritesMiddleware"},{"line_number":25,"context_line":"from swift.common.middleware.versioned_writes. \\"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_da24ee62","line":22,"updated":"2019-12-04 05:46:13.000000000","message":"it fells weird to me to wrap on a . in a from. There seems to be plenty of space to at least:\n\n  from swift.common.middleware.versioned_writes.legacy import \\\n\nThough maybe it\u0027s just a NIT","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"a4dae93583669488e0452de4193879519d988c11","unresolved":false,"context_lines":[{"line_number":22,"context_line":"from swift.common.middleware.versioned_writes. \\"},{"line_number":23,"context_line":"    legacy import CLIENT_VERSIONS_LOC, CLIENT_HISTORY_LOC, \\"},{"line_number":24,"context_line":"    VersionedWritesMiddleware"},{"line_number":25,"context_line":"from swift.common.middleware.versioned_writes. \\"},{"line_number":26,"context_line":"    object_versioning import ObjectVersioningMiddleware"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"from swift.common.utils import config_true_value, register_swift_info, \\"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_5a18fe1c","line":25,"updated":"2019-12-04 05:46:13.000000000","message":"and here.","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"}],"swift/common/middleware/versioned_writes/object_versioning.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1ceb9443f85a14839be2d229c14892f020f55e5e","unresolved":false,"context_lines":[{"line_number":99,"context_line":"        except ListingIterError:"},{"line_number":100,"context_line":"            raise HTTPServerError(request\u003dreq)"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"    def _in_proxy_reverse_listing(self, account_name, lcontainer, lprefix,"},{"line_number":103,"context_line":"                                  req, failed_marker, failed_listing):"},{"line_number":104,"context_line":"        \u0027\u0027\u0027Get the complete prefix listing and reverse it on the proxy."},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        This is only necessary if we encounter a response from a"},{"line_number":107,"context_line":"        container-server that does not respect the ``reverse`` param"},{"line_number":108,"context_line":"        included by default in ``_listing_pages_iter``. This may happen"},{"line_number":109,"context_line":"        during rolling upgrades from pre-2.6.0 swift."},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"        :param failed_marker: the marker that was used when we encountered"},{"line_number":112,"context_line":"                              the non-reversed listing"},{"line_number":113,"context_line":"        :param failed_listing: the non-reversed listing that was encountered."},{"line_number":114,"context_line":"                               If ``failed_marker`` is blank, we can use this"},{"line_number":115,"context_line":"                               to save ourselves a request"},{"line_number":116,"context_line":"        :returns: an iterator over all objects starting with ``lprefix`` (up"},{"line_number":117,"context_line":"                  to but not including the failed marker) in reverse order"},{"line_number":118,"context_line":"        \u0027\u0027\u0027"},{"line_number":119,"context_line":"        complete_listing \u003d []"},{"line_number":120,"context_line":"        if not failed_marker:"},{"line_number":121,"context_line":"            # We\u0027ve never gotten a reversed listing. So save a request and"},{"line_number":122,"context_line":"            # use the failed listing."},{"line_number":123,"context_line":"            complete_listing.extend(failed_listing)"},{"line_number":124,"context_line":"            marker \u003d bytes_to_wsgi(complete_listing[-1][\u0027name\u0027].encode(\u0027utf8\u0027))"},{"line_number":125,"context_line":"        else:"},{"line_number":126,"context_line":"            # We\u0027ve gotten at least one reversed listing. Have to start at"},{"line_number":127,"context_line":"            # the beginning."},{"line_number":128,"context_line":"            marker \u003d \u0027\u0027"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"        # First, take the *entire* prefix listing into memory"},{"line_number":131,"context_line":"        try:"},{"line_number":132,"context_line":"            for page in self._listing_pages_iter("},{"line_number":133,"context_line":"                    account_name, lcontainer, lprefix,"},{"line_number":134,"context_line":"                    req, marker, end_marker\u003dfailed_marker, reverse\u003dFalse):"},{"line_number":135,"context_line":"                complete_listing.extend(page)"},{"line_number":136,"context_line":"        except ListingIterNotFound:"},{"line_number":137,"context_line":"            pass"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"        # Now that we\u0027ve got everything, return the whole listing as one giant"},{"line_number":140,"context_line":"        # reversed page"},{"line_number":141,"context_line":"        return reversed(complete_listing)"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"    def _listing_pages_iter(self, account_name, lcontainer, lprefix,"},{"line_number":144,"context_line":"                            req, marker\u003d\u0027\u0027, end_marker\u003d\u0027\u0027, reverse\u003dTrue):"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_ce2e5e42","line":141,"range":{"start_line":102,"start_character":4,"end_line":141,"end_character":41},"updated":"2019-09-24 18:23:01.000000000","message":"One of the really nice things about all of this? We don\u0027t need reversed listings anymore, so we can axe all of this (plus the reverse handling in _listing_pages_iter).","commit_id":"f9bd19f1a5fc00f16cab33b1d142f72904a3e899"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":99,"context_line":"        except ListingIterError:"},{"line_number":100,"context_line":"            raise HTTPServerError(request\u003dreq)"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"    def _in_proxy_reverse_listing(self, account_name, lcontainer, lprefix,"},{"line_number":103,"context_line":"                                  req, failed_marker, failed_listing):"},{"line_number":104,"context_line":"        \u0027\u0027\u0027Get the complete prefix listing and reverse it on the proxy."},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        This is only necessary if we encounter a response from a"},{"line_number":107,"context_line":"        container-server that does not respect the ``reverse`` param"},{"line_number":108,"context_line":"        included by default in ``_listing_pages_iter``. This may happen"},{"line_number":109,"context_line":"        during rolling upgrades from pre-2.6.0 swift."},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"        :param failed_marker: the marker that was used when we encountered"},{"line_number":112,"context_line":"                              the non-reversed listing"},{"line_number":113,"context_line":"        :param failed_listing: the non-reversed listing that was encountered."},{"line_number":114,"context_line":"                               If ``failed_marker`` is blank, we can use this"},{"line_number":115,"context_line":"                               to save ourselves a request"},{"line_number":116,"context_line":"        :returns: an iterator over all objects starting with ``lprefix`` (up"},{"line_number":117,"context_line":"                  to but not including the failed marker) in reverse order"},{"line_number":118,"context_line":"        \u0027\u0027\u0027"},{"line_number":119,"context_line":"        complete_listing \u003d []"},{"line_number":120,"context_line":"        if not failed_marker:"},{"line_number":121,"context_line":"            # We\u0027ve never gotten a reversed listing. So save a request and"},{"line_number":122,"context_line":"            # use the failed listing."},{"line_number":123,"context_line":"            complete_listing.extend(failed_listing)"},{"line_number":124,"context_line":"            marker \u003d bytes_to_wsgi(complete_listing[-1][\u0027name\u0027].encode(\u0027utf8\u0027))"},{"line_number":125,"context_line":"        else:"},{"line_number":126,"context_line":"            # We\u0027ve gotten at least one reversed listing. Have to start at"},{"line_number":127,"context_line":"            # the beginning."},{"line_number":128,"context_line":"            marker \u003d \u0027\u0027"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"        # First, take the *entire* prefix listing into memory"},{"line_number":131,"context_line":"        try:"},{"line_number":132,"context_line":"            for page in self._listing_pages_iter("},{"line_number":133,"context_line":"                    account_name, lcontainer, lprefix,"},{"line_number":134,"context_line":"                    req, marker, end_marker\u003dfailed_marker, reverse\u003dFalse):"},{"line_number":135,"context_line":"                complete_listing.extend(page)"},{"line_number":136,"context_line":"        except ListingIterNotFound:"},{"line_number":137,"context_line":"            pass"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"        # Now that we\u0027ve got everything, return the whole listing as one giant"},{"line_number":140,"context_line":"        # reversed page"},{"line_number":141,"context_line":"        return reversed(complete_listing)"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"    def _listing_pages_iter(self, account_name, lcontainer, lprefix,"},{"line_number":144,"context_line":"                            req, marker\u003d\u0027\u0027, end_marker\u003d\u0027\u0027, reverse\u003dTrue):"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_2c1c3e13","line":141,"range":{"start_line":102,"start_character":4,"end_line":141,"end_character":41},"in_reply_to":"3fa7e38b_ce2e5e42","updated":"2019-12-17 01:30:58.000000000","message":"Removed in PS 6","commit_id":"f9bd19f1a5fc00f16cab33b1d142f72904a3e899"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1ceb9443f85a14839be2d229c14892f020f55e5e","unresolved":false,"context_lines":[{"line_number":728,"context_line":"            resp \u003d req.get_response(self.app)"},{"line_number":729,"context_line":""},{"line_number":730,"context_line":"            if SYSMETA_VERSION_ID in resp.headers:"},{"line_number":731,"context_line":"                resp.headers[\u0027version\u0027] \u003d resp.headers[SYSMETA_VERSION_ID]"},{"line_number":732,"context_line":""},{"line_number":733,"context_line":"            # Well, except for some delete marker business..."},{"line_number":734,"context_line":"            is_del_marker \u003d DELETE_MARKER_CONTENT_TYPE \u003d\u003d resp.headers.get("}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_9725d65e","line":731,"range":{"start_line":731,"start_character":42,"end_line":731,"end_character":74},"updated":"2019-09-24 18:23:01.000000000","message":"Will this ever *not* match the version arg?\n\nSeparately, I\u0027m not sure \u0027Version\u0027 is the best/most-descriptive header name -- I was originally thinking \u0027X-Object-Version\u0027 (being similar to \u0027X-Object-Meta-*\u0027 and \u0027X-Object-Sysmeta-*\u0027). Maybe I\u0027m just bike-shedding, though?","commit_id":"f9bd19f1a5fc00f16cab33b1d142f72904a3e899"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":728,"context_line":"            resp \u003d req.get_response(self.app)"},{"line_number":729,"context_line":""},{"line_number":730,"context_line":"            if SYSMETA_VERSION_ID in resp.headers:"},{"line_number":731,"context_line":"                resp.headers[\u0027version\u0027] \u003d resp.headers[SYSMETA_VERSION_ID]"},{"line_number":732,"context_line":""},{"line_number":733,"context_line":"            # Well, except for some delete marker business..."},{"line_number":734,"context_line":"            is_del_marker \u003d DELETE_MARKER_CONTENT_TYPE \u003d\u003d resp.headers.get("}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_6cd79624","line":731,"range":{"start_line":731,"start_character":42,"end_line":731,"end_character":74},"in_reply_to":"3fa7e38b_9725d65e","updated":"2019-12-17 01:30:58.000000000","message":"Addressed in PS ... 7, I think?","commit_id":"f9bd19f1a5fc00f16cab33b1d142f72904a3e899"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"b81bcd17789e43025e89c3d64e1181aa766b2c63","unresolved":false,"context_lines":[{"line_number":775,"context_line":"                        _, meta \u003d parse_header(item[\u0027hash\u0027])"},{"line_number":776,"context_line":"                        tgt_bytes \u003d int(item.pop(\u0027symlink_bytes\u0027))"},{"line_number":777,"context_line":"                        item[\u0027bytes\u0027] \u003d tgt_bytes"},{"line_number":778,"context_line":"                        item[\u0027version_symlink\u0027] \u003d True"},{"line_number":779,"context_line":"                        item[\u0027hash\u0027] \u003d item.pop(\u0027symlink_etag\u0027) + \u0027\u0027.join("},{"line_number":780,"context_line":"                            \u0027; %s\u003d%s\u0027 % (k, v) for k, v in meta.items())"},{"line_number":781,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3fa7e38b_9b140d46","line":778,"updated":"2019-09-25 04:17:41.000000000","message":"Should we drop symlink_path somewhere around here? particularly if we\u0027re going to use the client-inaccessible null namespace... idk that it\u0027s doing clients any favors to include it...","commit_id":"3fb204bf16e849d09174e9c52e47ab25187b41ed"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":775,"context_line":"                        _, meta \u003d parse_header(item[\u0027hash\u0027])"},{"line_number":776,"context_line":"                        tgt_bytes \u003d int(item.pop(\u0027symlink_bytes\u0027))"},{"line_number":777,"context_line":"                        item[\u0027bytes\u0027] \u003d tgt_bytes"},{"line_number":778,"context_line":"                        item[\u0027version_symlink\u0027] \u003d True"},{"line_number":779,"context_line":"                        item[\u0027hash\u0027] \u003d item.pop(\u0027symlink_etag\u0027) + \u0027\u0027.join("},{"line_number":780,"context_line":"                            \u0027; %s\u003d%s\u0027 % (k, v) for k, v in meta.items())"},{"line_number":781,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3fa7e38b_8cb532f0","line":778,"in_reply_to":"3fa7e38b_9b140d46","updated":"2019-12-17 01:30:58.000000000","message":"Addressed in PS 39.","commit_id":"3fb204bf16e849d09174e9c52e47ab25187b41ed"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"b81bcd17789e43025e89c3d64e1181aa766b2c63","unresolved":false,"context_lines":[{"line_number":824,"context_line":"        # exist will fail, we should avoid trying to create"},{"line_number":825,"context_line":"        # a container. or maybe we could create the versions"},{"line_number":826,"context_line":"        # container on the first object PUT?"},{"line_number":827,"context_line":"        if config_true_value(is_enabled) and not versions_cont:"},{"line_number":828,"context_line":"            (version, account, container, _) \u003d req.split_path(3, 4, True)"},{"line_number":829,"context_line":"            # TODO: choose correct policy, probably need to truncate"},{"line_number":830,"context_line":"            # container name"}],"source_content_type":"text/x-python","patch_set":6,"id":"3fa7e38b_0d822401","line":827,"range":{"start_line":827,"start_character":11,"end_line":827,"end_character":40},"updated":"2019-09-25 04:17:41.000000000","message":"Hmm... So if you jump straight from versioning-never-enabled to versioning-suspended ... we don\u0027t create the archive container, instead waiting for the client to \"re\"-enable it?\n\nDoes this have any impacts with our plan for recording DELETEs while suspended?","commit_id":"3fb204bf16e849d09174e9c52e47ab25187b41ed"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"44d6e37ffb15e59d7f5d68b1a9e2fbbb49ad9a8f","unresolved":false,"context_lines":[{"line_number":824,"context_line":"        # exist will fail, we should avoid trying to create"},{"line_number":825,"context_line":"        # a container. or maybe we could create the versions"},{"line_number":826,"context_line":"        # container on the first object PUT?"},{"line_number":827,"context_line":"        if config_true_value(is_enabled) and not versions_cont:"},{"line_number":828,"context_line":"            (version, account, container, _) \u003d req.split_path(3, 4, True)"},{"line_number":829,"context_line":"            # TODO: choose correct policy, probably need to truncate"},{"line_number":830,"context_line":"            # container name"}],"source_content_type":"text/x-python","patch_set":6,"id":"3fa7e38b_1ef80179","line":827,"range":{"start_line":827,"start_character":11,"end_line":827,"end_character":40},"in_reply_to":"3fa7e38b_0d822401","updated":"2019-09-27 08:23:10.000000000","message":"to me the definition of versioning-suspended is:\nis_enabled \u003d\u003d False AND versions_cont \u003d\u003d \u0027cont\\x01versions\u0027\n\nso if container never had a sysmeta-versions-location attached to it, it has never been enabled.","commit_id":"3fb204bf16e849d09174e9c52e47ab25187b41ed"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":824,"context_line":"        # exist will fail, we should avoid trying to create"},{"line_number":825,"context_line":"        # a container. or maybe we could create the versions"},{"line_number":826,"context_line":"        # container on the first object PUT?"},{"line_number":827,"context_line":"        if config_true_value(is_enabled) and not versions_cont:"},{"line_number":828,"context_line":"            (version, account, container, _) \u003d req.split_path(3, 4, True)"},{"line_number":829,"context_line":"            # TODO: choose correct policy, probably need to truncate"},{"line_number":830,"context_line":"            # container name"}],"source_content_type":"text/x-python","patch_set":6,"id":"3fa7e38b_ac5cae80","line":827,"range":{"start_line":827,"start_character":11,"end_line":827,"end_character":40},"in_reply_to":"3fa7e38b_1ef80179","updated":"2019-12-17 01:30:58.000000000","message":"...can a client determine that difference? As recently as PS 52, I\u0027m not sure they can :-/","commit_id":"3fb204bf16e849d09174e9c52e47ab25187b41ed"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":824,"context_line":"        # exist will fail, we should avoid trying to create"},{"line_number":825,"context_line":"        # a container. or maybe we could create the versions"},{"line_number":826,"context_line":"        # container on the first object PUT?"},{"line_number":827,"context_line":"        if config_true_value(is_enabled) and not versions_cont:"},{"line_number":828,"context_line":"            (version, account, container, _) \u003d req.split_path(3, 4, True)"},{"line_number":829,"context_line":"            # TODO: choose correct policy, probably need to truncate"},{"line_number":830,"context_line":"            # container name"}],"source_content_type":"text/x-python","patch_set":6,"id":"3fa7e38b_a6865f5e","line":827,"range":{"start_line":827,"start_character":11,"end_line":827,"end_character":40},"in_reply_to":"3fa7e38b_ac5cae80","updated":"2020-01-08 22:41:42.000000000","message":"OK, I think\n\n\u003e our plan for recording DELETEs while suspended\n\nis either S3-only, or some old misconception of mine. That\u0027s not a thing in this patch, anyway.\n\nI still think there may be value in setting versions_cont when suspending -- I think it\u0027ll make recovery from archive-exists-without-primary a bit easier.","commit_id":"3fb204bf16e849d09174e9c52e47ab25187b41ed"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"b81bcd17789e43025e89c3d64e1181aa766b2c63","unresolved":false,"context_lines":[{"line_number":852,"context_line":"        # make original request"},{"line_number":853,"context_line":"        app_resp \u003d self._app_call(req.environ)"},{"line_number":854,"context_line":""},{"line_number":855,"context_line":"        # if we just created a versions container but the original"},{"line_number":856,"context_line":"        # request failed, we need to delete the versions container"},{"line_number":857,"context_line":"        # and let user retry later"},{"line_number":858,"context_line":"        if not is_success(self._get_status_int()) and \\"},{"line_number":859,"context_line":"                SYSMETA_VERSIONS_CONT in req.headers:"},{"line_number":860,"context_line":"            # TODO: delete just created versions container"},{"line_number":861,"context_line":"            versions_cont_path \u003d \"/%s/%s/%s\" % ("},{"line_number":862,"context_line":"                version, account, versions_cont)"},{"line_number":863,"context_line":"            ver_cont_req \u003d make_pre_authed_request("},{"line_number":864,"context_line":"                req.environ, path\u003dwsgi_quote(versions_cont_path),"},{"line_number":865,"context_line":"                method\u003d\u0027DELETE\u0027, swift_source\u003d\u0027VW\u0027)"},{"line_number":866,"context_line":""},{"line_number":867,"context_line":"            # TODO: what if this one fails??"},{"line_number":868,"context_line":"            ver_cont_req.get_response(self.app)"},{"line_number":869,"context_line":""},{"line_number":870,"context_line":"        if self._response_headers is None:"},{"line_number":871,"context_line":"            self._response_headers \u003d []"}],"source_content_type":"text/x-python","patch_set":6,"id":"3fa7e38b_20d4c847","line":868,"range":{"start_line":855,"start_character":7,"end_line":868,"end_character":47},"updated":"2019-09-25 04:17:41.000000000","message":":-/ hmm... well *that\u0027s* an annoying edge case...","commit_id":"3fb204bf16e849d09174e9c52e47ab25187b41ed"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"44d6e37ffb15e59d7f5d68b1a9e2fbbb49ad9a8f","unresolved":false,"context_lines":[{"line_number":852,"context_line":"        # make original request"},{"line_number":853,"context_line":"        app_resp \u003d self._app_call(req.environ)"},{"line_number":854,"context_line":""},{"line_number":855,"context_line":"        # if we just created a versions container but the original"},{"line_number":856,"context_line":"        # request failed, we need to delete the versions container"},{"line_number":857,"context_line":"        # and let user retry later"},{"line_number":858,"context_line":"        if not is_success(self._get_status_int()) and \\"},{"line_number":859,"context_line":"                SYSMETA_VERSIONS_CONT in req.headers:"},{"line_number":860,"context_line":"            # TODO: delete just created versions container"},{"line_number":861,"context_line":"            versions_cont_path \u003d \"/%s/%s/%s\" % ("},{"line_number":862,"context_line":"                version, account, versions_cont)"},{"line_number":863,"context_line":"            ver_cont_req \u003d make_pre_authed_request("},{"line_number":864,"context_line":"                req.environ, path\u003dwsgi_quote(versions_cont_path),"},{"line_number":865,"context_line":"                method\u003d\u0027DELETE\u0027, swift_source\u003d\u0027VW\u0027)"},{"line_number":866,"context_line":""},{"line_number":867,"context_line":"            # TODO: what if this one fails??"},{"line_number":868,"context_line":"            ver_cont_req.get_response(self.app)"},{"line_number":869,"context_line":""},{"line_number":870,"context_line":"        if self._response_headers is None:"},{"line_number":871,"context_line":"            self._response_headers \u003d []"}],"source_content_type":"text/x-python","patch_set":6,"id":"3fa7e38b_1e7c811d","line":868,"range":{"start_line":855,"start_character":7,"end_line":868,"end_character":47},"in_reply_to":"3fa7e38b_20d4c847","updated":"2019-09-27 08:23:10.000000000","message":"yeah, but if we are going with a \"repeatable\" versions container name, then I won\u0027t feel so bad about having a dangling container there. Once user tries to enable versions on the container again we would just try to re-create the same container (of course we have the storage-policy problem)","commit_id":"3fb204bf16e849d09174e9c52e47ab25187b41ed"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"b81bcd17789e43025e89c3d64e1181aa766b2c63","unresolved":false,"context_lines":[{"line_number":879,"context_line":"                       self._response_exc_info)"},{"line_number":880,"context_line":"        return app_resp"},{"line_number":881,"context_line":""},{"line_number":882,"context_line":"    def _list_versions(self, req, start_response, location, primary_listing):"},{"line_number":883,"context_line":"        params \u003d req.params"},{"line_number":884,"context_line":"        if \u0027version_marker\u0027 in params:"},{"line_number":885,"context_line":"            if \u0027marker\u0027 not in params:"}],"source_content_type":"text/x-python","patch_set":6,"id":"3fa7e38b_c075b4cc","line":882,"updated":"2019-09-25 04:17:41.000000000","message":"...should this API be JSON-only? At the moment, it kinda supports text and xml... but they\u0027re not terribly useful, since they don\u0027t have version_id anywhere in them.","commit_id":"3fb204bf16e849d09174e9c52e47ab25187b41ed"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":879,"context_line":"                       self._response_exc_info)"},{"line_number":880,"context_line":"        return app_resp"},{"line_number":881,"context_line":""},{"line_number":882,"context_line":"    def _list_versions(self, req, start_response, location, primary_listing):"},{"line_number":883,"context_line":"        params \u003d req.params"},{"line_number":884,"context_line":"        if \u0027version_marker\u0027 in params:"},{"line_number":885,"context_line":"            if \u0027marker\u0027 not in params:"}],"source_content_type":"text/x-python","patch_set":6,"id":"3fa7e38b_8cd0d2ca","line":882,"in_reply_to":"3fa7e38b_c075b4cc","updated":"2019-12-17 01:30:58.000000000","message":"Addressed by PS 41 or so.","commit_id":"3fb204bf16e849d09174e9c52e47ab25187b41ed"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"41d5b31c27b1c37c7d4ec12c1587cd56d63d165a","unresolved":false,"context_lines":[{"line_number":630,"context_line":"        :param version: version of the object to act on"},{"line_number":631,"context_line":"        \"\"\""},{"line_number":632,"context_line":"        # ?version requests are allowed for GET, HEAD, DELETE reqs"},{"line_number":633,"context_line":"        # TODO is a POST allowed?"},{"line_number":634,"context_line":"        if req.method in (\u0027PUT\u0027, \u0027POST\u0027):"},{"line_number":635,"context_line":"            raise HTTPBadRequest("},{"line_number":636,"context_line":"                \u0027cannot PUT a specific version\u0027, request\u003dreq)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3fa7e38b_ca2cd903","line":633,"range":{"start_line":633,"start_character":8,"end_line":633,"end_character":33},"updated":"2019-09-25 20:56:31.000000000","message":"I was thinking yes... among other things, this lets you set/update expiration on a version.","commit_id":"21294d0e267677926715271f7a803fb63ce3139f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":630,"context_line":"        :param version: version of the object to act on"},{"line_number":631,"context_line":"        \"\"\""},{"line_number":632,"context_line":"        # ?version requests are allowed for GET, HEAD, DELETE reqs"},{"line_number":633,"context_line":"        # TODO is a POST allowed?"},{"line_number":634,"context_line":"        if req.method in (\u0027PUT\u0027, \u0027POST\u0027):"},{"line_number":635,"context_line":"            raise HTTPBadRequest("},{"line_number":636,"context_line":"                \u0027cannot PUT a specific version\u0027, request\u003dreq)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3fa7e38b_4c1c1a7b","line":633,"range":{"start_line":633,"start_character":8,"end_line":633,"end_character":33},"in_reply_to":"3fa7e38b_0ae2f1a0","updated":"2019-12-17 01:30:58.000000000","message":"Still blacklisted as of PS 52 -- I suppose it\u0027s easier to open up later than fully flesh-out now? Though the current expiry behavior is a little worrying to me.","commit_id":"21294d0e267677926715271f7a803fb63ce3139f"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"44d6e37ffb15e59d7f5d68b1a9e2fbbb49ad9a8f","unresolved":false,"context_lines":[{"line_number":630,"context_line":"        :param version: version of the object to act on"},{"line_number":631,"context_line":"        \"\"\""},{"line_number":632,"context_line":"        # ?version requests are allowed for GET, HEAD, DELETE reqs"},{"line_number":633,"context_line":"        # TODO is a POST allowed?"},{"line_number":634,"context_line":"        if req.method in (\u0027PUT\u0027, \u0027POST\u0027):"},{"line_number":635,"context_line":"            raise HTTPBadRequest("},{"line_number":636,"context_line":"                \u0027cannot PUT a specific version\u0027, request\u003dreq)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3fa7e38b_0ae2f1a0","line":633,"range":{"start_line":633,"start_character":8,"end_line":633,"end_character":33},"in_reply_to":"3fa7e38b_ca2cd903","updated":"2019-09-27 08:23:10.000000000","message":"I\u0027m a bit torn on this since we allowed it in versioned_writes. But again from a end-user feature PoV it seems to allow for circumvention of what the feature is trying to protect you from. If we treat metadata as \"data\", then previous versions should not be allowed to be modifed (and yes, I do understand there\u0027s the issue that we do allow for the current version). Also, FWIW, aws s3 does not allow posts to older versions AFAIK, only to the most current version.","commit_id":"21294d0e267677926715271f7a803fb63ce3139f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"41d5b31c27b1c37c7d4ec12c1587cd56d63d165a","unresolved":false,"context_lines":[{"line_number":674,"context_line":"                \u0027X-Backend-Content-Type\u0027, resp.headers[\u0027Content-Type\u0027])"},{"line_number":675,"context_line":""},{"line_number":676,"context_line":"            if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":677,"context_line":"                close_if_possible(resp.app_iter)"},{"line_number":678,"context_line":""},{"line_number":679,"context_line":"            # XXX: this is a weird flag to switch between 200/404 behavior..."},{"line_number":680,"context_line":"            if req.params.get(\u0027symlink\u0027) !\u003d \u0027get\u0027 and is_del_marker:"}],"source_content_type":"text/x-python","patch_set":8,"id":"3fa7e38b_ea0c35a6","line":677,"updated":"2019-09-25 20:56:31.000000000","message":"What handles the close when it\u0027s *not* a HEAD?","commit_id":"21294d0e267677926715271f7a803fb63ce3139f"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"44d6e37ffb15e59d7f5d68b1a9e2fbbb49ad9a8f","unresolved":false,"context_lines":[{"line_number":674,"context_line":"                \u0027X-Backend-Content-Type\u0027, resp.headers[\u0027Content-Type\u0027])"},{"line_number":675,"context_line":""},{"line_number":676,"context_line":"            if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":677,"context_line":"                close_if_possible(resp.app_iter)"},{"line_number":678,"context_line":""},{"line_number":679,"context_line":"            # XXX: this is a weird flag to switch between 200/404 behavior..."},{"line_number":680,"context_line":"            if req.params.get(\u0027symlink\u0027) !\u003d \u0027get\u0027 and is_del_marker:"}],"source_content_type":"text/x-python","patch_set":8,"id":"3fa7e38b_caf1396d","line":677,"in_reply_to":"3fa7e38b_ea0c35a6","updated":"2019-09-27 08:23:10.000000000","message":"I need to look into this better, this was a hack to get tests passing :(","commit_id":"21294d0e267677926715271f7a803fb63ce3139f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"41d5b31c27b1c37c7d4ec12c1587cd56d63d165a","unresolved":false,"context_lines":[{"line_number":892,"context_line":"        # NB: no reverse or end_marker support (yet)"},{"line_number":893,"context_line":"        versions_req.params \u003d {"},{"line_number":894,"context_line":"            k: params.get(k, \u0027\u0027)"},{"line_number":895,"context_line":"            for k in (\u0027prefix\u0027, \u0027marker\u0027, \u0027limit\u0027, \u0027delimiter\u0027, \u0027reverse\u0027)}"},{"line_number":896,"context_line":"        versions_resp \u003d versions_req.get_response(self.app)"},{"line_number":897,"context_line":"        if versions_resp.status_int \u003d\u003d HTTP_NOT_FOUND:"},{"line_number":898,"context_line":"            body \u003d json.dumps(null_listing).encode(\u0027ascii\u0027)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3fa7e38b_aa371d4d","line":895,"range":{"start_line":895,"start_character":65,"end_line":895,"end_character":72},"updated":"2019-09-25 20:56:31.000000000","message":"I worry about our merge strategy when doing reverse listings...","commit_id":"21294d0e267677926715271f7a803fb63ce3139f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bd0cc53a7e8c7efd515184737354a70ba066c280","unresolved":false,"context_lines":[{"line_number":857,"context_line":"            raise HTTPBadRequest(\u0027invalid delimiter param\u0027)"},{"line_number":858,"context_line":""},{"line_number":859,"context_line":"        null_listing \u003d []"},{"line_number":860,"context_line":"        has_current_version \u003d set()"},{"line_number":861,"context_line":"        current_versions \u003d set()"},{"line_number":862,"context_line":"        for item in primary_listing:"},{"line_number":863,"context_line":"            if \u0027name\u0027 in item:"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_8237394e","line":860,"range":{"start_line":860,"start_character":8,"end_line":860,"end_character":27},"updated":"2019-10-19 05:16:40.000000000","message":"I should probably rename this to something like \u0027has_null_version\u0027...","commit_id":"fc7a2f568456311271b39bd7dd1782fbb0648c9f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":857,"context_line":"            raise HTTPBadRequest(\u0027invalid delimiter param\u0027)"},{"line_number":858,"context_line":""},{"line_number":859,"context_line":"        null_listing \u003d []"},{"line_number":860,"context_line":"        has_current_version \u003d set()"},{"line_number":861,"context_line":"        current_versions \u003d set()"},{"line_number":862,"context_line":"        for item in primary_listing:"},{"line_number":863,"context_line":"            if \u0027name\u0027 in item:"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_470ab31e","line":860,"range":{"start_line":860,"start_character":8,"end_line":860,"end_character":27},"in_reply_to":"3fa7e38b_8237394e","updated":"2019-12-17 01:30:58.000000000","message":"Addressed in PS 16, but then things have moved on since PS 48 or so.","commit_id":"fc7a2f568456311271b39bd7dd1782fbb0648c9f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bd0cc53a7e8c7efd515184737354a70ba066c280","unresolved":false,"context_lines":[{"line_number":865,"context_line":"            # TODO: need to be able to de-dupe subdirs..."},{"line_number":866,"context_line":""},{"line_number":867,"context_line":"            if item.get(\u0027version_symlink\u0027):"},{"line_number":868,"context_line":"                current_versions.add(wsgi_unquote(item[\u0027symlink_path\u0027]))"},{"line_number":869,"context_line":"            else:"},{"line_number":870,"context_line":"                null_listing.append(dict("},{"line_number":871,"context_line":"                    item, version_id\u003d\u0027null\u0027, is_latest\u003dTrue))"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_e245cdb5","line":868,"range":{"start_line":868,"start_character":50,"end_line":868,"end_character":70},"updated":"2019-10-19 05:16:40.000000000","message":"Hey! That\u0027s no WSGI string!","commit_id":"fc7a2f568456311271b39bd7dd1782fbb0648c9f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":865,"context_line":"            # TODO: need to be able to de-dupe subdirs..."},{"line_number":866,"context_line":""},{"line_number":867,"context_line":"            if item.get(\u0027version_symlink\u0027):"},{"line_number":868,"context_line":"                current_versions.add(wsgi_unquote(item[\u0027symlink_path\u0027]))"},{"line_number":869,"context_line":"            else:"},{"line_number":870,"context_line":"                null_listing.append(dict("},{"line_number":871,"context_line":"                    item, version_id\u003d\u0027null\u0027, is_latest\u003dTrue))"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_a7f9271d","line":868,"range":{"start_line":868,"start_character":50,"end_line":868,"end_character":70},"in_reply_to":"3fa7e38b_e245cdb5","updated":"2019-12-17 01:30:58.000000000","message":"Addressed in... PS 19, I think?","commit_id":"fc7a2f568456311271b39bd7dd1782fbb0648c9f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bd0cc53a7e8c7efd515184737354a70ba066c280","unresolved":false,"context_lines":[{"line_number":899,"context_line":"                    if ts is None:"},{"line_number":900,"context_line":"                        continue"},{"line_number":901,"context_line":"                    path \u003d \u0027/v1/%s/%s/%s\u0027 % (account, location, item[\u0027name\u0027])"},{"line_number":902,"context_line":"                    item[\u0027is_latest\u0027] \u003d path in current_versions or ("},{"line_number":903,"context_line":"                        item[\u0027name\u0027] not in has_current_version and"},{"line_number":904,"context_line":"                        item[\u0027content_type\u0027] \u003d\u003d DELETE_MARKER_CONTENT_TYPE)"},{"line_number":905,"context_line":"                    item[\u0027name\u0027] \u003d name"},{"line_number":906,"context_line":"                    item[\u0027version_id\u0027] \u003d ts.internal"},{"line_number":907,"context_line":"                    versions_listing.append(item)"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_223c452f","line":904,"range":{"start_line":902,"start_character":68,"end_line":904,"end_character":75},"updated":"2019-10-19 05:16:40.000000000","message":"This still isn\u0027t quite precise enough. Need to consider the possibility of having multiple delete markers -- only one can have is_latest\u003dTrue.","commit_id":"fc7a2f568456311271b39bd7dd1782fbb0648c9f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":899,"context_line":"                    if ts is None:"},{"line_number":900,"context_line":"                        continue"},{"line_number":901,"context_line":"                    path \u003d \u0027/v1/%s/%s/%s\u0027 % (account, location, item[\u0027name\u0027])"},{"line_number":902,"context_line":"                    item[\u0027is_latest\u0027] \u003d path in current_versions or ("},{"line_number":903,"context_line":"                        item[\u0027name\u0027] not in has_current_version and"},{"line_number":904,"context_line":"                        item[\u0027content_type\u0027] \u003d\u003d DELETE_MARKER_CONTENT_TYPE)"},{"line_number":905,"context_line":"                    item[\u0027name\u0027] \u003d name"},{"line_number":906,"context_line":"                    item[\u0027version_id\u0027] \u003d ts.internal"},{"line_number":907,"context_line":"                    versions_listing.append(item)"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_87218ba1","line":904,"range":{"start_line":902,"start_character":68,"end_line":904,"end_character":75},"in_reply_to":"3fa7e38b_223c452f","updated":"2019-12-17 01:30:58.000000000","message":"I think this was addressed by the latest_del_marker work... though I don\u0027t think that\u0027s quite up to snuff yet, either :-/","commit_id":"fc7a2f568456311271b39bd7dd1782fbb0648c9f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":899,"context_line":"                    if ts is None:"},{"line_number":900,"context_line":"                        continue"},{"line_number":901,"context_line":"                    path \u003d \u0027/v1/%s/%s/%s\u0027 % (account, location, item[\u0027name\u0027])"},{"line_number":902,"context_line":"                    item[\u0027is_latest\u0027] \u003d path in current_versions or ("},{"line_number":903,"context_line":"                        item[\u0027name\u0027] not in has_current_version and"},{"line_number":904,"context_line":"                        item[\u0027content_type\u0027] \u003d\u003d DELETE_MARKER_CONTENT_TYPE)"},{"line_number":905,"context_line":"                    item[\u0027name\u0027] \u003d name"},{"line_number":906,"context_line":"                    item[\u0027version_id\u0027] \u003d ts.internal"},{"line_number":907,"context_line":"                    versions_listing.append(item)"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_86e00329","line":904,"range":{"start_line":902,"start_character":68,"end_line":904,"end_character":75},"in_reply_to":"3fa7e38b_87218ba1","updated":"2020-01-08 22:41:42.000000000","message":"Pretty sure any lingering bad got addressed when we squashed in https://review.opendev.org/#/c/701334/2 in patchset 69.","commit_id":"fc7a2f568456311271b39bd7dd1782fbb0648c9f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bd0cc53a7e8c7efd515184737354a70ba066c280","unresolved":false,"context_lines":[{"line_number":905,"context_line":"                    item[\u0027name\u0027] \u003d name"},{"line_number":906,"context_line":"                    item[\u0027version_id\u0027] \u003d ts.internal"},{"line_number":907,"context_line":"                    versions_listing.append(item)"},{"line_number":908,"context_line":"                if six.PY2:"},{"line_number":909,"context_line":"                    body \u003d json.dumps(list(heapq.merge("},{"line_number":910,"context_line":"                        null_listing, versions_listing))).encode(\u0027ascii\u0027)"},{"line_number":911,"context_line":"                else:"},{"line_number":912,"context_line":"                    body \u003d json.dumps(list(heapq.merge("},{"line_number":913,"context_line":"                        null_listing, versions_listing,"},{"line_number":914,"context_line":"                        key\u003dlambda item: item[\u0027name\u0027]))).encode(\u0027ascii\u0027)"},{"line_number":915,"context_line":"                self.update_content_length(len(body))"},{"line_number":916,"context_line":"                app_resp \u003d [body]"},{"line_number":917,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_a22835ee","line":914,"range":{"start_line":908,"start_character":16,"end_line":914,"end_character":72},"updated":"2019-10-19 05:16:40.000000000","message":"Hmm :-/\n\nI need to look at cribbing my splice_listings() from https://review.opendev.org/#/c/678962/3/swift/common/middleware/versioned_writes.py and updating it to not barf on subdirs...","commit_id":"fc7a2f568456311271b39bd7dd1782fbb0648c9f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":905,"context_line":"                    item[\u0027name\u0027] \u003d name"},{"line_number":906,"context_line":"                    item[\u0027version_id\u0027] \u003d ts.internal"},{"line_number":907,"context_line":"                    versions_listing.append(item)"},{"line_number":908,"context_line":"                if six.PY2:"},{"line_number":909,"context_line":"                    body \u003d json.dumps(list(heapq.merge("},{"line_number":910,"context_line":"                        null_listing, versions_listing))).encode(\u0027ascii\u0027)"},{"line_number":911,"context_line":"                else:"},{"line_number":912,"context_line":"                    body \u003d json.dumps(list(heapq.merge("},{"line_number":913,"context_line":"                        null_listing, versions_listing,"},{"line_number":914,"context_line":"                        key\u003dlambda item: item[\u0027name\u0027]))).encode(\u0027ascii\u0027)"},{"line_number":915,"context_line":"                self.update_content_length(len(body))"},{"line_number":916,"context_line":"                app_resp \u003d [body]"},{"line_number":917,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa7e38b_a7e3673a","line":914,"range":{"start_line":908,"start_character":16,"end_line":914,"end_character":72},"in_reply_to":"3fa7e38b_a22835ee","updated":"2019-12-17 01:30:58.000000000","message":"Addressed in PS 37 (I think).","commit_id":"fc7a2f568456311271b39bd7dd1782fbb0648c9f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c37b3d00ce2a542aba6485ab2b04ddcf677b98bc","unresolved":false,"context_lines":[{"line_number":75,"context_line":"        self.logger \u003d logger"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def _build_versions_object_prefix(self, object_name):"},{"line_number":78,"context_line":"        return get_reserved_name(object_name, \u0027\u0027)"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def _build_versions_container_name(self, container_name):"},{"line_number":81,"context_line":"        return get_reserved_name(\u0027versions\u0027, container_name)"}],"source_content_type":"text/x-python","patch_set":18,"id":"3fa7e38b_935be3f4","line":78,"range":{"start_line":78,"start_character":15,"end_line":78,"end_character":32},"updated":"2019-10-22 21:02:23.000000000","message":"This always returns unicode on py2, though, yeah? I\u0027d been assuming these helpers would deal in native strings :-/ (or possibly WSGI strings -- our choice of reserved char means the distinction shouldn\u0027t matter)","commit_id":"d70fe26fbbc789007435f9f63f8cd7aa6dec09a9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":75,"context_line":"        self.logger \u003d logger"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def _build_versions_object_prefix(self, object_name):"},{"line_number":78,"context_line":"        return get_reserved_name(object_name, \u0027\u0027)"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def _build_versions_container_name(self, container_name):"},{"line_number":81,"context_line":"        return get_reserved_name(\u0027versions\u0027, container_name)"}],"source_content_type":"text/x-python","patch_set":18,"id":"3fa7e38b_473393f8","line":78,"range":{"start_line":78,"start_character":15,"end_line":78,"end_character":32},"in_reply_to":"3fa7e38b_935be3f4","updated":"2019-12-17 01:30:58.000000000","message":"No longer true as of https://review.opendev.org/#/c/682138/18/ -- get_reserved_name returns str on both py2 and py3.","commit_id":"d70fe26fbbc789007435f9f63f8cd7aa6dec09a9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c37b3d00ce2a542aba6485ab2b04ddcf677b98bc","unresolved":false,"context_lines":[{"line_number":90,"context_line":"            ts \u003d ~Timestamp(inv)"},{"line_number":91,"context_line":"        except ValueError:"},{"line_number":92,"context_line":"            return versioned_name, None"},{"line_number":93,"context_line":"        return name, ts"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"class ObjectContext(ObjectVersioningContext):"}],"source_content_type":"text/x-python","patch_set":18,"id":"3fa7e38b_1367f3b9","line":93,"range":{"start_line":93,"start_character":15,"end_line":93,"end_character":19},"updated":"2019-10-22 21:02:23.000000000","message":"I think this will come out unicode, too...","commit_id":"d70fe26fbbc789007435f9f63f8cd7aa6dec09a9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":90,"context_line":"            ts \u003d ~Timestamp(inv)"},{"line_number":91,"context_line":"        except ValueError:"},{"line_number":92,"context_line":"            return versioned_name, None"},{"line_number":93,"context_line":"        return name, ts"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"class ObjectContext(ObjectVersioningContext):"}],"source_content_type":"text/x-python","patch_set":18,"id":"3fa7e38b_072d9b8e","line":93,"range":{"start_line":93,"start_character":15,"end_line":93,"end_character":19},"in_reply_to":"3fa7e38b_1367f3b9","updated":"2019-12-17 01:30:58.000000000","message":"Also resolved in parent patch.","commit_id":"d70fe26fbbc789007435f9f63f8cd7aa6dec09a9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c37b3d00ce2a542aba6485ab2b04ddcf677b98bc","unresolved":false,"context_lines":[{"line_number":847,"context_line":"                params[\u0027marker\u0027]) + \u0027:\u0027  # just past all numbers"},{"line_number":848,"context_line":""},{"line_number":849,"context_line":"        delim \u003d params.get(\u0027delimiter\u0027, \u0027\u0027)"},{"line_number":850,"context_line":"        # XXX WTF is this?"},{"line_number":851,"context_line":"        if set(delim).intersection(\u00270123456789.%s\u0027 % RESERVED_STR):"},{"line_number":852,"context_line":"            raise HTTPBadRequest(\u0027invalid delimiter param\u0027)"},{"line_number":853,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"3fa7e38b_f3bd7702","line":850,"updated":"2019-10-22 21:02:23.000000000","message":"?delimiter\u003d8 queries will get weird if you\u0027ve got some objects like\n\n /v1/a/%00versions%00c/%00foo%008428222459.07840\n\nYou\u0027d get a subdir entry that has some *portion* of a timestamp in it :-/","commit_id":"d70fe26fbbc789007435f9f63f8cd7aa6dec09a9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":847,"context_line":"                params[\u0027marker\u0027]) + \u0027:\u0027  # just past all numbers"},{"line_number":848,"context_line":""},{"line_number":849,"context_line":"        delim \u003d params.get(\u0027delimiter\u0027, \u0027\u0027)"},{"line_number":850,"context_line":"        # XXX WTF is this?"},{"line_number":851,"context_line":"        if set(delim).intersection(\u00270123456789.%s\u0027 % RESERVED_STR):"},{"line_number":852,"context_line":"            raise HTTPBadRequest(\u0027invalid delimiter param\u0027)"},{"line_number":853,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"3fa7e38b_c74c6377","line":850,"in_reply_to":"3fa7e38b_f3bd7702","updated":"2019-12-17 01:30:58.000000000","message":"Comment added explaining it in PS 19.","commit_id":"d70fe26fbbc789007435f9f63f8cd7aa6dec09a9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c37b3d00ce2a542aba6485ab2b04ddcf677b98bc","unresolved":false,"context_lines":[{"line_number":899,"context_line":"                        wsgi_quote(bytes_to_wsgi(item[\u0027name\u0027].encode(\u0027utf8\u0027))))"},{"line_number":900,"context_line":"                    \u0027\u0027\u0027"},{"line_number":901,"context_line":"                    path \u003d wsgi_unquote("},{"line_number":902,"context_line":"                        \u0027/v1/%s/%s/%s\u0027 % (account, location, item[\u0027name\u0027]))"},{"line_number":903,"context_line":"                    item[\u0027is_latest\u0027] \u003d path in current_versions or ("},{"line_number":904,"context_line":"                        item[\u0027name\u0027] not in has_null_version"},{"line_number":905,"context_line":"                        and item[\u0027content_type\u0027] \u003d\u003d DELETE_MARKER_CONTENT_TYPE)"}],"source_content_type":"text/x-python","patch_set":18,"id":"3fa7e38b_134e1338","line":902,"range":{"start_line":902,"start_character":61,"end_line":902,"end_character":73},"updated":"2019-10-22 21:02:23.000000000","message":"Wait... item[\u0027name\u0027] is *quoted*?","commit_id":"d70fe26fbbc789007435f9f63f8cd7aa6dec09a9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":899,"context_line":"                        wsgi_quote(bytes_to_wsgi(item[\u0027name\u0027].encode(\u0027utf8\u0027))))"},{"line_number":900,"context_line":"                    \u0027\u0027\u0027"},{"line_number":901,"context_line":"                    path \u003d wsgi_unquote("},{"line_number":902,"context_line":"                        \u0027/v1/%s/%s/%s\u0027 % (account, location, item[\u0027name\u0027]))"},{"line_number":903,"context_line":"                    item[\u0027is_latest\u0027] \u003d path in current_versions or ("},{"line_number":904,"context_line":"                        item[\u0027name\u0027] not in has_null_version"},{"line_number":905,"context_line":"                        and item[\u0027content_type\u0027] \u003d\u003d DELETE_MARKER_CONTENT_TYPE)"}],"source_content_type":"text/x-python","patch_set":18,"id":"3fa7e38b_47bdd301","line":902,"range":{"start_line":902,"start_character":61,"end_line":902,"end_character":73},"in_reply_to":"3fa7e38b_134e1338","updated":"2019-12-17 01:30:58.000000000","message":"I\u0027m *pretty sure* this got addressed... somewhere along the line...","commit_id":"d70fe26fbbc789007435f9f63f8cd7aa6dec09a9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"24d13a18a703f8e1c37a7bc53ca532665bf88a90","unresolved":false,"context_lines":[{"line_number":921,"context_line":"        Only after disabling versioning and deleting *all* object versions"},{"line_number":922,"context_line":"        can a container be deleted."},{"line_number":923,"context_line":"        \"\"\""},{"line_number":924,"context_line":"        container_info \u003d get_container_info(req.environ, self.app)"},{"line_number":925,"context_line":""},{"line_number":926,"context_line":"        versions_cont \u003d unquote(container_info.get("},{"line_number":927,"context_line":"            \u0027sysmeta\u0027, {}).get(\u0027versions-container\u0027, \u0027\u0027))"}],"source_content_type":"text/x-python","patch_set":30,"id":"3fa7e38b_ff8f4a1f","line":924,"updated":"2019-11-15 06:43:37.000000000","message":"Oh... I think this is breaking the test_locked_container_dbs probe test...\n\nCan repro the failure locally, anyway.","commit_id":"f073318333cbce990e114197a3f0829517a60d95"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":921,"context_line":"        Only after disabling versioning and deleting *all* object versions"},{"line_number":922,"context_line":"        can a container be deleted."},{"line_number":923,"context_line":"        \"\"\""},{"line_number":924,"context_line":"        container_info \u003d get_container_info(req.environ, self.app)"},{"line_number":925,"context_line":""},{"line_number":926,"context_line":"        versions_cont \u003d unquote(container_info.get("},{"line_number":927,"context_line":"            \u0027sysmeta\u0027, {}).get(\u0027versions-container\u0027, \u0027\u0027))"}],"source_content_type":"text/x-python","patch_set":30,"id":"3fa7e38b_0cdce2df","line":924,"in_reply_to":"3fa7e38b_ff8f4a1f","updated":"2019-12-17 01:30:58.000000000","message":"Probe tests were passing again by PS 35.","commit_id":"f073318333cbce990e114197a3f0829517a60d95"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"6b55b056808112f4d6094381291e73c3659afae9","unresolved":false,"context_lines":[{"line_number":931,"context_line":"        if config_true_value(is_enabled):"},{"line_number":932,"context_line":"            raise HTTPBadRequest("},{"line_number":933,"context_line":"                \u0027Disable object versioning and delete all \u0027"},{"line_number":934,"context_line":"                \u0027versions to delete container.\u0027,"},{"line_number":935,"context_line":"                request\u003dreq)"},{"line_number":936,"context_line":"        elif versions_cont:"},{"line_number":937,"context_line":"            account \u003d req.split_path(3, 3, True)[1]"}],"source_content_type":"text/x-python","patch_set":30,"id":"3fa7e38b_df284eef","line":934,"updated":"2019-11-15 07:06:04.000000000","message":"Does AWS have a similar requirement? Or can you delete buckets while versioning is enabled, provided all versions have been deleted?\n\nAs things stand, the next patch needs to suspend versioning as part of its func-test cleanup.","commit_id":"f073318333cbce990e114197a3f0829517a60d95"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":931,"context_line":"        if config_true_value(is_enabled):"},{"line_number":932,"context_line":"            raise HTTPBadRequest("},{"line_number":933,"context_line":"                \u0027Disable object versioning and delete all \u0027"},{"line_number":934,"context_line":"                \u0027versions to delete container.\u0027,"},{"line_number":935,"context_line":"                request\u003dreq)"},{"line_number":936,"context_line":"        elif versions_cont:"},{"line_number":937,"context_line":"            account \u003d req.split_path(3, 3, True)[1]"}],"source_content_type":"text/x-python","patch_set":30,"id":"3fa7e38b_6ce476a9","line":934,"in_reply_to":"3fa7e38b_df284eef","updated":"2019-12-17 01:30:58.000000000","message":"Requirement removed in PS 32.","commit_id":"f073318333cbce990e114197a3f0829517a60d95"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"48f0160fa30098d77f68c579fa0193aa7aba2d76","unresolved":false,"context_lines":[{"line_number":895,"context_line":"                        item[\u0027hash\u0027] \u003d item.pop(\u0027symlink_etag\u0027) + \u0027\u0027.join("},{"line_number":896,"context_line":"                            \u0027; %s\u003d%s\u0027 % (k, v) for k, v in meta.items())"},{"line_number":897,"context_line":""},{"line_number":898,"context_line":"                    if \u0027versions\u0027 in req.params:"},{"line_number":899,"context_line":"                        return self._list_versions("},{"line_number":900,"context_line":"                            req, start_response, location,"},{"line_number":901,"context_line":"                            listing)"}],"source_content_type":"text/x-python","patch_set":31,"id":"3fa7e38b_9f6ad6ea","line":898,"updated":"2019-11-15 07:28:24.000000000","message":"Hmm... so we only even look for the \u0027versions\u0027 param if versioning is enabled or suspended...\n\nWhat do you all think about serving a version-aware listing even when the container has *never had* its versioning status changed?","commit_id":"55e22ce89c2538edaf871b690342c6137f50e3e6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":895,"context_line":"                        item[\u0027hash\u0027] \u003d item.pop(\u0027symlink_etag\u0027) + \u0027\u0027.join("},{"line_number":896,"context_line":"                            \u0027; %s\u003d%s\u0027 % (k, v) for k, v in meta.items())"},{"line_number":897,"context_line":""},{"line_number":898,"context_line":"                    if \u0027versions\u0027 in req.params:"},{"line_number":899,"context_line":"                        return self._list_versions("},{"line_number":900,"context_line":"                            req, start_response, location,"},{"line_number":901,"context_line":"                            listing)"}],"source_content_type":"text/x-python","patch_set":31,"id":"3fa7e38b_a795a796","line":898,"in_reply_to":"3fa7e38b_9f6ad6ea","updated":"2019-12-17 01:30:58.000000000","message":"Support for version-aware listings against un-versioned containers added in PS 37.","commit_id":"55e22ce89c2538edaf871b690342c6137f50e3e6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e2267cf8c9d02ca4e8f0f05ea55b3fb28377546b","unresolved":false,"context_lines":[{"line_number":1107,"context_line":"            for k in (\u0027prefix\u0027, \u0027marker\u0027, \u0027limit\u0027, \u0027delimiter\u0027, \u0027reverse\u0027)}"},{"line_number":1108,"context_line":"        versions_resp \u003d versions_req.get_response(self.app)"},{"line_number":1109,"context_line":"        if versions_resp.status_int \u003d\u003d HTTP_NOT_FOUND:"},{"line_number":1110,"context_line":"            body \u003d json.dumps(null_listing).encode(\u0027ascii\u0027)"},{"line_number":1111,"context_line":"            self.update_content_length(len(body))"},{"line_number":1112,"context_line":"            app_resp \u003d [body]"},{"line_number":1113,"context_line":"            close_if_possible(versions_resp.app_iter)"}],"source_content_type":"text/x-python","patch_set":31,"id":"3fa7e38b_ceb177e2","line":1110,"range":{"start_line":1110,"start_character":30,"end_line":1110,"end_character":42},"updated":"2019-11-16 22:16:13.000000000","message":"Needs subdirs -- should probably also include busted symlinks?","commit_id":"55e22ce89c2538edaf871b690342c6137f50e3e6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":1107,"context_line":"            for k in (\u0027prefix\u0027, \u0027marker\u0027, \u0027limit\u0027, \u0027delimiter\u0027, \u0027reverse\u0027)}"},{"line_number":1108,"context_line":"        versions_resp \u003d versions_req.get_response(self.app)"},{"line_number":1109,"context_line":"        if versions_resp.status_int \u003d\u003d HTTP_NOT_FOUND:"},{"line_number":1110,"context_line":"            body \u003d json.dumps(null_listing).encode(\u0027ascii\u0027)"},{"line_number":1111,"context_line":"            self.update_content_length(len(body))"},{"line_number":1112,"context_line":"            app_resp \u003d [body]"},{"line_number":1113,"context_line":"            close_if_possible(versions_resp.app_iter)"}],"source_content_type":"text/x-python","patch_set":31,"id":"3fa7e38b_c79a23c3","line":1110,"range":{"start_line":1110,"start_character":30,"end_line":1110,"end_character":42},"in_reply_to":"3fa7e38b_ceb177e2","updated":"2019-12-17 01:30:58.000000000","message":"Addressed in PS 37.","commit_id":"55e22ce89c2538edaf871b690342c6137f50e3e6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e2267cf8c9d02ca4e8f0f05ea55b3fb28377546b","unresolved":false,"context_lines":[{"line_number":1138,"context_line":"                        item[\u0027is_latest\u0027] \u003d path in current_versions or ("},{"line_number":1139,"context_line":"                            item[\u0027name\u0027] not in has_null_version"},{"line_number":1140,"context_line":"                            and item[\u0027content_type\u0027] \u003d\u003d"},{"line_number":1141,"context_line":"                            DELETE_MARKER_CONTENT_TYPE)"},{"line_number":1142,"context_line":"                        item[\u0027name\u0027] \u003d name"},{"line_number":1143,"context_line":"                        item[\u0027version_id\u0027] \u003d ts.internal"},{"line_number":1144,"context_line":"                        versions_listing.append(item)"}],"source_content_type":"text/x-python","patch_set":31,"id":"3fa7e38b_ee1233b4","line":1141,"updated":"2019-11-16 22:16:13.000000000","message":"When we find a current version, we should remove it from the set -- then after this loop, make another list for busted symlinks and splice that in, too.","commit_id":"55e22ce89c2538edaf871b690342c6137f50e3e6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":1138,"context_line":"                        item[\u0027is_latest\u0027] \u003d path in current_versions or ("},{"line_number":1139,"context_line":"                            item[\u0027name\u0027] not in has_null_version"},{"line_number":1140,"context_line":"                            and item[\u0027content_type\u0027] \u003d\u003d"},{"line_number":1141,"context_line":"                            DELETE_MARKER_CONTENT_TYPE)"},{"line_number":1142,"context_line":"                        item[\u0027name\u0027] \u003d name"},{"line_number":1143,"context_line":"                        item[\u0027version_id\u0027] \u003d ts.internal"},{"line_number":1144,"context_line":"                        versions_listing.append(item)"}],"source_content_type":"text/x-python","patch_set":31,"id":"3fa7e38b_27a9b7dd","line":1141,"in_reply_to":"3fa7e38b_ee1233b4","updated":"2019-12-17 01:30:58.000000000","message":"Mostly addressed in PS 37... but I think I was a little sloppy, and that\u0027s why we can get doubled-up is_active entries today :-/","commit_id":"55e22ce89c2538edaf871b690342c6137f50e3e6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e2267cf8c9d02ca4e8f0f05ea55b3fb28377546b","unresolved":false,"context_lines":[{"line_number":1155,"context_line":"                    elif \u0027subdir\u0027 in item:"},{"line_number":1156,"context_line":"                        return item[\u0027subdir\u0027]"},{"line_number":1157,"context_line":"                    else:"},{"line_number":1158,"context_line":"                        return None"},{"line_number":1159,"context_line":"                if six.PY2:"},{"line_number":1160,"context_line":"                    body \u003d json.dumps(sorted(itertools.chain("},{"line_number":1161,"context_line":"                        null_listing, versions_listing,"}],"source_content_type":"text/x-python","patch_set":31,"id":"3fa7e38b_0e7d4fe6","line":1158,"updated":"2019-11-16 22:16:13.000000000","message":"This should never happen, though, right? I think I\u0027d be ok with failing more loudly/obviously.","commit_id":"55e22ce89c2538edaf871b690342c6137f50e3e6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":1155,"context_line":"                    elif \u0027subdir\u0027 in item:"},{"line_number":1156,"context_line":"                        return item[\u0027subdir\u0027]"},{"line_number":1157,"context_line":"                    else:"},{"line_number":1158,"context_line":"                        return None"},{"line_number":1159,"context_line":"                if six.PY2:"},{"line_number":1160,"context_line":"                    body \u003d json.dumps(sorted(itertools.chain("},{"line_number":1161,"context_line":"                        null_listing, versions_listing,"}],"source_content_type":"text/x-python","patch_set":31,"id":"3fa7e38b_478f1376","line":1158,"in_reply_to":"3fa7e38b_0e7d4fe6","updated":"2019-12-17 01:30:58.000000000","message":"Addressed in PS 37, when I brought back in build_listing()","commit_id":"55e22ce89c2538edaf871b690342c6137f50e3e6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e2267cf8c9d02ca4e8f0f05ea55b3fb28377546b","unresolved":false,"context_lines":[{"line_number":1162,"context_line":"                        subdir_listing), key\u003dmerge_key,"},{"line_number":1163,"context_line":"                        reverse\u003dreverse)).encode(\u0027ascii\u0027)"},{"line_number":1164,"context_line":"                else:"},{"line_number":1165,"context_line":"                    body \u003d json.dumps(list(heapq.merge("},{"line_number":1166,"context_line":"                        null_listing, versions_listing, subdir_listing,"},{"line_number":1167,"context_line":"                        key\u003dmerge_key, reverse\u003dreverse))).encode(\u0027ascii\u0027)"},{"line_number":1168,"context_line":"                self.update_content_length(len(body))"}],"source_content_type":"text/x-python","patch_set":31,"id":"3fa7e38b_6e264319","line":1165,"range":{"start_line":1165,"start_character":43,"end_line":1165,"end_character":54},"updated":"2019-11-16 22:16:13.000000000","message":"As the number of listings to splice grows, I wonder how much it\u0027s worth continuing trying to use this... maybe we should always do the sorted chain... timings seem to agree:\n\n $ python2 -m timeit -s \u0027import heapq, itertools, random; listings \u003d [sorted(random.randint(1,10000) for _ in range(1000)) for _ in range(5)]\u0027 \\\n \u0027list(heapq.merge(*listings))\u0027\n 1000 loops, best of 3: 1.31 msec per loop\n $ python2 -m timeit -s \u0027import heapq, itertools, random; listings \u003d [sorted(random.randint(1,10000) for _ in range(1000)) for _ in range(5)]\u0027 \\\n \u0027sorted(item for listing in listings for item in listing)\u0027\n 1000 loops, best of 3: 286 usec per loop\n $ python3 -m timeit -s \u0027import heapq, itertools, random; listings \u003d [sorted(random.randint(1,10000) for _ in range(1000)) for _ in range(5)]\u0027 \\\n \u0027list(heapq.merge(*listings))\u0027\n 1000 loops, best of 3: 1.04 msec per loop\n $ python3 -m timeit -s \u0027import heapq, itertools, random; listings \u003d [sorted(random.randint(1,10000) for _ in range(1000)) for _ in range(5)]\u0027 \\\n \u0027sorted(item for listing in listings for item in listing)\u0027\n 1000 loops, best of 3: 312 usec per loop","commit_id":"55e22ce89c2538edaf871b690342c6137f50e3e6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":1162,"context_line":"                        subdir_listing), key\u003dmerge_key,"},{"line_number":1163,"context_line":"                        reverse\u003dreverse)).encode(\u0027ascii\u0027)"},{"line_number":1164,"context_line":"                else:"},{"line_number":1165,"context_line":"                    body \u003d json.dumps(list(heapq.merge("},{"line_number":1166,"context_line":"                        null_listing, versions_listing, subdir_listing,"},{"line_number":1167,"context_line":"                        key\u003dmerge_key, reverse\u003dreverse))).encode(\u0027ascii\u0027)"},{"line_number":1168,"context_line":"                self.update_content_length(len(body))"}],"source_content_type":"text/x-python","patch_set":31,"id":"3fa7e38b_e78b9f66","line":1165,"range":{"start_line":1165,"start_character":43,"end_line":1165,"end_character":54},"in_reply_to":"3fa7e38b_6e264319","updated":"2019-12-17 01:30:58.000000000","message":"Addressed in PS 37.","commit_id":"55e22ce89c2538edaf871b690342c6137f50e3e6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"cc7acf485eb94063c21bc65485c5d42157958d77","unresolved":false,"context_lines":[{"line_number":914,"context_line":"                        \u0027; %s\u003d%s\u0027 % (k, v) for k, v in meta.items())"},{"line_number":915,"context_line":"                    tgt_obj, version \u003d self._split_version_from_name(tgt_obj)"},{"line_number":916,"context_line":"                    if version is not None and \u0027versions\u0027 not in req.params:"},{"line_number":917,"context_line":"                        sp \u003d \u0027/v1/%s/%s/%s?version-id\u003d%s\u0027 % ("},{"line_number":918,"context_line":"                            tgt_acct, container, tgt_obj,"},{"line_number":919,"context_line":"                            version.internal)"},{"line_number":920,"context_line":"                        item[\u0027symlink_path\u0027] \u003d sp"},{"line_number":921,"context_line":""},{"line_number":922,"context_line":"                if \u0027versions\u0027 in req.params:"},{"line_number":923,"context_line":"                    return self._list_versions("}],"source_content_type":"text/x-python","patch_set":40,"id":"3fa7e38b_00f5e550","line":920,"range":{"start_line":917,"start_character":24,"end_line":920,"end_character":49},"updated":"2019-11-21 00:20:44.000000000","message":"tgt_obj came out of path, so it\u0027s unquoted, yeah? We probably ought to quote a/c/o -- otherwise:\n\n* it\u0027ll be inconsistent with the existing symlink_path behavior (which has it quoted) and\n* there will be problems when containers or objects include question marks (among other chars).","commit_id":"212a6cb43be190a990ac2c4e44ccfd925201b588"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":914,"context_line":"                        \u0027; %s\u003d%s\u0027 % (k, v) for k, v in meta.items())"},{"line_number":915,"context_line":"                    tgt_obj, version \u003d self._split_version_from_name(tgt_obj)"},{"line_number":916,"context_line":"                    if version is not None and \u0027versions\u0027 not in req.params:"},{"line_number":917,"context_line":"                        sp \u003d \u0027/v1/%s/%s/%s?version-id\u003d%s\u0027 % ("},{"line_number":918,"context_line":"                            tgt_acct, container, tgt_obj,"},{"line_number":919,"context_line":"                            version.internal)"},{"line_number":920,"context_line":"                        item[\u0027symlink_path\u0027] \u003d sp"},{"line_number":921,"context_line":""},{"line_number":922,"context_line":"                if \u0027versions\u0027 in req.params:"},{"line_number":923,"context_line":"                    return self._list_versions("}],"source_content_type":"text/x-python","patch_set":40,"id":"3fa7e38b_07defb69","line":920,"range":{"start_line":917,"start_character":24,"end_line":920,"end_character":49},"in_reply_to":"3fa7e38b_00f5e550","updated":"2019-12-17 01:30:58.000000000","message":"Addressed in PS 41.","commit_id":"212a6cb43be190a990ac2c4e44ccfd925201b588"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7637576183b93d75137b86eb49d35468bdacf336","unresolved":false,"context_lines":[{"line_number":818,"context_line":""},{"line_number":819,"context_line":"        resp.headers[\u0027X-Object-Version-Id\u0027] \u003d \u0027null\u0027"},{"line_number":820,"context_line":"        # Check for a \"real\" version"},{"line_number":821,"context_line":"        loc \u003d wsgi_unquote(resp.headers.get(\u0027Content-Location\u0027, \u0027\u0027))"},{"line_number":822,"context_line":"        if loc:"},{"line_number":823,"context_line":"            _, acct, cont, version_obj \u003d split_path(loc, 4, 4, True)"},{"line_number":824,"context_line":"            if acct \u003d\u003d account and cont \u003d\u003d versions_cont:"}],"source_content_type":"text/x-python","patch_set":41,"id":"3fa7e38b_3fa4bbb8","line":821,"range":{"start_line":821,"start_character":14,"end_line":821,"end_character":26},"updated":"2019-11-21 07:03:30.000000000","message":"We unquote here, but don\u0027t re-quote below.","commit_id":"1b357c01653883a20984e0499fccca04173fa369"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":818,"context_line":""},{"line_number":819,"context_line":"        resp.headers[\u0027X-Object-Version-Id\u0027] \u003d \u0027null\u0027"},{"line_number":820,"context_line":"        # Check for a \"real\" version"},{"line_number":821,"context_line":"        loc \u003d wsgi_unquote(resp.headers.get(\u0027Content-Location\u0027, \u0027\u0027))"},{"line_number":822,"context_line":"        if loc:"},{"line_number":823,"context_line":"            _, acct, cont, version_obj \u003d split_path(loc, 4, 4, True)"},{"line_number":824,"context_line":"            if acct \u003d\u003d account and cont \u003d\u003d versions_cont:"}],"source_content_type":"text/x-python","patch_set":41,"id":"3fa7e38b_27c0d77d","line":821,"range":{"start_line":821,"start_character":14,"end_line":821,"end_character":26},"in_reply_to":"3fa7e38b_3fa4bbb8","updated":"2019-12-17 01:30:58.000000000","message":"Addressed in PS 42.","commit_id":"1b357c01653883a20984e0499fccca04173fa369"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"79a445da01d294dba11dcfdbc192659a73d39743","unresolved":false,"context_lines":[{"line_number":1174,"context_line":"                            wsgi_to_str(account),"},{"line_number":1175,"context_line":"                            wsgi_to_str(location),"},{"line_number":1176,"context_line":"                            item[\u0027name\u0027].encode(\u0027utf8\u0027)"},{"line_number":1177,"context_line":"                            if six.PY2 else item[\u0027name\u0027])"},{"line_number":1178,"context_line":""},{"line_number":1179,"context_line":"                        if path in current_versions:"},{"line_number":1180,"context_line":"                            item[\u0027is_latest\u0027] \u003d True"}],"source_content_type":"text/x-python","patch_set":44,"id":"3fa7e38b_6892704d","line":1177,"updated":"2019-11-21 17:49:39.000000000","message":"Oh, of course! Thanks.","commit_id":"4556c6055f2eb621c99c6c5b4ea2be5ef965069a"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"a4dae93583669488e0452de4193879519d988c11","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright (c) 2014 OpenStack Foundation"},{"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":48,"id":"3fa7e38b_1ab926eb","line":1,"updated":"2019-12-04 05:46:13.000000000","message":"I wonder if this year can be updated.. it aint 2014 anymore :P","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"a4dae93583669488e0452de4193879519d988c11","unresolved":false,"context_lines":[{"line_number":101,"context_line":"First to list previous versions, issue a a ``GET`` request to the versioned"},{"line_number":102,"context_line":"container with query parameter::"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"    ?versions"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"To list a container with a large number of object versions, clients can"},{"line_number":107,"context_line":"also use the ``version_marker`` parameter together with the ``marker``"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_9a699627","line":104,"updated":"2019-12-04 05:46:13.000000000","message":"Should we mention that using ?versions will return in json. Unless you explicitly ask for another, in which case you get a 406.","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"a4dae93583669488e0452de4193879519d988c11","unresolved":false,"context_lines":[{"line_number":228,"context_line":""},{"line_number":229,"context_line":"    def _build_versions_object_name(self, object_name, ts):"},{"line_number":230,"context_line":"        inv \u003d ~Timestamp(ts)"},{"line_number":231,"context_line":"        return get_reserved_name(object_name, inv.internal)"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"    def _split_version_from_name(self, versioned_name):"},{"line_number":234,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_5a1ebebb","line":231,"updated":"2019-12-04 05:46:13.000000000","message":"I\u0027m not 100% onboard with using the timestamp as the version. I feel this was discussed somewhere, probably the etherpad. \nSo maybe I should go back there.\n\nisn\u0027t there an edgecase, albeit very slight, that 2 people could write at the same time. I guess we do use ts everywhere else so I guess it\u0027s ok.\nBut what benefit do we get from having it a ts? I mean sure we can figure out when it was created.. but don\u0027t we already have that metadata?\n\nIs it because the versions are listed by name and then id? And so ts makes that happen in time order?\nIs it because it makes it easy to create an id for non versioned objects that become versioned? Hmm, maybe I can come around thinking about that.. \n\nI dunno, I\u0027ve started playing with it, and seeing something like 1575436687.02775, with the decimal, just looks weird. I guess it\u0027s fine. I guess something like a uuid might be a big combersome.\n\nI\u0027m probably just being a bit nitpicky today :P I\u0027ll keep playing with it. I\u0027m really liking the new API BTW!","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"86b7b7a9c670d64de6ad23c962a26f3164094989","unresolved":false,"context_lines":[{"line_number":228,"context_line":""},{"line_number":229,"context_line":"    def _build_versions_object_name(self, object_name, ts):"},{"line_number":230,"context_line":"        inv \u003d ~Timestamp(ts)"},{"line_number":231,"context_line":"        return get_reserved_name(object_name, inv.internal)"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"    def _split_version_from_name(self, versioned_name):"},{"line_number":234,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_89412f39","line":231,"in_reply_to":"3fa7e38b_3c197379","updated":"2019-12-06 08:41:05.000000000","message":"Thanks Clay, +1. Makes sense, thanks for clearing it up (and agreeing to some extent). I think I can live with it if it makes it all much simpler ;)","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"63e50c3f3a050c6e5b4af5a714e45633b8fda2e0","unresolved":false,"context_lines":[{"line_number":228,"context_line":""},{"line_number":229,"context_line":"    def _build_versions_object_name(self, object_name, ts):"},{"line_number":230,"context_line":"        inv \u003d ~Timestamp(ts)"},{"line_number":231,"context_line":"        return get_reserved_name(object_name, inv.internal)"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"    def _split_version_from_name(self, versioned_name):"},{"line_number":234,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_3c197379","line":231,"in_reply_to":"3fa7e38b_5a1ebebb","updated":"2019-12-04 18:48:55.000000000","message":"I agree there\u0027s an ascetic disadvantage compared to using something opaque.  I think the \"conflicting timestamp\" argument is ... less compelling.\n\nThe main reason we\u0027re tied to using timestamps is sorting in the container?versions listings - the object written into the DB have the inverse of the timestamp in the name so our existing db index can easily return all versions in most recent to oldest order.\n\nSo the name in the listing has to include the timestamp - if we use just the opaque identifier we loose ordering.  If tried to use a timestamp for ordering AND opaque identifier - we\u0027d have to do a lookup.\n\nThe ascetic disadvantage seems worth the benefit of the elegant and efficient implementation.","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"244b33d7f63fe655ab4e9e57aeef98ef896dbf43","unresolved":false,"context_lines":[{"line_number":228,"context_line":""},{"line_number":229,"context_line":"    def _build_versions_object_name(self, object_name, ts):"},{"line_number":230,"context_line":"        inv \u003d ~Timestamp(ts)"},{"line_number":231,"context_line":"        return get_reserved_name(object_name, inv.internal)"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"    def _split_version_from_name(self, versioned_name):"},{"line_number":234,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_1a49268d","line":231,"in_reply_to":"3fa7e38b_5a1ebebb","updated":"2019-12-09 08:41:09.000000000","message":"the version is used in the object name, so having the inversed timestamp helps with listing the objects in the order they were versioned.","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5c5872576d0638587edb1b32e05c795e28f46950","unresolved":false,"context_lines":[{"line_number":262,"context_line":"        \u0027\u0027\u0027"},{"line_number":263,"context_line":"        while True:"},{"line_number":264,"context_line":"            lreq \u003d make_pre_authed_request("},{"line_number":265,"context_line":"                req.environ, method\u003d\u0027GET\u0027, swift_source\u003d\u0027VW\u0027,"},{"line_number":266,"context_line":"                headers\u003d{\u0027X-Backend-Allow-Reserved-Names\u0027: \u0027true\u0027},"},{"line_number":267,"context_line":"                path\u003dwsgi_quote(\u0027/v1/%s/%s\u0027 % (account_name, lcontainer)))"},{"line_number":268,"context_line":"            lreq.environ[\u0027QUERY_STRING\u0027] \u003d \\"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_e692459f","line":265,"range":{"start_line":265,"start_character":57,"end_line":265,"end_character":59},"updated":"2019-12-06 18:21:05.000000000","message":"Should we continue using VW here, or should we invent a new swift_source? (OV, maybe?)","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"244b33d7f63fe655ab4e9e57aeef98ef896dbf43","unresolved":false,"context_lines":[{"line_number":262,"context_line":"        \u0027\u0027\u0027"},{"line_number":263,"context_line":"        while True:"},{"line_number":264,"context_line":"            lreq \u003d make_pre_authed_request("},{"line_number":265,"context_line":"                req.environ, method\u003d\u0027GET\u0027, swift_source\u003d\u0027VW\u0027,"},{"line_number":266,"context_line":"                headers\u003d{\u0027X-Backend-Allow-Reserved-Names\u0027: \u0027true\u0027},"},{"line_number":267,"context_line":"                path\u003dwsgi_quote(\u0027/v1/%s/%s\u0027 % (account_name, lcontainer)))"},{"line_number":268,"context_line":"            lreq.environ[\u0027QUERY_STRING\u0027] \u003d \\"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_4d07ad71","line":265,"range":{"start_line":265,"start_character":57,"end_line":265,"end_character":59},"in_reply_to":"3fa7e38b_e692459f","updated":"2019-12-09 08:41:09.000000000","message":"going with a new one, OV sounds good","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5c5872576d0638587edb1b32e05c795e28f46950","unresolved":false,"context_lines":[{"line_number":450,"context_line":"        # making any backend requests"},{"line_number":451,"context_line":"        if \u0027swift.authorize\u0027 in req.environ:"},{"line_number":452,"context_line":"            container_info \u003d get_container_info("},{"line_number":453,"context_line":"                req.environ, self.app)"},{"line_number":454,"context_line":"            req.acl \u003d container_info.get(\u0027write_acl\u0027)"},{"line_number":455,"context_line":"            aresp \u003d req.environ[\u0027swift.authorize\u0027](req)"},{"line_number":456,"context_line":"            if aresp:"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_a688cd6a","line":453,"updated":"2019-12-06 18:21:05.000000000","message":"Should set swift source here.","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"244b33d7f63fe655ab4e9e57aeef98ef896dbf43","unresolved":false,"context_lines":[{"line_number":450,"context_line":"        # making any backend requests"},{"line_number":451,"context_line":"        if \u0027swift.authorize\u0027 in req.environ:"},{"line_number":452,"context_line":"            container_info \u003d get_container_info("},{"line_number":453,"context_line":"                req.environ, self.app)"},{"line_number":454,"context_line":"            req.acl \u003d container_info.get(\u0027write_acl\u0027)"},{"line_number":455,"context_line":"            aresp \u003d req.environ[\u0027swift.authorize\u0027](req)"},{"line_number":456,"context_line":"            if aresp:"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_6d0ce992","line":453,"in_reply_to":"3fa7e38b_a688cd6a","updated":"2019-12-09 08:41:09.000000000","message":"Done","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"244b33d7f63fe655ab4e9e57aeef98ef896dbf43","unresolved":false,"context_lines":[{"line_number":773,"context_line":"                req, versions_cont, api_version, account,"},{"line_number":774,"context_line":"                container, obj, is_enabled, version)"},{"line_number":775,"context_line":"        if version \u003d\u003d \u0027null\u0027:"},{"line_number":776,"context_line":"            head_is_tombstone, symlink_target \u003d self._check_head("},{"line_number":777,"context_line":"                req, {\u0027X-Auth-Token\u0027: req.headers.get(\u0027X-Auth-Token\u0027)})"},{"line_number":778,"context_line":"            if head_is_tombstone or symlink_target:"},{"line_number":779,"context_line":"                raise HTTPNotFound(request\u003dreq)"},{"line_number":780,"context_line":""},{"line_number":781,"context_line":"            # else, primary container has the null version; let it through"},{"line_number":782,"context_line":"            resp \u003d req.get_response(self.app)"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_6292b3fe","line":779,"range":{"start_line":776,"start_character":12,"end_line":779,"end_character":47},"updated":"2019-12-09 08:41:09.000000000","message":"don\u0027t think this is needed, what I am missing?","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"86b7b7a9c670d64de6ad23c962a26f3164094989","unresolved":false,"context_lines":[{"line_number":851,"context_line":"        bytes and etag to use the target\u0027s instead of using the symlink info."},{"line_number":852,"context_line":"        \"\"\""},{"line_number":853,"context_line":"        app_resp \u003d self._app_call(req.environ)"},{"line_number":854,"context_line":"        container \u003d req.split_path(3, 3, True)[2]"},{"line_number":855,"context_line":"        if self._response_headers is None:"},{"line_number":856,"context_line":"            self._response_headers \u003d []"},{"line_number":857,"context_line":"        location \u003d \u0027\u0027"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_490817d8","line":854,"updated":"2019-12-06 08:41:05.000000000","message":"you\u0027re doing a path split here and an, albeit optional one down on line 875. We also do one on __call__. Do we need to keep splitting the same path? You pass the account, container, and object to the handle_object. Maybe we should pass to here too?\nOr are we worried that the req may change when we call _app_call?\n\nJust writing my thoughts as I go :)","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"244b33d7f63fe655ab4e9e57aeef98ef896dbf43","unresolved":false,"context_lines":[{"line_number":851,"context_line":"        bytes and etag to use the target\u0027s instead of using the symlink info."},{"line_number":852,"context_line":"        \"\"\""},{"line_number":853,"context_line":"        app_resp \u003d self._app_call(req.environ)"},{"line_number":854,"context_line":"        container \u003d req.split_path(3, 3, True)[2]"},{"line_number":855,"context_line":"        if self._response_headers is None:"},{"line_number":856,"context_line":"            self._response_headers \u003d []"},{"line_number":857,"context_line":"        location \u003d \u0027\u0027"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_ed6c5934","line":854,"in_reply_to":"3fa7e38b_490817d8","updated":"2019-12-09 08:41:09.000000000","message":"changed to just one split_path in handle_request just to minimize changes for now, sound ok?","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"86b7b7a9c670d64de6ad23c962a26f3164094989","unresolved":false,"context_lines":[{"line_number":914,"context_line":"                        path, 4, 4, True)"},{"line_number":915,"context_line":"                    if tgt_container !\u003d location:"},{"line_number":916,"context_line":"                        # if the archive container changed, leave the extra"},{"line_number":917,"context_line":"                        # info unmolested"},{"line_number":918,"context_line":"                        continue"},{"line_number":919,"context_line":"                    _, meta \u003d parse_header(item[\u0027hash\u0027])"},{"line_number":920,"context_line":"                    tgt_bytes \u003d int(item.pop(\u0027symlink_bytes\u0027))"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_c91c0715","line":917,"range":{"start_line":917,"start_character":31,"end_line":917,"end_character":41},"updated":"2019-12-06 08:41:05.000000000","message":"As we don\u0027t know who\u0027ll be reading the swift code in the future, and because this is opensource, this might be considered inappropriate. Someone could find it offensive or make them uncomfortable.\n\nMaybe better to make this more tame:\n\n  leave the extra info untouched (or unmodified or untouched).","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"244b33d7f63fe655ab4e9e57aeef98ef896dbf43","unresolved":false,"context_lines":[{"line_number":914,"context_line":"                        path, 4, 4, True)"},{"line_number":915,"context_line":"                    if tgt_container !\u003d location:"},{"line_number":916,"context_line":"                        # if the archive container changed, leave the extra"},{"line_number":917,"context_line":"                        # info unmolested"},{"line_number":918,"context_line":"                        continue"},{"line_number":919,"context_line":"                    _, meta \u003d parse_header(item[\u0027hash\u0027])"},{"line_number":920,"context_line":"                    tgt_bytes \u003d int(item.pop(\u0027symlink_bytes\u0027))"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_ad64214a","line":917,"range":{"start_line":917,"start_character":31,"end_line":917,"end_character":41},"in_reply_to":"3fa7e38b_c91c0715","updated":"2019-12-09 08:41:09.000000000","message":"Done","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5c5872576d0638587edb1b32e05c795e28f46950","unresolved":false,"context_lines":[{"line_number":955,"context_line":"        Only after disabling versioning and deleting *all* object versions"},{"line_number":956,"context_line":"        can a container be deleted."},{"line_number":957,"context_line":"        \"\"\""},{"line_number":958,"context_line":"        container_info \u003d get_container_info(req.environ, self.app)"},{"line_number":959,"context_line":""},{"line_number":960,"context_line":"        versions_cont \u003d unquote(container_info.get("},{"line_number":961,"context_line":"            \u0027sysmeta\u0027, {}).get(\u0027versions-container\u0027, \u0027\u0027))"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_26f29d06","line":958,"updated":"2019-12-06 18:21:05.000000000","message":"Should set swift source here.","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"244b33d7f63fe655ab4e9e57aeef98ef896dbf43","unresolved":false,"context_lines":[{"line_number":955,"context_line":"        Only after disabling versioning and deleting *all* object versions"},{"line_number":956,"context_line":"        can a container be deleted."},{"line_number":957,"context_line":"        \"\"\""},{"line_number":958,"context_line":"        container_info \u003d get_container_info(req.environ, self.app)"},{"line_number":959,"context_line":""},{"line_number":960,"context_line":"        versions_cont \u003d unquote(container_info.get("},{"line_number":961,"context_line":"            \u0027sysmeta\u0027, {}).get(\u0027versions-container\u0027, \u0027\u0027))"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_6d5aa982","line":958,"in_reply_to":"3fa7e38b_26f29d06","updated":"2019-12-09 08:41:09.000000000","message":"Done","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5c5872576d0638587edb1b32e05c795e28f46950","unresolved":false,"context_lines":[{"line_number":993,"context_line":"        return app_resp"},{"line_number":994,"context_line":""},{"line_number":995,"context_line":"    def enable_versioning(self, req, start_response):"},{"line_number":996,"context_line":"        container_info \u003d get_container_info(req.environ, self.app)"},{"line_number":997,"context_line":""},{"line_number":998,"context_line":"        # if container is already configured to use old style versioning,"},{"line_number":999,"context_line":"        # we don\u0027t allow user to enable object versioning here. They must"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_e6d7a54e","line":996,"updated":"2019-12-06 18:21:05.000000000","message":"Should set swift source here.","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"244b33d7f63fe655ab4e9e57aeef98ef896dbf43","unresolved":false,"context_lines":[{"line_number":993,"context_line":"        return app_resp"},{"line_number":994,"context_line":""},{"line_number":995,"context_line":"    def enable_versioning(self, req, start_response):"},{"line_number":996,"context_line":"        container_info \u003d get_container_info(req.environ, self.app)"},{"line_number":997,"context_line":""},{"line_number":998,"context_line":"        # if container is already configured to use old style versioning,"},{"line_number":999,"context_line":"        # we don\u0027t allow user to enable object versioning here. They must"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_adc98125","line":996,"in_reply_to":"3fa7e38b_e6d7a54e","updated":"2019-12-09 08:41:09.000000000","message":"Done","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"86b7b7a9c670d64de6ad23c962a26f3164094989","unresolved":false,"context_lines":[{"line_number":1092,"context_line":""},{"line_number":1093,"context_line":"            if params[\u0027version_marker\u0027] !\u003d \u0027null\u0027:"},{"line_number":1094,"context_line":"                try:"},{"line_number":1095,"context_line":"                    ts \u003d Timestamp(params.pop(\u0027version_marker\u0027))"},{"line_number":1096,"context_line":"                except ValueError:"},{"line_number":1097,"context_line":"                    raise HTTPBadRequest(\u0027invalid version_marker param\u0027)"},{"line_number":1098,"context_line":""}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_69eab3d9","line":1095,"updated":"2019-12-06 08:41:05.000000000","message":"marker doesn\u0027t have to be a whole object name, does the version_marker?\n\nI guess, I\u0027ll just have a play and find out :)","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5c5872576d0638587edb1b32e05c795e28f46950","unresolved":false,"context_lines":[{"line_number":1277,"context_line":"        \"\"\""},{"line_number":1278,"context_line":"        resp \u003d None"},{"line_number":1279,"context_line":"        container_info \u003d get_container_info("},{"line_number":1280,"context_line":"            req.environ, self.app)"},{"line_number":1281,"context_line":""},{"line_number":1282,"context_line":"        versions_cont \u003d container_info.get("},{"line_number":1283,"context_line":"            \u0027sysmeta\u0027, {}).get(\u0027versions-container\u0027, \u0027\u0027)"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_a6dd2d6e","line":1280,"updated":"2019-12-06 18:21:05.000000000","message":"Should set swift source here.","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"244b33d7f63fe655ab4e9e57aeef98ef896dbf43","unresolved":false,"context_lines":[{"line_number":1277,"context_line":"        \"\"\""},{"line_number":1278,"context_line":"        resp \u003d None"},{"line_number":1279,"context_line":"        container_info \u003d get_container_info("},{"line_number":1280,"context_line":"            req.environ, self.app)"},{"line_number":1281,"context_line":""},{"line_number":1282,"context_line":"        versions_cont \u003d container_info.get("},{"line_number":1283,"context_line":"            \u0027sysmeta\u0027, {}).get(\u0027versions-container\u0027, \u0027\u0027)"}],"source_content_type":"text/x-python","patch_set":48,"id":"3fa7e38b_6dcf0928","line":1280,"in_reply_to":"3fa7e38b_a6dd2d6e","updated":"2019-12-09 08:41:09.000000000","message":"Done","commit_id":"b0d90f1b45bca50556b1df79f30110ccee9beab8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":332,"context_line":"        return put_resp"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":"    def _put_versioned_obj_from_client(self, req, versions_cont, api_version,"},{"line_number":335,"context_line":"                                       account_name, object_name):"},{"line_number":336,"context_line":"        vers_obj_name \u003d self._build_versions_object_name("},{"line_number":337,"context_line":"            object_name, req.timestamp.internal)"},{"line_number":338,"context_line":"        put_path_info \u003d \"/%s/%s/%s/%s\" % ("}],"source_content_type":"text/x-python","patch_set":52,"id":"3fa7e38b_2c719ee0","line":335,"updated":"2019-12-17 01:30:58.000000000","message":"I think this function ought to pop off any X-Delete-At/X-Delete-After headers... yeah?\n\nAlso, whomp-whomp:\n\n Dec 17 00:28:45 saio container-6031: 127.0.0.1 - - [17/Dec/2019:00:28:45 +0000] \"PUT /sdb3/300/.expiring_objects/1576542523/1576542525-AUTH_test/%00versions%00c/%00o%008423457475.05134\" 400 33 \"PUT http://saio:8090/sdb1/194/AUTH_test/%00versions%00c/%00o%008423457475.05134\" \"tx1b254139acb2452c98ea0-005df8213c\" \"object-server 25300\" 0.0003 \"-\" 25305 0\n ...\n Dec 17 00:28:45 saio object-6010: ERROR Container update failed (saving for async update later): 400 response from 127.0.0.1:6031/sdb3 (txn: tx1b254139acb2452c98ea0-005df8213c)\n\nSee also: https://review.opendev.org/#/c/682138/38/swift/common/request_helpers.py@87","commit_id":"8c5555ddb9d2583d26a13befd0ea0adea3edca2c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7dbbbeae69ecc88e1940e6c30ec9d19c58b061f3","unresolved":false,"context_lines":[{"line_number":332,"context_line":"        return put_resp"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":"    def _put_versioned_obj_from_client(self, req, versions_cont, api_version,"},{"line_number":335,"context_line":"                                       account_name, object_name):"},{"line_number":336,"context_line":"        vers_obj_name \u003d self._build_versions_object_name("},{"line_number":337,"context_line":"            object_name, req.timestamp.internal)"},{"line_number":338,"context_line":"        put_path_info \u003d \"/%s/%s/%s/%s\" % ("}],"source_content_type":"text/x-python","patch_set":52,"id":"3fa7e38b_c97bb177","line":335,"in_reply_to":"3fa7e38b_2c719ee0","updated":"2019-12-28 07:00:49.000000000","message":"Addressed in patch set 61, though the general reserve-name/expirer interaction still needs to be resolved by https://review.opendev.org/#/c/700449/","commit_id":"8c5555ddb9d2583d26a13befd0ea0adea3edca2c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":332,"context_line":"        return put_resp"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":"    def _put_versioned_obj_from_client(self, req, versions_cont, api_version,"},{"line_number":335,"context_line":"                                       account_name, object_name):"},{"line_number":336,"context_line":"        vers_obj_name \u003d self._build_versions_object_name("},{"line_number":337,"context_line":"            object_name, req.timestamp.internal)"},{"line_number":338,"context_line":"        put_path_info \u003d \"/%s/%s/%s/%s\" % ("}],"source_content_type":"text/x-python","patch_set":52,"id":"3fa7e38b_26c90faa","line":335,"in_reply_to":"3fa7e38b_c97bb177","updated":"2020-01-08 22:41:42.000000000","message":"https://review.opendev.org/700449 landed; I\u0027m no longer worried about expirer/reconciler queues. Might be nice to have a probe test to cover expirer, but as things currently   stand, we don\u0027t allow expiry headers in the reserved container.","commit_id":"8c5555ddb9d2583d26a13befd0ea0adea3edca2c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":669,"context_line":"            if head_is_tombstone:"},{"line_number":670,"context_line":"                resp_version_id \u003d \u0027null\u0027"},{"line_number":671,"context_line":"            else:"},{"line_number":672,"context_line":"                _, vers_obj_name \u003d wsgi_unquote(symlink_target).split(\u0027/\u0027, 1)"},{"line_number":673,"context_line":"                resp_version_id \u003d self._split_version_from_name("},{"line_number":674,"context_line":"                    vers_obj_name)[1].internal"},{"line_number":675,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":52,"id":"3fa7e38b_6c7d56e5","line":672,"range":{"start_line":672,"start_character":16,"end_line":672,"end_character":17},"updated":"2019-12-17 01:30:58.000000000","message":"I\u0027m a little nervous that this could be something other than versions_cont, or that _split_version_from_name() might come back None -- but either of those would require a decent bit of effort on the part of the operator, right? Surely they\u0027d know they were off the happy path by then...\n\nOr can we run into trouble with static links the user created while versioning was suspended?","commit_id":"8c5555ddb9d2583d26a13befd0ea0adea3edca2c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":796,"context_line":"                \u0027X-Backend-Content-Type\u0027, resp.headers[\u0027Content-Type\u0027])"},{"line_number":797,"context_line":""},{"line_number":798,"context_line":"            if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":799,"context_line":"                close_if_possible(resp.app_iter)"},{"line_number":800,"context_line":""},{"line_number":801,"context_line":"            if is_del_marker:"},{"line_number":802,"context_line":"                hdrs \u003d {\u0027X-Object-Version-Id\u0027: version,"}],"source_content_type":"text/x-python","patch_set":52,"id":"3fa7e38b_0c2622cd","line":799,"updated":"2019-12-17 01:30:58.000000000","message":"(Carried over from PS 8)\n\nWhat handles the close when it\u0027s *not* a HEAD?","commit_id":"8c5555ddb9d2583d26a13befd0ea0adea3edca2c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7dbbbeae69ecc88e1940e6c30ec9d19c58b061f3","unresolved":false,"context_lines":[{"line_number":796,"context_line":"                \u0027X-Backend-Content-Type\u0027, resp.headers[\u0027Content-Type\u0027])"},{"line_number":797,"context_line":""},{"line_number":798,"context_line":"            if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":799,"context_line":"                close_if_possible(resp.app_iter)"},{"line_number":800,"context_line":""},{"line_number":801,"context_line":"            if is_del_marker:"},{"line_number":802,"context_line":"                hdrs \u003d {\u0027X-Object-Version-Id\u0027: version,"}],"source_content_type":"text/x-python","patch_set":52,"id":"3fa7e38b_8991399d","line":799,"in_reply_to":"3fa7e38b_0c2622cd","updated":"2019-12-28 07:00:49.000000000","message":"We\u0027re returning resp, so... one of the filters left of us or eventlet, I suppose.\n\nWhich now leaves me wondering: why do we do this for HEAD?","commit_id":"8c5555ddb9d2583d26a13befd0ea0adea3edca2c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"13fcf9987abc5c8dd5ee0ab245f5bc4cc2434c84","unresolved":false,"context_lines":[{"line_number":870,"context_line":"                location \u003d value"},{"line_number":871,"context_line":"            if header.lower() \u003d\u003d SYSMETA_VERSIONS_ENABLED:"},{"line_number":872,"context_line":"                self._response_headers.extend(["},{"line_number":873,"context_line":"                    (CLIENT_VERSIONS_ENABLED.title(), value)])"},{"line_number":874,"context_line":""},{"line_number":875,"context_line":"        if location:"},{"line_number":876,"context_line":"            location \u003d wsgi_unquote(location)"}],"source_content_type":"text/x-python","patch_set":52,"id":"3fa7e38b_8213b965","line":873,"updated":"2019-12-17 05:52:34.000000000","message":"Thinking about https://review.opendev.org/#/c/682382/6/swift/common/middleware/versioned_writes/object_versioning.py@827 -- we should only send this back to the client when we have a versions location. Maybe even require that the thing seems to exist?\n\nHmm... given the deterministic naming for the versions location, I wonder how much value we really get out of X-Container-Sysmeta-Versions-Container....\n\nAre we *sure* that trying to go straight from versioning-never-enabled to versioning-suspended shouldn\u0027t create the archive container? I feel like that\u0027s not going to do what we want for s3api. :-/","commit_id":"8c5555ddb9d2583d26a13befd0ea0adea3edca2c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"13fcf9987abc5c8dd5ee0ab245f5bc4cc2434c84","unresolved":false,"context_lines":[{"line_number":1040,"context_line":"            else:"},{"line_number":1041,"context_line":"                if \u0027X-Storage-Policy\u0027 in req.headers:"},{"line_number":1042,"context_line":"                    hdrs \u003d {\u0027X-Storage-Policy\u0027:"},{"line_number":1043,"context_line":"                            req.headers[\u0027X-Storage-Policy\u0027]}"},{"line_number":1044,"context_line":"                else:"},{"line_number":1045,"context_line":"                    hdrs \u003d {}"},{"line_number":1046,"context_line":"            hdrs[\u0027X-Backend-Allow-Reserved-Names\u0027] \u003d \u0027true\u0027"}],"source_content_type":"text/x-python","patch_set":52,"id":"3fa7e38b_0247c9a5","line":1043,"updated":"2019-12-17 05:52:34.000000000","message":"This seems to contradict the comment above...","commit_id":"8c5555ddb9d2583d26a13befd0ea0adea3edca2c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"13fcf9987abc5c8dd5ee0ab245f5bc4cc2434c84","unresolved":false,"context_lines":[{"line_number":1053,"context_line":"                method\u003d\u0027PUT\u0027, headers\u003dhdrs, swift_source\u003d\u0027OV\u0027)"},{"line_number":1054,"context_line":"            resp \u003d ver_cont_req.get_response(self.app)"},{"line_number":1055,"context_line":"            close_if_possible(resp.app_iter)"},{"line_number":1056,"context_line":"            if is_success(resp.status_int):"},{"line_number":1057,"context_line":"                req.headers[SYSMETA_VERSIONS_CONT] \u003d wsgi_quote(versions_cont)"},{"line_number":1058,"context_line":"            else:"},{"line_number":1059,"context_line":"                raise HTTPInternalServerError("}],"source_content_type":"text/x-python","patch_set":52,"id":"3fa7e38b_a246f57d","line":1056,"updated":"2019-12-17 05:52:34.000000000","message":"We should also treat 409 as successful. If I *really* want to split policies between the primary and archive containers, the \"obvious\" way to do it with the fewest requests doesn\u0027t work:\n\n $ curl http://saio:8090/v1/AUTH_test/%00versions%00con -X PUT -H x-storage-policy:replicated -H x-backend-allow-reserved-names:t -v\n*   Trying 10.0.2.15...\n* TCP_NODELAY set\n* Connected to saio (10.0.2.15) port 8090 (#0)\n\u003e PUT /v1/AUTH_test/%00versions%00con HTTP/1.1\n\u003e Host: saio:8090\n\u003e User-Agent: curl/7.58.0\n\u003e Accept: */*\n\u003e x-storage-policy:replicated\n\u003e x-backend-allow-reserved-names:t\n\u003e \n\u003c HTTP/1.1 201 Created\n\u003c Content-Type: text/html; charset\u003dUTF-8\n\u003c Content-Length: 0\n\u003c X-Backend-Storage-Policy-Index: 1\n\u003c X-Trans-Id: txba1e82e76ff34b8ba87d7-005df86673\n\u003c X-Openstack-Request-Id: txba1e82e76ff34b8ba87d7-005df86673\n\u003c Date: Tue, 17 Dec 2019 05:24:03 GMT\n\u003c \n* Connection #0 to host saio left intact\n\n $ curl http://saio:8090/v1/AUTH_test/con -X PUT -H x-versions-enabled:t -H x-storage-policy:default -v\n*   Trying 10.0.2.15...\n* TCP_NODELAY set\n* Connected to saio (10.0.2.15) port 8090 (#0)\n\u003e PUT /v1/AUTH_test/con HTTP/1.1\n\u003e Host: saio:8090\n\u003e User-Agent: curl/7.58.0\n\u003e Accept: */*\n\u003e x-versions-enabled:t\n\u003e x-storage-policy:default\n\u003e \n\u003c HTTP/1.1 500 Internal Error\n\u003c Content-Type: text/html; charset\u003dUTF-8\n\u003c Content-Length: 32\n\u003c X-Trans-Id: txc68789fb2d184b51b6b13-005df86689\n\u003c X-Openstack-Request-Id: txc68789fb2d184b51b6b13-005df86689\n\u003c Date: Tue, 17 Dec 2019 05:24:25 GMT\n\u003c \n* Connection #0 to host saio left intact\nError enabling object versioning","commit_id":"8c5555ddb9d2583d26a13befd0ea0adea3edca2c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7dbbbeae69ecc88e1940e6c30ec9d19c58b061f3","unresolved":false,"context_lines":[{"line_number":1053,"context_line":"                method\u003d\u0027PUT\u0027, headers\u003dhdrs, swift_source\u003d\u0027OV\u0027)"},{"line_number":1054,"context_line":"            resp \u003d ver_cont_req.get_response(self.app)"},{"line_number":1055,"context_line":"            close_if_possible(resp.app_iter)"},{"line_number":1056,"context_line":"            if is_success(resp.status_int):"},{"line_number":1057,"context_line":"                req.headers[SYSMETA_VERSIONS_CONT] \u003d wsgi_quote(versions_cont)"},{"line_number":1058,"context_line":"            else:"},{"line_number":1059,"context_line":"                raise HTTPInternalServerError("}],"source_content_type":"text/x-python","patch_set":52,"id":"3fa7e38b_298a8564","line":1056,"in_reply_to":"3fa7e38b_a246f57d","updated":"2019-12-28 07:00:49.000000000","message":"Addressed in patch set 61","commit_id":"8c5555ddb9d2583d26a13befd0ea0adea3edca2c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"13fcf9987abc5c8dd5ee0ab245f5bc4cc2434c84","unresolved":false,"context_lines":[{"line_number":1056,"context_line":"            if is_success(resp.status_int):"},{"line_number":1057,"context_line":"                req.headers[SYSMETA_VERSIONS_CONT] \u003d wsgi_quote(versions_cont)"},{"line_number":1058,"context_line":"            else:"},{"line_number":1059,"context_line":"                raise HTTPInternalServerError("},{"line_number":1060,"context_line":"                    \u0027Error enabling object versioning\u0027)"},{"line_number":1061,"context_line":""},{"line_number":1062,"context_line":"        # make original request"}],"source_content_type":"text/x-python","patch_set":52,"id":"3fa7e38b_82e97980","line":1059,"updated":"2019-12-17 05:52:34.000000000","message":"We should consume the error response (which should be short) before raising -- otherwise I get log lines like\n\n ...\n Dec 17 05:08:14 saio container-6031: 127.0.0.1 - - [17/Dec/2019:05:08:14 +0000] \"PUT /sdb3/388/AUTH_test/%00versions%00con\" 412 29 \"PUT http://saio:8090/v1/AUTH_test/%00versions%00con\" \"tx1c77e887a107423ab6115-005df862be\" \"proxy-server 26025\" 0.0002 \"-\" 25916 -\n Dec 17 05:08:14 saio proxy-server: - - 17/Dec/2019/05/08/14 PUT /v1/AUTH_test/%2500versions%2500con HTTP/1.0 499 - Swift - - 29 - tx1c77e887a107423ab6115-005df862be - 0.0345 OV - 1576559294.442893744 1576559294.477400064 -\n Dec 17 05:08:14 saio proxy-server: 10.0.2.15 10.0.2.15 17/Dec/2019/05/08/14 PUT /v1/AUTH_test/con HTTP/1.0 500 - curl/7.58.0 - - 32 - tx1c77e887a107423ab6115-005df862be - 0.0771 - - 1576559294.403933525 1576559294.481024504 -\n\n(I.e., the container servers log and respond 412, but the proxy-server logs a 499 for the subrequest before separately responding 500 to the client.)\n\nHmmm.... actually, I think we need to consume the body in all cases -- I can get similar logs even when it\u0027s successful:\n\n Dec 17 05:19:20 saio container-6041: 127.0.0.1 - - [17/Dec/2019:05:19:20 +0000] \"PUT /sdb4/388/AUTH_test/%00versions%00con\" 202 - \"PUT http://saio:8090/v1/AUTH_test/%00versions%00con\" \"tx6e17354acc9e4be49bece-005df86558\" \"proxy-server 26025\" 0.1110 \"-\" 26169 1\n Dec 17 05:19:20 saio proxy-server: - - 17/Dec/2019/05/19/20 PUT /v1/AUTH_test/%2500versions%2500con HTTP/1.0 499 - Swift - - 76 - tx6e17354acc9e4be49bece-005df86558 - 0.1533 OV - 1576559960.731002092 1576559960.884313107 1","commit_id":"8c5555ddb9d2583d26a13befd0ea0adea3edca2c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7dbbbeae69ecc88e1940e6c30ec9d19c58b061f3","unresolved":false,"context_lines":[{"line_number":1056,"context_line":"            if is_success(resp.status_int):"},{"line_number":1057,"context_line":"                req.headers[SYSMETA_VERSIONS_CONT] \u003d wsgi_quote(versions_cont)"},{"line_number":1058,"context_line":"            else:"},{"line_number":1059,"context_line":"                raise HTTPInternalServerError("},{"line_number":1060,"context_line":"                    \u0027Error enabling object versioning\u0027)"},{"line_number":1061,"context_line":""},{"line_number":1062,"context_line":"        # make original request"}],"source_content_type":"text/x-python","patch_set":52,"id":"3fa7e38b_4987c15c","line":1059,"in_reply_to":"3fa7e38b_82e97980","updated":"2019-12-28 07:00:49.000000000","message":"Addressed in patch set 61","commit_id":"8c5555ddb9d2583d26a13befd0ea0adea3edca2c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":1204,"context_line":"                              DELETE_MARKER_CONTENT_TYPE"},{"line_number":1205,"context_line":"                              and name not in latest_del_marker):"},{"line_number":1206,"context_line":"                            item[\u0027is_latest\u0027] \u003d True"},{"line_number":1207,"context_line":"                            latest_del_marker.add(name)"},{"line_number":1208,"context_line":"                        else:"},{"line_number":1209,"context_line":"                            item[\u0027is_latest\u0027] \u003d False"},{"line_number":1210,"context_line":""}],"source_content_type":"text/x-python","patch_set":52,"id":"3fa7e38b_4c365a52","line":1207,"updated":"2019-12-17 01:30:58.000000000","message":"So, if I\u0027ve got a live version, delete marker, archived version stacked... I see two is_latest versions:\n\n $ curl http://saio:8090/v1/AUTH_test/c?versions -s | jq\n[\n  {\n    \"bytes\": 4,\n    \"hash\": \"674f3c2c1a8a6f90461e8a66fb5550ba\",\n    \"name\": \"o\",\n    \"content_type\": \"application/x-www-form-urlencoded\",\n    \"last_modified\": \"2019-12-16T23:36:33.170150\",\n    \"version_id\": \"null\",\n    \"is_latest\": true\n  },\n  {\n    \"bytes\": 0,\n    \"hash\": \"d41d8cd98f00b204e9800998ecf8427e\",\n    \"name\": \"o\",\n    \"content_type\": \"application/x-deleted;swift_versions_deleted\u003d1\",\n    \"last_modified\": \"2019-12-16T23:35:53.744100\",\n    \"is_latest\": true,\n    \"version_id\": \"1576539353.74288\"\n  },\n  {\n    \"bytes\": 4,\n    \"hash\": \"81dc9bdb52d04dc20036dbd8313ed055\",\n    \"name\": \"o\",\n    \"content_type\": \"application/x-www-form-urlencoded\",\n    \"last_modified\": \"2019-12-16T23:35:49.325780\",\n    \"is_latest\": false,\n    \"version_id\": \"1576539349.32578\"\n  }\n]\n\nActually, that\u0027ll happen even if I re-enabled versioning and PUT some more data:\n\n $ curl http://saio:8090/v1/AUTH_test/c?versions -s | jq\n[\n  {\n    \"bytes\": 4,\n    \"hash\": \"707229919d6eb235181eed9b8b951a68\",\n    \"name\": \"o\",\n    \"content_type\": \"application/x-www-form-urlencoded\",\n    \"last_modified\": \"2019-12-17T00:02:28.088500\",\n    \"is_latest\": true,\n    \"version_id\": \"1576540948.08850\"\n  },\n  {\n    \"bytes\": 4,\n    \"hash\": \"674f3c2c1a8a6f90461e8a66fb5550ba\",\n    \"name\": \"o\",\n    \"content_type\": \"application/x-www-form-urlencoded\",\n    \"last_modified\": \"2019-12-17T00:02:28.025110\",\n    \"is_latest\": false,\n    \"version_id\": \"1576539393.17015\"\n  },\n  {\n    \"bytes\": 0,\n    \"hash\": \"d41d8cd98f00b204e9800998ecf8427e\",\n    \"name\": \"o\",\n    \"content_type\": \"application/x-deleted;swift_versions_deleted\u003d1\",\n    \"last_modified\": \"2019-12-16T23:35:53.744100\",\n    \"is_latest\": true,\n    \"version_id\": \"1576539353.74288\"\n  },\n  {\n    \"bytes\": 4,\n    \"hash\": \"81dc9bdb52d04dc20036dbd8313ed055\",\n    \"name\": \"o\",\n    \"content_type\": \"application/x-www-form-urlencoded\",\n    \"last_modified\": \"2019-12-16T23:35:49.325780\",\n    \"is_latest\": false,\n    \"version_id\": \"1576539349.32578\"\n  }\n]","commit_id":"8c5555ddb9d2583d26a13befd0ea0adea3edca2c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"b01cbcfa83a9c1b5fa15563cb868502d731c6422","unresolved":false,"context_lines":[{"line_number":108,"context_line":"parameter.  While the ``marker`` parameter is used to specify an object name"},{"line_number":109,"context_line":"the ``version_marker`` will be used specify the version id."},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"All other pagination parameters can be used in conjunction with the"},{"line_number":112,"context_line":"``versions`` parameter."},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"During container listings, delete markers can be identified with the"},{"line_number":115,"context_line":"content-type ``application/x-deleted;swift_versions_deleted\u003d1``. The most"}],"source_content_type":"text/x-python","patch_set":53,"id":"3fa7e38b_03b1fa01","line":112,"range":{"start_line":111,"start_character":0,"end_line":112,"end_character":23},"updated":"2019-12-18 06:56:11.000000000","message":"...except end_marker. In fact, *trying* to use end_marker leads to some weird behavior (watch is_latest):\n\nvagrant@saio:~$ curl -s http://saio:8090/v1/AUTH_test/container-81b96036-0431-4a57-9ca6-478bae2121b8?versions\\\u0026marker\u003dobj-0001\\\u0026version_marker\u003d1576647419.45632\\\u0026limit\u003d2 | jq\n[\n  {\n    \"bytes\": 0,\n    \"hash\": \"d41d8cd98f00b204e9800998ecf8427e\",\n    \"name\": \"obj-0001\",\n    \"content_type\": \"application/octet-stream\",\n    \"last_modified\": \"2019-12-18T05:36:59.365030\",\n    \"is_latest\": false,\n    \"version_id\": \"1576647419.36503\"\n  },\n  {\n    \"bytes\": 0,\n    \"hash\": \"d41d8cd98f00b204e9800998ecf8427e\",\n    \"name\": \"obj-0002\",\n    \"content_type\": \"application/octet-stream\",\n    \"last_modified\": \"2019-12-18T05:36:59.828080\",\n    \"is_latest\": true,\n    \"version_id\": \"1576647419.82808\"\n  }\n]\nvagrant@saio:~$ curl -s http://saio:8090/v1/AUTH_test/container-81b96036-0431-4a57-9ca6-478bae2121b8?versions\\\u0026marker\u003dobj-0001\\\u0026version_marker\u003d1576647419.45632\\\u0026limit\u003d2\\\u0026end_marker\u003daa | jq\n[\n  {\n    \"bytes\": 0,\n    \"hash\": \"d41d8cd98f00b204e9800998ecf8427e\",\n    \"name\": \"obj-0001\",\n    \"content_type\": \"application/octet-stream\",\n    \"last_modified\": \"2019-12-18T05:36:59.365030\",\n    \"is_latest\": false,\n    \"version_id\": \"1576647419.36503\"\n  },\n  {\n    \"bytes\": 0,\n    \"hash\": \"d41d8cd98f00b204e9800998ecf8427e\",\n    \"name\": \"obj-0002\",\n    \"content_type\": \"application/octet-stream\",\n    \"last_modified\": \"2019-12-18T05:36:59.828080\",\n    \"is_latest\": false,\n    \"version_id\": \"1576647419.82808\"\n  }\n]\nvagrant@saio:~$ curl -s http://saio:8090/v1/AUTH_test/container-81b96036-0431-4a57-9ca6-478bae2121b8?versions\\\u0026marker\u003dobj-0001\\\u0026version_marker\u003d1576647419.45632\\\u0026limit\u003d2\\\u0026end_marker\u003dzz | jq\n[\n  {\n    \"bytes\": 0,\n    \"hash\": \"d41d8cd98f00b204e9800998ecf8427e\",\n    \"name\": \"obj-0001\",\n    \"content_type\": \"application/octet-stream\",\n    \"last_modified\": \"2019-12-18T05:36:59.365030\",\n    \"is_latest\": false,\n    \"version_id\": \"1576647419.36503\"\n  },\n  {\n    \"bytes\": 0,\n    \"hash\": \"d41d8cd98f00b204e9800998ecf8427e\",\n    \"name\": \"obj-0002\",\n    \"content_type\": \"application/octet-stream\",\n    \"last_modified\": \"2019-12-18T05:36:59.828080\",\n    \"is_latest\": true,\n    \"version_id\": \"1576647419.82808\"\n  }\n]","commit_id":"02d045a2f8f7f16408fa8af59481eaeaac2c7328"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ff3ca5f9fe06eb6fabe2f9cb793163a2a25feb74","unresolved":false,"context_lines":[{"line_number":162,"context_line":"from swift.common.swob import HTTPPreconditionFailed, HTTPServiceUnavailable, \\"},{"line_number":163,"context_line":"    HTTPServerError, HTTPBadRequest, str_to_wsgi, bytes_to_wsgi, wsgi_quote, \\"},{"line_number":164,"context_line":"    wsgi_to_str, wsgi_unquote, Request, HTTPNotFound, HTTPException, \\"},{"line_number":165,"context_line":"    HTTPRequestEntityTooLarge, HTTPInternalServerError, HTTPNotAcceptable"},{"line_number":166,"context_line":"from swift.common.storage_policy import POLICIES"},{"line_number":167,"context_line":"from swift.common.utils import get_logger, Timestamp, \\"},{"line_number":168,"context_line":"    config_true_value, close_if_possible, closing_if_possible, \\"}],"source_content_type":"text/x-python","patch_set":53,"id":"3fa7e38b_de3e3025","line":165,"range":{"start_line":165,"start_character":31,"end_line":165,"end_character":54},"updated":"2019-12-20 07:14:42.000000000","message":"Kinda weird that we import both HTTPServerError *and* HTTPInternalServerError...","commit_id":"02d045a2f8f7f16408fa8af59481eaeaac2c7328"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7dbbbeae69ecc88e1940e6c30ec9d19c58b061f3","unresolved":false,"context_lines":[{"line_number":162,"context_line":"from swift.common.swob import HTTPPreconditionFailed, HTTPServiceUnavailable, \\"},{"line_number":163,"context_line":"    HTTPServerError, HTTPBadRequest, str_to_wsgi, bytes_to_wsgi, wsgi_quote, \\"},{"line_number":164,"context_line":"    wsgi_to_str, wsgi_unquote, Request, HTTPNotFound, HTTPException, \\"},{"line_number":165,"context_line":"    HTTPRequestEntityTooLarge, HTTPInternalServerError, HTTPNotAcceptable"},{"line_number":166,"context_line":"from swift.common.storage_policy import POLICIES"},{"line_number":167,"context_line":"from swift.common.utils import get_logger, Timestamp, \\"},{"line_number":168,"context_line":"    config_true_value, close_if_possible, closing_if_possible, \\"}],"source_content_type":"text/x-python","patch_set":53,"id":"3fa7e38b_e9e54d3f","line":165,"range":{"start_line":165,"start_character":31,"end_line":165,"end_character":54},"in_reply_to":"3fa7e38b_de3e3025","updated":"2019-12-28 07:00:49.000000000","message":"Addressed in patch set 61","commit_id":"02d045a2f8f7f16408fa8af59481eaeaac2c7328"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ff3ca5f9fe06eb6fabe2f9cb793163a2a25feb74","unresolved":false,"context_lines":[{"line_number":980,"context_line":"            close_if_possible(vresp.app_iter)"},{"line_number":981,"context_line":"            if vresp.is_success and int(vresp.headers.get("},{"line_number":982,"context_line":"                    \u0027X-Container-Object-Count\u0027, 0)) \u003e 0:"},{"line_number":983,"context_line":"                raise HTTPBadRequest("},{"line_number":984,"context_line":"                    \u0027Delete all versions to delete container.\u0027,"},{"line_number":985,"context_line":"                    request\u003dreq)"},{"line_number":986,"context_line":"            elif not vresp.is_success and vresp.status_int !\u003d 404:"}],"source_content_type":"text/x-python","patch_set":53,"id":"3fa7e38b_1e35a843","line":983,"range":{"start_line":983,"start_character":22,"end_line":983,"end_character":36},"updated":"2019-12-20 07:14:42.000000000","message":"Should this be a 400, or a 409?","commit_id":"02d045a2f8f7f16408fa8af59481eaeaac2c7328"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7dbbbeae69ecc88e1940e6c30ec9d19c58b061f3","unresolved":false,"context_lines":[{"line_number":980,"context_line":"            close_if_possible(vresp.app_iter)"},{"line_number":981,"context_line":"            if vresp.is_success and int(vresp.headers.get("},{"line_number":982,"context_line":"                    \u0027X-Container-Object-Count\u0027, 0)) \u003e 0:"},{"line_number":983,"context_line":"                raise HTTPBadRequest("},{"line_number":984,"context_line":"                    \u0027Delete all versions to delete container.\u0027,"},{"line_number":985,"context_line":"                    request\u003dreq)"},{"line_number":986,"context_line":"            elif not vresp.is_success and vresp.status_int !\u003d 404:"}],"source_content_type":"text/x-python","patch_set":53,"id":"3fa7e38b_09eb0912","line":983,"range":{"start_line":983,"start_character":22,"end_line":983,"end_character":36},"in_reply_to":"3fa7e38b_1e35a843","updated":"2019-12-28 07:00:49.000000000","message":"Addressed in patch set 61","commit_id":"02d045a2f8f7f16408fa8af59481eaeaac2c7328"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"b01cbcfa83a9c1b5fa15563cb868502d731c6422","unresolved":false,"context_lines":[{"line_number":1096,"context_line":"            raise HTTPNotAcceptable(request\u003dreq)"},{"line_number":1097,"context_line":""},{"line_number":1098,"context_line":"        params \u003d req.params"},{"line_number":1099,"context_line":"        if \u0027version_marker\u0027 in params:"},{"line_number":1100,"context_line":"            if \u0027marker\u0027 not in params:"},{"line_number":1101,"context_line":"                raise HTTPBadRequest(\u0027version_marker param requires marker\u0027)"},{"line_number":1102,"context_line":""}],"source_content_type":"text/x-python","patch_set":53,"id":"3fa7e38b_230f56e1","line":1099,"updated":"2019-12-18 06:56:11.000000000","message":"I wonder if there should also be a version_end_marker... particularly since we get something close to that behavior when using reverse...","commit_id":"02d045a2f8f7f16408fa8af59481eaeaac2c7328"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7dbbbeae69ecc88e1940e6c30ec9d19c58b061f3","unresolved":false,"context_lines":[{"line_number":1041,"context_line":"            # Attempt to use same policy as primary container, otherwise"},{"line_number":1042,"context_line":"            # use default policy"},{"line_number":1043,"context_line":"            primary_policy_idx \u003d container_info.get(\u0027storage_policy\u0027, None)"},{"line_number":1044,"context_line":"            if primary_policy_idx:"},{"line_number":1045,"context_line":"                hdrs \u003d {\u0027X-Storage-Policy\u0027: POLICIES[primary_policy_idx].name}"},{"line_number":1046,"context_line":"            else:"},{"line_number":1047,"context_line":"                if \u0027X-Storage-Policy\u0027 in req.headers:"}],"source_content_type":"text/x-python","patch_set":60,"id":"3fa7e38b_2ea5aba0","line":1044,"range":{"start_line":1044,"start_character":12,"end_line":1044,"end_character":33},"updated":"2019-12-28 07:00:49.000000000","message":"Should this be more like\n\n if primary_policy_idx is not None:\n\n? If you had policy 1 as your default and went to enable versioning on pre-existing container with policy 0...\n\nOh wait, get_container_info ensures storage_policy is always set and always an integer: https://github.com/openstack/swift/blob/2.23.0/swift/proxy/controllers/base.py#L379-L388\n\nSo really, we want something more like\n\n if is_success(container_info[\u0027status\u0027]):","commit_id":"b658ff8918b19e4ac827150a4b641a83f3ef0905"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1041,"context_line":"            # Attempt to use same policy as primary container, otherwise"},{"line_number":1042,"context_line":"            # use default policy"},{"line_number":1043,"context_line":"            primary_policy_idx \u003d container_info.get(\u0027storage_policy\u0027, None)"},{"line_number":1044,"context_line":"            if primary_policy_idx:"},{"line_number":1045,"context_line":"                hdrs \u003d {\u0027X-Storage-Policy\u0027: POLICIES[primary_policy_idx].name}"},{"line_number":1046,"context_line":"            else:"},{"line_number":1047,"context_line":"                if \u0027X-Storage-Policy\u0027 in req.headers:"}],"source_content_type":"text/x-python","patch_set":60,"id":"3fa7e38b_065413c5","line":1044,"range":{"start_line":1044,"start_character":12,"end_line":1044,"end_character":33},"in_reply_to":"3fa7e38b_2ea5aba0","updated":"2020-01-08 22:41:42.000000000","message":"Addressed in PS 61.","commit_id":"b658ff8918b19e4ac827150a4b641a83f3ef0905"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7dbbbeae69ecc88e1940e6c30ec9d19c58b061f3","unresolved":false,"context_lines":[{"line_number":1052,"context_line":"            # Attempt to use same policy as primary container, otherwise"},{"line_number":1053,"context_line":"            # use default policy"},{"line_number":1054,"context_line":"            if is_success(container_info[\u0027status\u0027]):"},{"line_number":1055,"context_line":"                primary_policy_idx \u003d container_info[\u0027storage_policy\u0027]"},{"line_number":1056,"context_line":"                hdrs \u003d {\u0027X-Storage-Policy\u0027: POLICIES[primary_policy_idx].name}"},{"line_number":1057,"context_line":"            else:"},{"line_number":1058,"context_line":"                if \u0027X-Storage-Policy\u0027 in req.headers:"}],"source_content_type":"text/x-python","patch_set":61,"id":"3fa7e38b_a9ebd50e","line":1055,"updated":"2019-12-28 07:00:49.000000000","message":"So... what happens when you try to enable versioning on an existing container in a deprecated policy?\n\nWhat *should* happen?","commit_id":"de1658ab0b68cd37640841dc718b1f8c63950c03"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1052,"context_line":"            # Attempt to use same policy as primary container, otherwise"},{"line_number":1053,"context_line":"            # use default policy"},{"line_number":1054,"context_line":"            if is_success(container_info[\u0027status\u0027]):"},{"line_number":1055,"context_line":"                primary_policy_idx \u003d container_info[\u0027storage_policy\u0027]"},{"line_number":1056,"context_line":"                hdrs \u003d {\u0027X-Storage-Policy\u0027: POLICIES[primary_policy_idx].name}"},{"line_number":1057,"context_line":"            else:"},{"line_number":1058,"context_line":"                if \u0027X-Storage-Policy\u0027 in req.headers:"}],"source_content_type":"text/x-python","patch_set":61,"id":"3fa7e38b_e66c579e","line":1055,"in_reply_to":"3fa7e38b_a9ebd50e","updated":"2020-01-08 22:41:42.000000000","message":"Addressed in https://review.opendev.org/#/c/701453/ which was squashed in with PS 69.","commit_id":"de1658ab0b68cd37640841dc718b1f8c63950c03"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7dbbbeae69ecc88e1940e6c30ec9d19c58b061f3","unresolved":false,"context_lines":[{"line_number":1055,"context_line":"                primary_policy_idx \u003d container_info[\u0027storage_policy\u0027]"},{"line_number":1056,"context_line":"                hdrs \u003d {\u0027X-Storage-Policy\u0027: POLICIES[primary_policy_idx].name}"},{"line_number":1057,"context_line":"            else:"},{"line_number":1058,"context_line":"                if \u0027X-Storage-Policy\u0027 in req.headers:"},{"line_number":1059,"context_line":"                    hdrs \u003d {\u0027X-Storage-Policy\u0027:"},{"line_number":1060,"context_line":"                            req.headers[\u0027X-Storage-Policy\u0027]}"},{"line_number":1061,"context_line":"                else:"}],"source_content_type":"text/x-python","patch_set":61,"id":"3fa7e38b_c9f091ff","line":1058,"updated":"2019-12-28 07:00:49.000000000","message":"Should this include an\n\n and req.method \u003d\u003d \u0027PUT\u0027\n\n? That\u0027s the main case this is trying to cover, right? PUT when the primary container doesn\u0027t exist yet?","commit_id":"de1658ab0b68cd37640841dc718b1f8c63950c03"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7a0c13dfe1ed1f88602ecb6099c9d33f41506fdf","unresolved":false,"context_lines":[{"line_number":781,"context_line":"        elif not versions_cont and version !\u003d \u0027null\u0027:"},{"line_number":782,"context_line":"            raise HTTPBadRequest("},{"line_number":783,"context_line":"                \u0027version-aware operations require that the container is \u0027"},{"line_number":784,"context_line":"                \u0027versioned\u0027, request\u003dreq)"},{"line_number":785,"context_line":"        if version !\u003d \u0027null\u0027:"},{"line_number":786,"context_line":"            try:"},{"line_number":787,"context_line":"                Timestamp(version)"}],"source_content_type":"text/x-python","patch_set":66,"id":"3fa7e38b_ff42ad3b","line":784,"updated":"2020-01-06 22:55:39.000000000","message":"Hmm... so if we get in a bad state where we\u0027ve got an archive with no primary... then naively pop it back into existence *without* turning on versioning again... this\u0027ll block us from doing anything with the old versions :-/\n\nvagrant@saio:~$ curl -s http://saio:8090/v1/AUTH_test/bucket?format\u003djson\\\u0026versions | jq\n[\n  {\n    \"bytes\": 0,\n    \"hash\": \"d41d8cd98f00b204e9800998ecf8427e\",\n    \"name\": \".profile\",\n    \"content_type\": \"application/x-deleted;swift_versions_deleted\u003d1\",\n    \"last_modified\": \"2020-01-06T21:58:23.359410\",\n    \"is_latest\": true,\n    \"version_id\": \"1578347903.35793\"\n  },\n  {\n    \"bytes\": 1089,\n    \"hash\": \"6da07eb1c4a401f670d979199ed3b6a4\",\n    \"name\": \".profile\",\n    \"content_type\": \"application/octet-stream\",\n    \"last_modified\": \"2020-01-06T21:49:22.615450\",\n    \"is_latest\": false,\n    \"version_id\": \"1578347362.61545\"\n  },\n  {\n    \"bytes\": 0,\n    \"hash\": \"d41d8cd98f00b204e9800998ecf8427e\",\n    \"name\": \".s3cfg\",\n    \"content_type\": \"application/x-deleted;swift_versions_deleted\u003d1\",\n    \"last_modified\": \"2020-01-06T21:58:23.404920\",\n    \"is_latest\": true,\n    \"version_id\": \"1578347903.40401\"\n  },\n  {\n    \"bytes\": 120,\n    \"hash\": \"7f89364dbaef92bcf78eff70b3c5fd9d\",\n    \"name\": \".s3cfg\",\n    \"content_type\": \"application/octet-stream\",\n    \"last_modified\": \"2020-01-06T21:49:22.706420\",\n    \"is_latest\": false,\n    \"version_id\": \"1578347362.70642\"\n  }\n]\nvagrant@saio:~$ curl http://saio:8090/v1/AUTH_test/bucket/.s3cfg?version-id\u003d1578347362.70642\nversion-aware operations require that the container is versioned\n\nOnce we turn if back on, of course, everything\u0027s fine, though, so *that\u0027s* good!\n\nOh... unless you take it right to suspended, since we only set X-Container-Sysmeta-Versions-Container when enabling...","commit_id":"4a2580e2a644dc7a47d63f8dedf245a203ac0223"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7a0c13dfe1ed1f88602ecb6099c9d33f41506fdf","unresolved":false,"context_lines":[{"line_number":1292,"context_line":"            else:"},{"line_number":1293,"context_line":"                # list hidden versions containers"},{"line_number":1294,"context_line":"                # It might be necessary to issue multiple listing requests"},{"line_number":1295,"context_line":"                # because of paging limitations, hence the while loop."},{"line_number":1296,"context_line":"                params \u003d req.params"},{"line_number":1297,"context_line":"                versions_dict \u003d {}"},{"line_number":1298,"context_line":"                while True:"}],"source_content_type":"text/x-python","patch_set":66,"id":"3fa7e38b_1f40e931","line":1295,"updated":"2020-01-06 22:55:39.000000000","message":"We\u0027ll have the same page limit for the client and reserved listings... is this really necessary?","commit_id":"4a2580e2a644dc7a47d63f8dedf245a203ac0223"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"f1f8b1b3b1b14e2e5d4a2ebacbf0da3a2325c950","unresolved":false,"context_lines":[{"line_number":1292,"context_line":"            else:"},{"line_number":1293,"context_line":"                # list hidden versions containers"},{"line_number":1294,"context_line":"                # It might be necessary to issue multiple listing requests"},{"line_number":1295,"context_line":"                # because of paging limitations, hence the while loop."},{"line_number":1296,"context_line":"                params \u003d req.params"},{"line_number":1297,"context_line":"                versions_dict \u003d {}"},{"line_number":1298,"context_line":"                while True:"}],"source_content_type":"text/x-python","patch_set":66,"id":"3fa7e38b_a7ce6bb4","line":1295,"in_reply_to":"3fa7e38b_1f40e931","updated":"2020-01-08 20:25:17.000000000","message":"is the loop necessary? I think so because of the possibility of orphan hidden containers, so you might not have a 1:1 mapping of the original list to the hidden containers list","commit_id":"4a2580e2a644dc7a47d63f8dedf245a203ac0223"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5156649e864434c37822e4c079b3ef4e18ccbb92","unresolved":false,"context_lines":[{"line_number":1292,"context_line":"            else:"},{"line_number":1293,"context_line":"                # list hidden versions containers"},{"line_number":1294,"context_line":"                # It might be necessary to issue multiple listing requests"},{"line_number":1295,"context_line":"                # because of paging limitations, hence the while loop."},{"line_number":1296,"context_line":"                params \u003d req.params"},{"line_number":1297,"context_line":"                versions_dict \u003d {}"},{"line_number":1298,"context_line":"                while True:"}],"source_content_type":"text/x-python","patch_set":66,"id":"3fa7e38b_a27fceba","line":1295,"in_reply_to":"3fa7e38b_6e44ae9f","updated":"2020-01-14 20:05:39.000000000","message":"*bump*","commit_id":"4a2580e2a644dc7a47d63f8dedf245a203ac0223"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1292,"context_line":"            else:"},{"line_number":1293,"context_line":"                # list hidden versions containers"},{"line_number":1294,"context_line":"                # It might be necessary to issue multiple listing requests"},{"line_number":1295,"context_line":"                # because of paging limitations, hence the while loop."},{"line_number":1296,"context_line":"                params \u003d req.params"},{"line_number":1297,"context_line":"                versions_dict \u003d {}"},{"line_number":1298,"context_line":"                while True:"}],"source_content_type":"text/x-python","patch_set":66,"id":"3fa7e38b_6e44ae9f","line":1295,"in_reply_to":"3fa7e38b_a7ce6bb4","updated":"2020-01-08 22:41:42.000000000","message":"But any orphaned containers would get their own entry, too, right? So if we got a full page\u0027s worth of user-namespace containers, any orphans should start pushing out the user containers at the end.\n\nOr can we get back more than CONTAINER_LISTING_LIMIT entries now?","commit_id":"4a2580e2a644dc7a47d63f8dedf245a203ac0223"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7a0c13dfe1ed1f88602ecb6099c9d33f41506fdf","unresolved":false,"context_lines":[{"line_number":1383,"context_line":"                # (possibly storing data) that should have been deleted"},{"line_number":1384,"context_line":"                # along with the primary container. In this case, let\u0027s add"},{"line_number":1385,"context_line":"                # those containers to listing so users can be aware and"},{"line_number":1386,"context_line":"                # clean them up"},{"line_number":1387,"context_line":"                for key in versions_dict:"},{"line_number":1388,"context_line":"                    item \u003d versions_dict[key]"},{"line_number":1389,"context_line":"                    item[\u0027name\u0027] \u003d key"}],"source_content_type":"text/x-python","patch_set":66,"id":"3fa7e38b_bf72f5ae","line":1386,"updated":"2020-01-06 22:55:39.000000000","message":"We should probably include some indication of the fact that these are busted -- as it is, given a condition like \"this container 404s but still shows up in listings\", it\u0027s hard to distinguish between\n\n* ... because it\u0027s got a dangling object-versioning container, and\n* ... because the is-deleted update hasn\u0027t landed in the account db yet.","commit_id":"4a2580e2a644dc7a47d63f8dedf245a203ac0223"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7a0c13dfe1ed1f88602ecb6099c9d33f41506fdf","unresolved":false,"context_lines":[{"line_number":1385,"context_line":"                # those containers to listing so users can be aware and"},{"line_number":1386,"context_line":"                # clean them up"},{"line_number":1387,"context_line":"                for key in versions_dict:"},{"line_number":1388,"context_line":"                    item \u003d versions_dict[key]"},{"line_number":1389,"context_line":"                    item[\u0027name\u0027] \u003d key"},{"line_number":1390,"context_line":"                    listing.append(item)"},{"line_number":1391,"context_line":""}],"source_content_type":"text/x-python","patch_set":66,"id":"3fa7e38b_df77b19e","line":1388,"updated":"2020-01-06 22:55:39.000000000","message":"nit: Cleaner as\n\n for key, item in versions_dict.items():","commit_id":"4a2580e2a644dc7a47d63f8dedf245a203ac0223"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"f1f8b1b3b1b14e2e5d4a2ebacbf0da3a2325c950","unresolved":false,"context_lines":[{"line_number":1385,"context_line":"                # those containers to listing so users can be aware and"},{"line_number":1386,"context_line":"                # clean them up"},{"line_number":1387,"context_line":"                for key in versions_dict:"},{"line_number":1388,"context_line":"                    item \u003d versions_dict[key]"},{"line_number":1389,"context_line":"                    item[\u0027name\u0027] \u003d key"},{"line_number":1390,"context_line":"                    listing.append(item)"},{"line_number":1391,"context_line":""}],"source_content_type":"text/x-python","patch_set":66,"id":"3fa7e38b_e76f835e","line":1388,"in_reply_to":"3fa7e38b_df77b19e","updated":"2020-01-08 20:25:17.000000000","message":"Done in follow-up patch (along with other fixes)","commit_id":"4a2580e2a644dc7a47d63f8dedf245a203ac0223"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7a0c13dfe1ed1f88602ecb6099c9d33f41506fdf","unresolved":false,"context_lines":[{"line_number":1419,"context_line":"    def account_request(self, req, api_version, account, start_response):"},{"line_number":1420,"context_line":"        account_ctx \u003d AccountContext(self.app, self.logger)"},{"line_number":1421,"context_line":"        if req.method \u003d\u003d \u0027GET\u0027:"},{"line_number":1422,"context_line":"            return account_ctx.list_containers("},{"line_number":1423,"context_line":"                req, api_version, account, start_response)"},{"line_number":1424,"context_line":"        else:"},{"line_number":1425,"context_line":"            return self.app(req.environ, start_response)"}],"source_content_type":"text/x-python","patch_set":66,"id":"3fa7e38b_3f6605f0","line":1422,"updated":"2020-01-06 22:55:39.000000000","message":"Should we maybe skip this if\n\n X-Backend-Allow-Reserved-Names\n\nis on? *shrug*","commit_id":"4a2580e2a644dc7a47d63f8dedf245a203ac0223"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":226,"context_line":"        super(ObjectVersioningContext, self).__init__(wsgi_app)"},{"line_number":227,"context_line":"        self.logger \u003d logger"},{"line_number":228,"context_line":""},{"line_number":229,"context_line":"    def _build_versions_object_prefix(self, object_name):"},{"line_number":230,"context_line":"        return get_reserved_name(object_name, \u0027\u0027)"},{"line_number":231,"context_line":""},{"line_number":232,"context_line":"    def _build_versions_container_name(self, container_name):"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_756c7d6a","line":229,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":226,"context_line":"        super(ObjectVersioningContext, self).__init__(wsgi_app)"},{"line_number":227,"context_line":"        self.logger \u003d logger"},{"line_number":228,"context_line":""},{"line_number":229,"context_line":"    def _build_versions_object_prefix(self, object_name):"},{"line_number":230,"context_line":"        return get_reserved_name(object_name, \u0027\u0027)"},{"line_number":231,"context_line":""},{"line_number":232,"context_line":"    def _build_versions_container_name(self, container_name):"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_b5609ca5","line":229,"in_reply_to":"3fa7e38b_756c7d6a","updated":"2020-01-13 06:48:32.000000000","message":"Done","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":241,"context_line":"            name, inv \u003d split_reserved_name(versioned_name)"},{"line_number":242,"context_line":"            ts \u003d ~Timestamp(inv)"},{"line_number":243,"context_line":"        except ValueError:"},{"line_number":244,"context_line":"            return versioned_name, None"},{"line_number":245,"context_line":"        return name, ts"},{"line_number":246,"context_line":""},{"line_number":247,"context_line":"    def _split_versions_container_name(self, versions_container):"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_158d0929","line":244,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":241,"context_line":"            name, inv \u003d split_reserved_name(versioned_name)"},{"line_number":242,"context_line":"            ts \u003d ~Timestamp(inv)"},{"line_number":243,"context_line":"        except ValueError:"},{"line_number":244,"context_line":"            return versioned_name, None"},{"line_number":245,"context_line":"        return name, ts"},{"line_number":246,"context_line":""},{"line_number":247,"context_line":"    def _split_versions_container_name(self, versions_container):"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_555368de","line":244,"in_reply_to":"3fa7e38b_158d0929","updated":"2020-01-13 06:48:32.000000000","message":"Done","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":248,"context_line":"        try:"},{"line_number":249,"context_line":"            versions, container_name \u003d split_reserved_name(versions_container)"},{"line_number":250,"context_line":"        except ValueError:"},{"line_number":251,"context_line":"            return versions_container"},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"        if versions !\u003d \u0027versions\u0027:"},{"line_number":254,"context_line":"            return versions_container"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_95a01993","line":251,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":251,"context_line":"            return versions_container"},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"        if versions !\u003d \u0027versions\u0027:"},{"line_number":254,"context_line":"            return versions_container"},{"line_number":255,"context_line":""},{"line_number":256,"context_line":"        return container_name"},{"line_number":257,"context_line":""}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_55a621ae","line":254,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":258,"context_line":""},{"line_number":259,"context_line":"class ObjectContext(ObjectVersioningContext):"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"    def _listing_iter(self, account_name, lcontainer, lprefix, req):"},{"line_number":262,"context_line":"        try:"},{"line_number":263,"context_line":"            for page in self._listing_pages_iter(account_name, lcontainer,"},{"line_number":264,"context_line":"                                                 lprefix, req):"},{"line_number":265,"context_line":"                for item in page:"},{"line_number":266,"context_line":"                    yield item"},{"line_number":267,"context_line":"        except ListingIterNotFound:"},{"line_number":268,"context_line":"            pass"},{"line_number":269,"context_line":"        except ListingIterError:"},{"line_number":270,"context_line":"            raise HTTPInternalServerError(request\u003dreq)"},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"    def _listing_pages_iter(self, account_name, lcontainer, lprefix,"},{"line_number":273,"context_line":"                            req, marker\u003d\u0027\u0027, end_marker\u003d\u0027\u0027):"},{"line_number":274,"context_line":"        \u0027\u0027\u0027Get \"pages\" worth of objects that start with a prefix."},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"        The optional keyword arguments ``marker`` and ``end_marker``"},{"line_number":277,"context_line":"        are used similar to how they are for containers. We\u0027re"},{"line_number":278,"context_line":"        coming directly from ``_listing_iter``, so none of the"},{"line_number":279,"context_line":"        optional args are specified."},{"line_number":280,"context_line":"        \u0027\u0027\u0027"},{"line_number":281,"context_line":"        while True:"},{"line_number":282,"context_line":"            lreq \u003d make_pre_authed_request("},{"line_number":283,"context_line":"                req.environ, method\u003d\u0027GET\u0027, swift_source\u003d\u0027OV\u0027,"},{"line_number":284,"context_line":"                headers\u003d{\u0027X-Backend-Allow-Reserved-Names\u0027: \u0027true\u0027},"},{"line_number":285,"context_line":"                path\u003dwsgi_quote(\u0027/v1/%s/%s\u0027 % (account_name, lcontainer)))"},{"line_number":286,"context_line":"            lreq.environ[\u0027QUERY_STRING\u0027] \u003d \\"},{"line_number":287,"context_line":"                \u0027prefix\u003d%s\u0026marker\u003d%s\u0027 % (wsgi_quote(lprefix),"},{"line_number":288,"context_line":"                                         wsgi_quote(marker))"},{"line_number":289,"context_line":"            if end_marker:"},{"line_number":290,"context_line":"                lreq.environ[\u0027QUERY_STRING\u0027] +\u003d \u0027\u0026end_marker\u003d%s\u0027 % ("},{"line_number":291,"context_line":"                    wsgi_quote(end_marker))"},{"line_number":292,"context_line":"            lresp \u003d lreq.get_response(self.app)"},{"line_number":293,"context_line":"            if not is_success(lresp.status_int):"},{"line_number":294,"context_line":"                close_if_possible(lresp.app_iter)"},{"line_number":295,"context_line":"                if lresp.status_int \u003d\u003d HTTP_NOT_FOUND:"},{"line_number":296,"context_line":"                    raise ListingIterNotFound()"},{"line_number":297,"context_line":"                elif is_client_error(lresp.status_int):"},{"line_number":298,"context_line":"                    raise HTTPPreconditionFailed(request\u003dreq)"},{"line_number":299,"context_line":"                else:"},{"line_number":300,"context_line":"                    raise ListingIterError()"},{"line_number":301,"context_line":""},{"line_number":302,"context_line":"            if not lresp.body:"},{"line_number":303,"context_line":"                break"},{"line_number":304,"context_line":"            sublisting \u003d json.loads(lresp.body)"},{"line_number":305,"context_line":"            if not sublisting:"},{"line_number":306,"context_line":"                break"},{"line_number":307,"context_line":"            marker \u003d bytes_to_wsgi(sublisting[-1][\u0027name\u0027].encode(\u0027utf-8\u0027))"},{"line_number":308,"context_line":""},{"line_number":309,"context_line":"            sublisting \u003d ["},{"line_number":310,"context_line":"                item for item in sublisting"},{"line_number":311,"context_line":"                for name in [bytes_to_wsgi(item[\u0027name\u0027].encode(\u0027utf-8\u0027))]"},{"line_number":312,"context_line":"                if self._split_version_from_name(name)[1] is not None]"},{"line_number":313,"context_line":""},{"line_number":314,"context_line":"            if not sublisting:"},{"line_number":315,"context_line":"                continue"},{"line_number":316,"context_line":"            yield sublisting"},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"    def _get_source_object(self, req, path_info):"},{"line_number":319,"context_line":"        # make a pre_auth request in case the user has write access"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_f5806df8","line":316,"range":{"start_line":261,"start_character":4,"end_line":316,"end_character":28},"updated":"2020-01-08 22:41:42.000000000","message":"Unused.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":258,"context_line":""},{"line_number":259,"context_line":"class ObjectContext(ObjectVersioningContext):"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"    def _listing_iter(self, account_name, lcontainer, lprefix, req):"},{"line_number":262,"context_line":"        try:"},{"line_number":263,"context_line":"            for page in self._listing_pages_iter(account_name, lcontainer,"},{"line_number":264,"context_line":"                                                 lprefix, req):"},{"line_number":265,"context_line":"                for item in page:"},{"line_number":266,"context_line":"                    yield item"},{"line_number":267,"context_line":"        except ListingIterNotFound:"},{"line_number":268,"context_line":"            pass"},{"line_number":269,"context_line":"        except ListingIterError:"},{"line_number":270,"context_line":"            raise HTTPInternalServerError(request\u003dreq)"},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"    def _listing_pages_iter(self, account_name, lcontainer, lprefix,"},{"line_number":273,"context_line":"                            req, marker\u003d\u0027\u0027, end_marker\u003d\u0027\u0027):"},{"line_number":274,"context_line":"        \u0027\u0027\u0027Get \"pages\" worth of objects that start with a prefix."},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"        The optional keyword arguments ``marker`` and ``end_marker``"},{"line_number":277,"context_line":"        are used similar to how they are for containers. We\u0027re"},{"line_number":278,"context_line":"        coming directly from ``_listing_iter``, so none of the"},{"line_number":279,"context_line":"        optional args are specified."},{"line_number":280,"context_line":"        \u0027\u0027\u0027"},{"line_number":281,"context_line":"        while True:"},{"line_number":282,"context_line":"            lreq \u003d make_pre_authed_request("},{"line_number":283,"context_line":"                req.environ, method\u003d\u0027GET\u0027, swift_source\u003d\u0027OV\u0027,"},{"line_number":284,"context_line":"                headers\u003d{\u0027X-Backend-Allow-Reserved-Names\u0027: \u0027true\u0027},"},{"line_number":285,"context_line":"                path\u003dwsgi_quote(\u0027/v1/%s/%s\u0027 % (account_name, lcontainer)))"},{"line_number":286,"context_line":"            lreq.environ[\u0027QUERY_STRING\u0027] \u003d \\"},{"line_number":287,"context_line":"                \u0027prefix\u003d%s\u0026marker\u003d%s\u0027 % (wsgi_quote(lprefix),"},{"line_number":288,"context_line":"                                         wsgi_quote(marker))"},{"line_number":289,"context_line":"            if end_marker:"},{"line_number":290,"context_line":"                lreq.environ[\u0027QUERY_STRING\u0027] +\u003d \u0027\u0026end_marker\u003d%s\u0027 % ("},{"line_number":291,"context_line":"                    wsgi_quote(end_marker))"},{"line_number":292,"context_line":"            lresp \u003d lreq.get_response(self.app)"},{"line_number":293,"context_line":"            if not is_success(lresp.status_int):"},{"line_number":294,"context_line":"                close_if_possible(lresp.app_iter)"},{"line_number":295,"context_line":"                if lresp.status_int \u003d\u003d HTTP_NOT_FOUND:"},{"line_number":296,"context_line":"                    raise ListingIterNotFound()"},{"line_number":297,"context_line":"                elif is_client_error(lresp.status_int):"},{"line_number":298,"context_line":"                    raise HTTPPreconditionFailed(request\u003dreq)"},{"line_number":299,"context_line":"                else:"},{"line_number":300,"context_line":"                    raise ListingIterError()"},{"line_number":301,"context_line":""},{"line_number":302,"context_line":"            if not lresp.body:"},{"line_number":303,"context_line":"                break"},{"line_number":304,"context_line":"            sublisting \u003d json.loads(lresp.body)"},{"line_number":305,"context_line":"            if not sublisting:"},{"line_number":306,"context_line":"                break"},{"line_number":307,"context_line":"            marker \u003d bytes_to_wsgi(sublisting[-1][\u0027name\u0027].encode(\u0027utf-8\u0027))"},{"line_number":308,"context_line":""},{"line_number":309,"context_line":"            sublisting \u003d ["},{"line_number":310,"context_line":"                item for item in sublisting"},{"line_number":311,"context_line":"                for name in [bytes_to_wsgi(item[\u0027name\u0027].encode(\u0027utf-8\u0027))]"},{"line_number":312,"context_line":"                if self._split_version_from_name(name)[1] is not None]"},{"line_number":313,"context_line":""},{"line_number":314,"context_line":"            if not sublisting:"},{"line_number":315,"context_line":"                continue"},{"line_number":316,"context_line":"            yield sublisting"},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"    def _get_source_object(self, req, path_info):"},{"line_number":319,"context_line":"        # make a pre_auth request in case the user has write access"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_753d448b","line":316,"range":{"start_line":261,"start_character":4,"end_line":316,"end_character":28},"in_reply_to":"3fa7e38b_f5806df8","updated":"2020-01-13 06:48:32.000000000","message":"removed","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":327,"context_line":"        if source_resp.content_length is None or \\"},{"line_number":328,"context_line":"                source_resp.content_length \u003e MAX_FILE_SIZE:"},{"line_number":329,"context_line":"            close_if_possible(source_resp.app_iter)"},{"line_number":330,"context_line":"            return HTTPRequestEntityTooLarge(request\u003dreq)"},{"line_number":331,"context_line":""},{"line_number":332,"context_line":"        return source_resp"},{"line_number":333,"context_line":""}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_15b669dd","line":330,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":367,"context_line":"        # a reference to the byte counter so we can get the bytes_read"},{"line_number":368,"context_line":"        if req.message_length() is None:"},{"line_number":369,"context_line":"            put_req.headers[\u0027transfer-encoding\u0027] \u003d \\"},{"line_number":370,"context_line":"                req.headers.get(\u0027transfer-encoding\u0027)"},{"line_number":371,"context_line":"        else:"},{"line_number":372,"context_line":"            put_req.content_length \u003d req.content_length"},{"line_number":373,"context_line":"        byte_counter \u003d ByteCountingReader(req.environ[\u0027wsgi.input\u0027])"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_f5ae2d7e","line":370,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by unit tests. *Maybe* func tests hit it?","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":378,"context_line":"        copy_header_subset(req, put_req, non_expiry_header)"},{"line_number":379,"context_line":"        if \u0027swift.content_type_overridden\u0027 in req.environ:"},{"line_number":380,"context_line":"            put_req.environ[\u0027swift.content_type_overridden\u0027] \u003d \\"},{"line_number":381,"context_line":"                req.environ.pop(\u0027swift.content_type_overridden\u0027)"},{"line_number":382,"context_line":""},{"line_number":383,"context_line":"        # do the write"},{"line_number":384,"context_line":"        put_resp \u003d put_req.get_response(self.app)"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_1560a934","line":381,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by unit tests, but SLO func tests *should* hit it.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":392,"context_line":"        # _validate_etag_and_update_sysmeta to deal with SLO"},{"line_number":393,"context_line":"        slo_size \u003d put_req.headers.get(\u0027X-Object-Sysmeta-Slo-Size\u0027)"},{"line_number":394,"context_line":"        if slo_size:"},{"line_number":395,"context_line":"            put_bytes \u003d slo_size"},{"line_number":396,"context_line":"        put_content_type \u003d parse_content_type("},{"line_number":397,"context_line":"            put_req.headers[\u0027Content-Type\u0027])[0]"},{"line_number":398,"context_line":""}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_15ee698a","line":395,"updated":"2020-01-08 22:41:42.000000000","message":"Same as above.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":632,"context_line":""},{"line_number":633,"context_line":"        # if it\u0027s a versioning symlink, send post to versioned object"},{"line_number":634,"context_line":"        if resp.status_int \u003d\u003d 307 and config_true_value("},{"line_number":635,"context_line":"                resp.headers.get(SYSMETA_VERSIONS_SYMLINK, \u0027false\u0027)):"},{"line_number":636,"context_line":"            loc \u003d wsgi_unquote(resp.headers[\u0027Location\u0027])"},{"line_number":637,"context_line":""},{"line_number":638,"context_line":"            # Only follow if the version container matches"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_d89ec8b5","line":635,"updated":"2020-01-08 22:41:42.000000000","message":"No unit tests for POSTs to non-symlinks.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":632,"context_line":""},{"line_number":633,"context_line":"        # if it\u0027s a versioning symlink, send post to versioned object"},{"line_number":634,"context_line":"        if resp.status_int \u003d\u003d 307 and config_true_value("},{"line_number":635,"context_line":"                resp.headers.get(SYSMETA_VERSIONS_SYMLINK, \u0027false\u0027)):"},{"line_number":636,"context_line":"            loc \u003d wsgi_unquote(resp.headers[\u0027Location\u0027])"},{"line_number":637,"context_line":""},{"line_number":638,"context_line":"            # Only follow if the version container matches"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_b3e66213","line":635,"in_reply_to":"3fa7e38b_d89ec8b5","updated":"2020-01-13 06:48:32.000000000","message":"Done","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":636,"context_line":"            loc \u003d wsgi_unquote(resp.headers[\u0027Location\u0027])"},{"line_number":637,"context_line":""},{"line_number":638,"context_line":"            # Only follow if the version container matches"},{"line_number":639,"context_line":"            if split_path(loc, 4, 4, True)[1:3] \u003d\u003d ["},{"line_number":640,"context_line":"                    account, versions_cont]:"},{"line_number":641,"context_line":"                close_if_possible(resp.app_iter)"},{"line_number":642,"context_line":"                post_req.path_info \u003d loc"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_58b2d84b","line":639,"updated":"2020-01-08 22:41:42.000000000","message":"No unit tests for mismatched containers.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":636,"context_line":"            loc \u003d wsgi_unquote(resp.headers[\u0027Location\u0027])"},{"line_number":637,"context_line":""},{"line_number":638,"context_line":"            # Only follow if the version container matches"},{"line_number":639,"context_line":"            if split_path(loc, 4, 4, True)[1:3] \u003d\u003d ["},{"line_number":640,"context_line":"                    account, versions_cont]:"},{"line_number":641,"context_line":"                close_if_possible(resp.app_iter)"},{"line_number":642,"context_line":"                post_req.path_info \u003d loc"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_b3942243","line":639,"in_reply_to":"3fa7e38b_58b2d84b","updated":"2020-01-13 06:48:32.000000000","message":"Done","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":646,"context_line":"    def _check_head(self, req, auth_token_header):"},{"line_number":647,"context_line":"        obj_head_headers \u003d {"},{"line_number":648,"context_line":"            \u0027X-Newest\u0027: \u0027True\u0027,"},{"line_number":649,"context_line":"            \u0027X-Backend-Allow-Reserved-Names\u0027: \u0027true\u0027,"},{"line_number":650,"context_line":"        }"},{"line_number":651,"context_line":"        obj_head_headers.update(auth_token_header)"},{"line_number":652,"context_line":"        head_req \u003d make_pre_authed_request("}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_b890ac97","line":649,"updated":"2020-01-08 22:41:42.000000000","message":"Do we actually need this for this HEAD?","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":646,"context_line":"    def _check_head(self, req, auth_token_header):"},{"line_number":647,"context_line":"        obj_head_headers \u003d {"},{"line_number":648,"context_line":"            \u0027X-Newest\u0027: \u0027True\u0027,"},{"line_number":649,"context_line":"            \u0027X-Backend-Allow-Reserved-Names\u0027: \u0027true\u0027,"},{"line_number":650,"context_line":"        }"},{"line_number":651,"context_line":"        obj_head_headers.update(auth_token_header)"},{"line_number":652,"context_line":"        head_req \u003d make_pre_authed_request("}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_93700644","line":649,"in_reply_to":"3fa7e38b_b890ac97","updated":"2020-01-13 06:48:32.000000000","message":"removed","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":656,"context_line":"        head_is_tombstone \u003d False"},{"line_number":657,"context_line":"        symlink_target \u003d None"},{"line_number":658,"context_line":"        if hresp.status_int \u003d\u003d HTTP_NOT_FOUND:"},{"line_number":659,"context_line":"            head_is_tombstone \u003d True"},{"line_number":660,"context_line":"        else:"},{"line_number":661,"context_line":"            head_is_tombstone \u003d False"},{"line_number":662,"context_line":"            # if there\u0027s any other kind of error with a broken link..."}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_f87aa473","line":659,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by unit tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":656,"context_line":"        head_is_tombstone \u003d False"},{"line_number":657,"context_line":"        symlink_target \u003d None"},{"line_number":658,"context_line":"        if hresp.status_int \u003d\u003d HTTP_NOT_FOUND:"},{"line_number":659,"context_line":"            head_is_tombstone \u003d True"},{"line_number":660,"context_line":"        else:"},{"line_number":661,"context_line":"            head_is_tombstone \u003d False"},{"line_number":662,"context_line":"            # if there\u0027s any other kind of error with a broken link..."}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_7360ea35","line":659,"in_reply_to":"3fa7e38b_f87aa473","updated":"2020-01-13 06:48:32.000000000","message":"Done","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":689,"context_line":"                api_version, account_name, versions_cont, versions_obj)"},{"line_number":690,"context_line":"            req.headers[\u0027X-Backend-Allow-Reserved-Names\u0027] \u003d \u0027true\u0027"},{"line_number":691,"context_line":"            if head_is_tombstone:"},{"line_number":692,"context_line":"                resp_version_id \u003d \u0027null\u0027"},{"line_number":693,"context_line":"            else:"},{"line_number":694,"context_line":"                _, vers_obj_name \u003d wsgi_unquote(symlink_target).split(\u0027/\u0027, 1)"},{"line_number":695,"context_line":"                resp_version_id \u003d self._split_version_from_name("}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_d8ec8829","line":692,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by unit tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":689,"context_line":"                api_version, account_name, versions_cont, versions_obj)"},{"line_number":690,"context_line":"            req.headers[\u0027X-Backend-Allow-Reserved-Names\u0027] \u003d \u0027true\u0027"},{"line_number":691,"context_line":"            if head_is_tombstone:"},{"line_number":692,"context_line":"                resp_version_id \u003d \u0027null\u0027"},{"line_number":693,"context_line":"            else:"},{"line_number":694,"context_line":"                _, vers_obj_name \u003d wsgi_unquote(symlink_target).split(\u0027/\u0027, 1)"},{"line_number":695,"context_line":"                resp_version_id \u003d self._split_version_from_name("}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_b36c2234","line":692,"in_reply_to":"3fa7e38b_d8ec8829","updated":"2020-01-13 06:48:32.000000000","message":"Done","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":691,"context_line":"            if head_is_tombstone:"},{"line_number":692,"context_line":"                resp_version_id \u003d \u0027null\u0027"},{"line_number":693,"context_line":"            else:"},{"line_number":694,"context_line":"                _, vers_obj_name \u003d wsgi_unquote(symlink_target).split(\u0027/\u0027, 1)"},{"line_number":695,"context_line":"                resp_version_id \u003d self._split_version_from_name("},{"line_number":696,"context_line":"                    vers_obj_name)[1].internal"},{"line_number":697,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_0e297af0","line":694,"updated":"2020-01-08 22:41:42.000000000","message":"Carrying forward from PS 52:\n\nI\u0027m a little nervous that this could be something other than versions_cont, or that _split_version_from_name() might come back None -- but either of those would require a decent bit of effort on the part of the operator, right? Surely they\u0027d know they were off the happy path by then...\n\nOr can we run into trouble with static links the user created while versioning was suspended?","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":691,"context_line":"            if head_is_tombstone:"},{"line_number":692,"context_line":"                resp_version_id \u003d \u0027null\u0027"},{"line_number":693,"context_line":"            else:"},{"line_number":694,"context_line":"                _, vers_obj_name \u003d wsgi_unquote(symlink_target).split(\u0027/\u0027, 1)"},{"line_number":695,"context_line":"                resp_version_id \u003d self._split_version_from_name("},{"line_number":696,"context_line":"                    vers_obj_name)[1].internal"},{"line_number":697,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_535b6e88","line":694,"in_reply_to":"3fa7e38b_0e297af0","updated":"2020-01-13 06:48:32.000000000","message":"actually uncovered a bug where head_is_tombstone \u003d\u003d False and symlink_target \u003d\u003d None. This would happen when user wants to delete older version while versioning is suspended AND there is a \u0027null\u0027 version (!\u003d symlink_target). Please review new logic and tests to make sure I got it right and let me know if you think I\u0027m still missing a corner case.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5156649e864434c37822e4c079b3ef4e18ccbb92","unresolved":false,"context_lines":[{"line_number":691,"context_line":"            if head_is_tombstone:"},{"line_number":692,"context_line":"                resp_version_id \u003d \u0027null\u0027"},{"line_number":693,"context_line":"            else:"},{"line_number":694,"context_line":"                _, vers_obj_name \u003d wsgi_unquote(symlink_target).split(\u0027/\u0027, 1)"},{"line_number":695,"context_line":"                resp_version_id \u003d self._split_version_from_name("},{"line_number":696,"context_line":"                    vers_obj_name)[1].internal"},{"line_number":697,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_8f9e7ab5","line":694,"in_reply_to":"3fa7e38b_535b6e88","updated":"2020-01-14 20:05:39.000000000","message":"Logic looks right. Good catch!","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":731,"context_line":"            versions_obj_name \u003d self._build_versions_object_name("},{"line_number":732,"context_line":"                object_name, version)"},{"line_number":733,"context_line":"        except ValueError:"},{"line_number":734,"context_line":"            raise HTTPBadRequest(\u0027Invalid version parameter\u0027, request\u003dreq)"},{"line_number":735,"context_line":"        versioned_obj_path \u003d \"/%s/%s/%s/%s\" % ("},{"line_number":736,"context_line":"            api_version, account_name, versions_cont, versions_obj_name)"},{"line_number":737,"context_line":"        obj_head_headers \u003d {\u0027X-Backend-Allow-Reserved-Names\u0027: \u0027true\u0027}"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_d8c56891","line":734,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":731,"context_line":"            versions_obj_name \u003d self._build_versions_object_name("},{"line_number":732,"context_line":"                object_name, version)"},{"line_number":733,"context_line":"        except ValueError:"},{"line_number":734,"context_line":"            raise HTTPBadRequest(\u0027Invalid version parameter\u0027, request\u003dreq)"},{"line_number":735,"context_line":"        versioned_obj_path \u003d \"/%s/%s/%s/%s\" % ("},{"line_number":736,"context_line":"            api_version, account_name, versions_cont, versions_obj_name)"},{"line_number":737,"context_line":"        obj_head_headers \u003d {\u0027X-Backend-Allow-Reserved-Names\u0027: \u0027true\u0027}"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_53b7ee89","line":734,"in_reply_to":"3fa7e38b_d8c56891","updated":"2020-01-13 06:48:32.000000000","message":"I actually removed the try block since the version is checked by the caller of handle_put_version.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":781,"context_line":"        elif not versions_cont and version !\u003d \u0027null\u0027:"},{"line_number":782,"context_line":"            raise HTTPBadRequest("},{"line_number":783,"context_line":"                \u0027version-aware operations require that the container is \u0027"},{"line_number":784,"context_line":"                \u0027versioned\u0027, request\u003dreq)"},{"line_number":785,"context_line":"        if version !\u003d \u0027null\u0027:"},{"line_number":786,"context_line":"            try:"},{"line_number":787,"context_line":"                Timestamp(version)"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_58b97813","line":784,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":781,"context_line":"        elif not versions_cont and version !\u003d \u0027null\u0027:"},{"line_number":782,"context_line":"            raise HTTPBadRequest("},{"line_number":783,"context_line":"                \u0027version-aware operations require that the container is \u0027"},{"line_number":784,"context_line":"                \u0027versioned\u0027, request\u003dreq)"},{"line_number":785,"context_line":"        if version !\u003d \u0027null\u0027:"},{"line_number":786,"context_line":"            try:"},{"line_number":787,"context_line":"                Timestamp(version)"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_b3a1823d","line":784,"in_reply_to":"3fa7e38b_58b97813","updated":"2020-01-13 06:48:32.000000000","message":"Done","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":798,"context_line":"                container, obj, is_enabled, version)"},{"line_number":799,"context_line":"        if version \u003d\u003d \u0027null\u0027:"},{"line_number":800,"context_line":"            resp \u003d req.get_response(self.app)"},{"line_number":801,"context_line":"            if resp.is_success:"},{"line_number":802,"context_line":"                if \u0027%00versions%00\u0027 in resp.headers.get("},{"line_number":803,"context_line":"                        \u0027Content-Location\u0027, \u0027\u0027):"},{"line_number":804,"context_line":"                    # Have a latest version, but it\u0027s got a real version-id."}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_d80808d9","line":801,"updated":"2020-01-08 22:41:42.000000000","message":"Never false in unit tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":798,"context_line":"                container, obj, is_enabled, version)"},{"line_number":799,"context_line":"        if version \u003d\u003d \u0027null\u0027:"},{"line_number":800,"context_line":"            resp \u003d req.get_response(self.app)"},{"line_number":801,"context_line":"            if resp.is_success:"},{"line_number":802,"context_line":"                if \u0027%00versions%00\u0027 in resp.headers.get("},{"line_number":803,"context_line":"                        \u0027Content-Location\u0027, \u0027\u0027):"},{"line_number":804,"context_line":"                    # Have a latest version, but it\u0027s got a real version-id."}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_333912f1","line":801,"in_reply_to":"3fa7e38b_d80808d9","updated":"2020-01-13 06:48:32.000000000","message":"Done","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":804,"context_line":"                    # Have a latest version, but it\u0027s got a real version-id."},{"line_number":805,"context_line":"                    # Since the user specifically asked for null, return 404"},{"line_number":806,"context_line":"                    close_if_possible(resp.app_iter)"},{"line_number":807,"context_line":"                    raise HTTPNotFound(request\u003dreq)"},{"line_number":808,"context_line":"                resp.headers[\u0027X-Object-Version-Id\u0027] \u003d \u0027null\u0027"},{"line_number":809,"context_line":"                if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":810,"context_line":"                    close_if_possible(resp.app_iter)"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_9848502e","line":807,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":804,"context_line":"                    # Have a latest version, but it\u0027s got a real version-id."},{"line_number":805,"context_line":"                    # Since the user specifically asked for null, return 404"},{"line_number":806,"context_line":"                    close_if_possible(resp.app_iter)"},{"line_number":807,"context_line":"                    raise HTTPNotFound(request\u003dreq)"},{"line_number":808,"context_line":"                resp.headers[\u0027X-Object-Version-Id\u0027] \u003d \u0027null\u0027"},{"line_number":809,"context_line":"                if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":810,"context_line":"                    close_if_possible(resp.app_iter)"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_d31d1e79","line":807,"in_reply_to":"3fa7e38b_9848502e","updated":"2020-01-13 06:48:32.000000000","message":"Done","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":817,"context_line":"            req.headers[\u0027X-Backend-Allow-Reserved-Names\u0027] \u003d \u0027true\u0027"},{"line_number":818,"context_line":""},{"line_number":819,"context_line":"            resp \u003d req.get_response(self.app)"},{"line_number":820,"context_line":"            if resp.is_success:"},{"line_number":821,"context_line":"                resp.headers[\u0027X-Object-Version-Id\u0027] \u003d version"},{"line_number":822,"context_line":""},{"line_number":823,"context_line":"            # Well, except for some delete marker business..."}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_38611ca9","line":820,"updated":"2020-01-08 22:41:42.000000000","message":"Never false in unit tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":817,"context_line":"            req.headers[\u0027X-Backend-Allow-Reserved-Names\u0027] \u003d \u0027true\u0027"},{"line_number":818,"context_line":""},{"line_number":819,"context_line":"            resp \u003d req.get_response(self.app)"},{"line_number":820,"context_line":"            if resp.is_success:"},{"line_number":821,"context_line":"                resp.headers[\u0027X-Object-Version-Id\u0027] \u003d version"},{"line_number":822,"context_line":""},{"line_number":823,"context_line":"            # Well, except for some delete marker business..."}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_f31a9a7e","line":820,"in_reply_to":"3fa7e38b_38611ca9","updated":"2020-01-13 06:48:32.000000000","message":"Done","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":886,"context_line":"        \"\"\""},{"line_number":887,"context_line":"        app_resp \u003d self._app_call(req.environ)"},{"line_number":888,"context_line":"        _, account, container, _ \u003d req.split_path(3, 4, True)"},{"line_number":889,"context_line":"        if self._response_headers is None:"},{"line_number":890,"context_line":"            self._response_headers \u003d []"},{"line_number":891,"context_line":"        location \u003d \u0027\u0027"},{"line_number":892,"context_line":"        curr_bytes \u003d 0"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_f824e460","line":889,"range":{"start_line":889,"start_character":8,"end_line":889,"end_character":42},"updated":"2020-01-08 22:41:42.000000000","message":"When would this ever be the case?","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":886,"context_line":"        \"\"\""},{"line_number":887,"context_line":"        app_resp \u003d self._app_call(req.environ)"},{"line_number":888,"context_line":"        _, account, container, _ \u003d req.split_path(3, 4, True)"},{"line_number":889,"context_line":"        if self._response_headers is None:"},{"line_number":890,"context_line":"            self._response_headers \u003d []"},{"line_number":891,"context_line":"        location \u003d \u0027\u0027"},{"line_number":892,"context_line":"        curr_bytes \u003d 0"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_953480ad","line":889,"range":{"start_line":889,"start_character":8,"end_line":889,"end_character":42},"in_reply_to":"3fa7e38b_f824e460","updated":"2020-01-13 06:48:32.000000000","message":"removed","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":911,"context_line":"                    path\u003dwsgi_quote(\u0027/v1/%s/%s\u0027 % (account, location)),"},{"line_number":912,"context_line":"                    headers\u003d{\u0027X-Backend-Allow-Reserved-Names\u0027: \u0027true\u0027})"},{"line_number":913,"context_line":"                vresp \u003d head_req.get_response(self.app)"},{"line_number":914,"context_line":"                if vresp.is_success:"},{"line_number":915,"context_line":"                    ver_bytes \u003d vresp.headers.get(\u0027X-Container-Bytes-Used\u0027, 0)"},{"line_number":916,"context_line":"                    self._response_headers[bytes_idx] \u003d ("},{"line_number":917,"context_line":"                        \u0027X-Container-Bytes-Used\u0027,"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_b81aec14","line":914,"updated":"2020-01-08 22:41:42.000000000","message":"Always true in tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":937,"context_line":"            try:"},{"line_number":938,"context_line":"                listing \u003d json.loads(body)"},{"line_number":939,"context_line":"            except ValueError:"},{"line_number":940,"context_line":"                app_resp \u003d [body]"},{"line_number":941,"context_line":"            else:"},{"line_number":942,"context_line":"                for item in listing:"},{"line_number":943,"context_line":"                    if not all(x in item for x in ("}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_38d4bc1e","line":940,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":998,"context_line":"        versions_cont \u003d unquote(container_info.get("},{"line_number":999,"context_line":"            \u0027sysmeta\u0027, {}).get(\u0027versions-container\u0027, \u0027\u0027))"},{"line_number":1000,"context_line":""},{"line_number":1001,"context_line":"        if versions_cont:"},{"line_number":1002,"context_line":"            account \u003d req.split_path(3, 3, True)[1]"},{"line_number":1003,"context_line":"            versions_req \u003d make_pre_authed_request("},{"line_number":1004,"context_line":"                req.environ, method\u003d\u0027HEAD\u0027, swift_source\u003d\u0027OV\u0027,"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_78e55406","line":1001,"updated":"2020-01-08 22:41:42.000000000","message":"Always true in tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1000,"context_line":""},{"line_number":1001,"context_line":"        if versions_cont:"},{"line_number":1002,"context_line":"            account \u003d req.split_path(3, 3, True)[1]"},{"line_number":1003,"context_line":"            versions_req \u003d make_pre_authed_request("},{"line_number":1004,"context_line":"                req.environ, method\u003d\u0027HEAD\u0027, swift_source\u003d\u0027OV\u0027,"},{"line_number":1005,"context_line":"                path\u003dwsgi_quote(\u0027/v1/%s/%s\u0027 % ("},{"line_number":1006,"context_line":"                    account, str_to_wsgi(versions_cont))),"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_38a27cae","line":1003,"range":{"start_line":1003,"start_character":27,"end_line":1003,"end_character":50},"updated":"2020-01-08 22:41:42.000000000","message":"Why not use get_container_info? I guess, to make sure we have an up-to-date response?","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5156649e864434c37822e4c079b3ef4e18ccbb92","unresolved":false,"context_lines":[{"line_number":1000,"context_line":""},{"line_number":1001,"context_line":"        if versions_cont:"},{"line_number":1002,"context_line":"            account \u003d req.split_path(3, 3, True)[1]"},{"line_number":1003,"context_line":"            versions_req \u003d make_pre_authed_request("},{"line_number":1004,"context_line":"                req.environ, method\u003d\u0027HEAD\u0027, swift_source\u003d\u0027OV\u0027,"},{"line_number":1005,"context_line":"                path\u003dwsgi_quote(\u0027/v1/%s/%s\u0027 % ("},{"line_number":1006,"context_line":"                    account, str_to_wsgi(versions_cont))),"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_f72a6695","line":1003,"range":{"start_line":1003,"start_character":27,"end_line":1003,"end_character":50},"in_reply_to":"3fa7e38b_35434c13","updated":"2020-01-14 20:05:39.000000000","message":"*shrug* Just stood out to me as kinda odd.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":1000,"context_line":""},{"line_number":1001,"context_line":"        if versions_cont:"},{"line_number":1002,"context_line":"            account \u003d req.split_path(3, 3, True)[1]"},{"line_number":1003,"context_line":"            versions_req \u003d make_pre_authed_request("},{"line_number":1004,"context_line":"                req.environ, method\u003d\u0027HEAD\u0027, swift_source\u003d\u0027OV\u0027,"},{"line_number":1005,"context_line":"                path\u003dwsgi_quote(\u0027/v1/%s/%s\u0027 % ("},{"line_number":1006,"context_line":"                    account, str_to_wsgi(versions_cont))),"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_35434c13","line":1003,"range":{"start_line":1003,"start_character":27,"end_line":1003,"end_character":50},"in_reply_to":"3fa7e38b_38a27cae","updated":"2020-01-13 06:48:32.000000000","message":"correct, overkill?","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"fe337410415f7ab51783ce1b7ec64f96fa386cd2","unresolved":false,"context_lines":[{"line_number":1000,"context_line":""},{"line_number":1001,"context_line":"        if versions_cont:"},{"line_number":1002,"context_line":"            account \u003d req.split_path(3, 3, True)[1]"},{"line_number":1003,"context_line":"            versions_req \u003d make_pre_authed_request("},{"line_number":1004,"context_line":"                req.environ, method\u003d\u0027HEAD\u0027, swift_source\u003d\u0027OV\u0027,"},{"line_number":1005,"context_line":"                path\u003dwsgi_quote(\u0027/v1/%s/%s\u0027 % ("},{"line_number":1006,"context_line":"                    account, str_to_wsgi(versions_cont))),"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_7ea88a20","line":1003,"range":{"start_line":1003,"start_character":27,"end_line":1003,"end_character":50},"in_reply_to":"3fa7e38b_f72a6695","updated":"2020-01-15 01:00:00.000000000","message":"I\u0027ll add a comment to call out the reasoning","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1014,"context_line":"                    request\u003dreq)"},{"line_number":1015,"context_line":"            elif not vresp.is_success and vresp.status_int !\u003d 404:"},{"line_number":1016,"context_line":"                raise HTTPInternalServerError("},{"line_number":1017,"context_line":"                    \u0027Error deleting versioned container\u0027)"},{"line_number":1018,"context_line":"            else:"},{"line_number":1019,"context_line":"                versions_req.method \u003d \u0027DELETE\u0027"},{"line_number":1020,"context_line":"                resp \u003d versions_req.get_response(self.app)"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_f8a704ba","line":1017,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1081,"context_line":"                        request\u003dreq)"},{"line_number":1082,"context_line":"                hdrs \u003d {\u0027X-Storage-Policy\u0027: POLICIES[primary_policy_idx].name}"},{"line_number":1083,"context_line":"            else:"},{"line_number":1084,"context_line":"                if \u0027X-Storage-Policy\u0027 in req.headers:"},{"line_number":1085,"context_line":"                    hdrs \u003d {\u0027X-Storage-Policy\u0027:"},{"line_number":1086,"context_line":"                            req.headers[\u0027X-Storage-Policy\u0027]}"},{"line_number":1087,"context_line":"                else:"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_2e2c76ff","line":1084,"updated":"2020-01-08 22:41:42.000000000","message":"Carrying forward from PS 61:\n\nShould this include an\n\n and req.method \u003d\u003d \u0027PUT\u0027\n\n? Or maybe turn the line above into an\n\n elif req.method \u003d\u003d \u0027PUT\u0027:\n\n? That\u0027s the main case this is trying to cover, right? PUT when the primary container doesn\u0027t exist yet?","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":1081,"context_line":"                        request\u003dreq)"},{"line_number":1082,"context_line":"                hdrs \u003d {\u0027X-Storage-Policy\u0027: POLICIES[primary_policy_idx].name}"},{"line_number":1083,"context_line":"            else:"},{"line_number":1084,"context_line":"                if \u0027X-Storage-Policy\u0027 in req.headers:"},{"line_number":1085,"context_line":"                    hdrs \u003d {\u0027X-Storage-Policy\u0027:"},{"line_number":1086,"context_line":"                            req.headers[\u0027X-Storage-Policy\u0027]}"},{"line_number":1087,"context_line":"                else:"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_f3037a10","line":1084,"in_reply_to":"3fa7e38b_2e2c76ff","updated":"2020-01-13 06:48:32.000000000","message":"Done","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1142,"context_line":"            raise HTTPNotAcceptable(request\u003dreq)"},{"line_number":1143,"context_line":""},{"line_number":1144,"context_line":"        params \u003d req.params"},{"line_number":1145,"context_line":"        if \u0027version_marker\u0027 in params:"},{"line_number":1146,"context_line":"            if \u0027marker\u0027 not in params:"},{"line_number":1147,"context_line":"                raise HTTPBadRequest(\u0027version_marker param requires marker\u0027)"},{"line_number":1148,"context_line":""}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_2e15569b","line":1145,"updated":"2020-01-08 22:41:42.000000000","message":"Carrying over from PS 53:\n\nI wonder if there should also be a version_end_marker... particularly since we get something close to that behavior when using reverse...","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1143,"context_line":""},{"line_number":1144,"context_line":"        params \u003d req.params"},{"line_number":1145,"context_line":"        if \u0027version_marker\u0027 in params:"},{"line_number":1146,"context_line":"            if \u0027marker\u0027 not in params:"},{"line_number":1147,"context_line":"                raise HTTPBadRequest(\u0027version_marker param requires marker\u0027)"},{"line_number":1148,"context_line":""},{"line_number":1149,"context_line":"            if params[\u0027version_marker\u0027] !\u003d \u0027null\u0027:"},{"line_number":1150,"context_line":"                try:"},{"line_number":1151,"context_line":"                    ts \u003d Timestamp(params.pop(\u0027version_marker\u0027))"},{"line_number":1152,"context_line":"                except ValueError:"},{"line_number":1153,"context_line":"                    raise HTTPBadRequest(\u0027invalid version_marker param\u0027)"},{"line_number":1154,"context_line":""},{"line_number":1155,"context_line":"                params[\u0027marker\u0027] \u003d self._build_versions_object_name("},{"line_number":1156,"context_line":"                    params[\u0027marker\u0027], ts)"},{"line_number":1157,"context_line":"        elif \u0027marker\u0027 in params:"},{"line_number":1158,"context_line":"            params[\u0027marker\u0027] \u003d self._build_versions_object_prefix("},{"line_number":1159,"context_line":"                params[\u0027marker\u0027]) + \u0027:\u0027  # just past all numbers"},{"line_number":1160,"context_line":""},{"line_number":1161,"context_line":"        delim \u003d params.get(\u0027delimiter\u0027, \u0027\u0027)"},{"line_number":1162,"context_line":"        # Exclude the set of chars used in version_id from user delimiters"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_b88d0c36","line":1159,"range":{"start_line":1146,"start_character":12,"end_line":1159,"end_character":64},"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":1143,"context_line":""},{"line_number":1144,"context_line":"        params \u003d req.params"},{"line_number":1145,"context_line":"        if \u0027version_marker\u0027 in params:"},{"line_number":1146,"context_line":"            if \u0027marker\u0027 not in params:"},{"line_number":1147,"context_line":"                raise HTTPBadRequest(\u0027version_marker param requires marker\u0027)"},{"line_number":1148,"context_line":""},{"line_number":1149,"context_line":"            if params[\u0027version_marker\u0027] !\u003d \u0027null\u0027:"},{"line_number":1150,"context_line":"                try:"},{"line_number":1151,"context_line":"                    ts \u003d Timestamp(params.pop(\u0027version_marker\u0027))"},{"line_number":1152,"context_line":"                except ValueError:"},{"line_number":1153,"context_line":"                    raise HTTPBadRequest(\u0027invalid version_marker param\u0027)"},{"line_number":1154,"context_line":""},{"line_number":1155,"context_line":"                params[\u0027marker\u0027] \u003d self._build_versions_object_name("},{"line_number":1156,"context_line":"                    params[\u0027marker\u0027], ts)"},{"line_number":1157,"context_line":"        elif \u0027marker\u0027 in params:"},{"line_number":1158,"context_line":"            params[\u0027marker\u0027] \u003d self._build_versions_object_prefix("},{"line_number":1159,"context_line":"                params[\u0027marker\u0027]) + \u0027:\u0027  # just past all numbers"},{"line_number":1160,"context_line":""},{"line_number":1161,"context_line":"        delim \u003d params.get(\u0027delimiter\u0027, \u0027\u0027)"},{"line_number":1162,"context_line":"        # Exclude the set of chars used in version_id from user delimiters"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_d54d183c","line":1159,"range":{"start_line":1146,"start_character":12,"end_line":1159,"end_character":64},"in_reply_to":"3fa7e38b_b88d0c36","updated":"2020-01-13 06:48:32.000000000","message":"Done","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1161,"context_line":"        delim \u003d params.get(\u0027delimiter\u0027, \u0027\u0027)"},{"line_number":1162,"context_line":"        # Exclude the set of chars used in version_id from user delimiters"},{"line_number":1163,"context_line":"        if set(delim).intersection(\u00270123456789.%s\u0027 % RESERVED_STR):"},{"line_number":1164,"context_line":"            raise HTTPBadRequest(\u0027invalid delimiter param\u0027)"},{"line_number":1165,"context_line":""},{"line_number":1166,"context_line":"        null_listing \u003d []"},{"line_number":1167,"context_line":"        subdir_set \u003d set()"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_58989874","line":1164,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1190,"context_line":"        # we don\u0027t want to bookend the prefix with RESERVED_NAME as user"},{"line_number":1191,"context_line":"        # could be using just part of object name as the prefix."},{"line_number":1192,"context_line":"        if \u0027prefix\u0027 in params:"},{"line_number":1193,"context_line":"            params[\u0027prefix\u0027] \u003d get_reserved_name(params[\u0027prefix\u0027])"},{"line_number":1194,"context_line":""},{"line_number":1195,"context_line":"        # NB: no end_marker support (yet)"},{"line_number":1196,"context_line":"        versions_req.params \u003d {"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_b8766c3e","line":1193,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1206,"context_line":"                    item[\u0027symlink_path\u0027].encode(\u0027utf8\u0027)))).split(\u0027/\u0027, 4)[-1]"},{"line_number":1207,"context_line":"                name, ts \u003d self._split_version_from_name(linked_name)"},{"line_number":1208,"context_line":"                if ts is None:"},{"line_number":1209,"context_line":"                    continue"},{"line_number":1210,"context_line":"                name \u003d name.decode(\u0027utf8\u0027) if six.PY2 else name"},{"line_number":1211,"context_line":"                is_latest \u003d False"},{"line_number":1212,"context_line":"                if name not in is_latest_set:"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_58717844","line":1209,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1209,"context_line":"                    continue"},{"line_number":1210,"context_line":"                name \u003d name.decode(\u0027utf8\u0027) if six.PY2 else name"},{"line_number":1211,"context_line":"                is_latest \u003d False"},{"line_number":1212,"context_line":"                if name not in is_latest_set:"},{"line_number":1213,"context_line":"                    is_latest_set.add(name)"},{"line_number":1214,"context_line":"                    is_latest \u003d True"},{"line_number":1215,"context_line":"                broken_listing.append({"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_38903c42","line":1212,"updated":"2020-01-08 22:41:42.000000000","message":"Always true in tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1231,"context_line":"            try:"},{"line_number":1232,"context_line":"                listing \u003d json.loads(versions_resp.body)"},{"line_number":1233,"context_line":"            except ValueError:"},{"line_number":1234,"context_line":"                app_resp \u003d [body]"},{"line_number":1235,"context_line":"            else:"},{"line_number":1236,"context_line":"                versions_listing \u003d []"},{"line_number":1237,"context_line":"                for item in listing:"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_f895c431","line":1234,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1242,"context_line":"                    else:"},{"line_number":1243,"context_line":"                        name, ts \u003d self._split_version_from_name(item[\u0027name\u0027])"},{"line_number":1244,"context_line":"                        if ts is None:"},{"line_number":1245,"context_line":"                            continue"},{"line_number":1246,"context_line":"                        path \u003d \u0027/v1/%s/%s/%s\u0027 % ("},{"line_number":1247,"context_line":"                            wsgi_to_str(account),"},{"line_number":1248,"context_line":"                            wsgi_to_str(location),"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_98a05093","line":1245,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1267,"context_line":""},{"line_number":1268,"context_line":"                subdir_listing \u003d [{\u0027subdir\u0027: s} for s in subdir_set]"},{"line_number":1269,"context_line":"                broken_listing \u003d []"},{"line_number":1270,"context_line":"                for item in current_versions.values():"},{"line_number":1271,"context_line":"                    link_path \u003d wsgi_to_str(wsgi_unquote(bytes_to_wsgi("},{"line_number":1272,"context_line":"                        item[\u0027symlink_path\u0027].encode(\u0027utf-8\u0027))))"},{"line_number":1273,"context_line":"                    name, ts \u003d self._split_version_from_name("}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_58a658ae","line":1270,"range":{"start_line":1270,"start_character":28,"end_line":1270,"end_character":54},"updated":"2020-01-08 22:41:42.000000000","message":"Always empty in tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1303,"context_line":"    def list_containers(self, req, api_version, account, start_response):"},{"line_number":1304,"context_line":"        app_resp \u003d self._app_call(req.environ)"},{"line_number":1305,"context_line":""},{"line_number":1306,"context_line":"        if is_success(self._get_status_int()):"},{"line_number":1307,"context_line":"            with closing_if_possible(app_resp):"},{"line_number":1308,"context_line":"                body \u003d b\u0027\u0027.join(app_resp)"},{"line_number":1309,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_38b91cca","line":1306,"updated":"2020-01-08 22:41:42.000000000","message":"Always true in tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1309,"context_line":"            try:"},{"line_number":1310,"context_line":"                listing \u003d json.loads(body)"},{"line_number":1311,"context_line":"            except ValueError:"},{"line_number":1312,"context_line":"                app_resp \u003d [body]"},{"line_number":1313,"context_line":"            else:"},{"line_number":1314,"context_line":"                # list hidden versions containers"},{"line_number":1315,"context_line":"                # It might be necessary to issue multiple listing requests"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_d8ab286e","line":1312,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1350,"context_line":"                        versions_listing \u003d json.loads(versions_resp.body)"},{"line_number":1351,"context_line":"                    except ValueError:"},{"line_number":1352,"context_line":"                        close_if_possible(versions_resp.app_iter)"},{"line_number":1353,"context_line":"                        break"},{"line_number":1354,"context_line":"                    else:"},{"line_number":1355,"context_line":"                        close_if_possible(versions_resp.app_iter)"},{"line_number":1356,"context_line":""}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_b8c42c42","line":1353,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1386,"context_line":"                            params[\u0027end_marker\u0027] \u003d \\"},{"line_number":1387,"context_line":"                                self._build_versions_container_name(last_cont)"},{"line_number":1388,"context_line":"                    else:"},{"line_number":1389,"context_line":"                        break"},{"line_number":1390,"context_line":""},{"line_number":1391,"context_line":"                # update bytes from original listing with bytes from"},{"line_number":1392,"context_line":"                # versions cont"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_78ba34ba","line":1389,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests. Also, I\u0027d be inclined to save some indent by doing something like\n\n if not listing and not versions_listing:\n     break\n\nabove.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":1386,"context_line":"                            params[\u0027end_marker\u0027] \u003d \\"},{"line_number":1387,"context_line":"                                self._build_versions_container_name(last_cont)"},{"line_number":1388,"context_line":"                    else:"},{"line_number":1389,"context_line":"                        break"},{"line_number":1390,"context_line":""},{"line_number":1391,"context_line":"                # update bytes from original listing with bytes from"},{"line_number":1392,"context_line":"                # versions cont"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_1e02dd09","line":1389,"in_reply_to":"3fa7e38b_78ba34ba","updated":"2020-01-13 06:48:32.000000000","message":"i think for clarity i\u0027d still would add the else, no?","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1404,"context_line":"                # (possibly storing data) that should have been deleted"},{"line_number":1405,"context_line":"                # along with the primary container. In this case, let\u0027s add"},{"line_number":1406,"context_line":"                # those containers to listing so users can be aware and"},{"line_number":1407,"context_line":"                # clean them up"},{"line_number":1408,"context_line":"                for key, item in versions_dict.items():"},{"line_number":1409,"context_line":"                    item[\u0027name\u0027] \u003d key"},{"line_number":1410,"context_line":"                    listing.append(item)"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_0e773a0a","line":1407,"updated":"2020-01-08 22:41:42.000000000","message":"Carrying forward from PS 66:\n\nWe should probably include some indication of the fact that these are busted -- as it is, given a condition like \"this container 404s but still shows up in listings\", it\u0027s hard to distinguish between\n\n* ... because it\u0027s got a dangling object-versioning container, and\n* ... because the is-deleted update hasn\u0027t landed in the account db yet.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1428,"context_line":"        self.conf \u003d conf"},{"line_number":1429,"context_line":"        self.logger \u003d get_logger(conf, log_route\u003d\u0027object_versioning\u0027)"},{"line_number":1430,"context_line":""},{"line_number":1431,"context_line":"    def filter_reserved(self, listing):"},{"line_number":1432,"context_line":"        new_listing \u003d []"},{"line_number":1433,"context_line":"        for entry in list(listing):"},{"line_number":1434,"context_line":"            for key in (\u0027name\u0027, \u0027subdir\u0027):"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_986a9018","line":1431,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests. Also, I thought we do this elsewhere now?","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":1428,"context_line":"        self.conf \u003d conf"},{"line_number":1429,"context_line":"        self.logger \u003d get_logger(conf, log_route\u003d\u0027object_versioning\u0027)"},{"line_number":1430,"context_line":""},{"line_number":1431,"context_line":"    def filter_reserved(self, listing):"},{"line_number":1432,"context_line":"        new_listing \u003d []"},{"line_number":1433,"context_line":"        for entry in list(listing):"},{"line_number":1434,"context_line":"            for key in (\u0027name\u0027, \u0027subdir\u0027):"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_b59bbcc5","line":1431,"in_reply_to":"3fa7e38b_986a9018","updated":"2020-01-13 06:48:32.000000000","message":"removed","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1439,"context_line":"    def account_request(self, req, api_version, account, start_response):"},{"line_number":1440,"context_line":"        account_ctx \u003d AccountContext(self.app, self.logger)"},{"line_number":1441,"context_line":"        if req.method \u003d\u003d \u0027GET\u0027:"},{"line_number":1442,"context_line":"            return account_ctx.list_containers("},{"line_number":1443,"context_line":"                req, api_version, account, start_response)"},{"line_number":1444,"context_line":"        else:"},{"line_number":1445,"context_line":"            return self.app(req.environ, start_response)"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_2e7a36ef","line":1442,"updated":"2020-01-08 22:41:42.000000000","message":"Carrying forward from PS 66:\n\nShould we maybe skip this if\n\n X-Backend-Allow-Reserved-Names\n\nis on? I was a little surprised at the double-counting while poking around in the null namespace... *shrug*","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1442,"context_line":"            return account_ctx.list_containers("},{"line_number":1443,"context_line":"                req, api_version, account, start_response)"},{"line_number":1444,"context_line":"        else:"},{"line_number":1445,"context_line":"            return self.app(req.environ, start_response)"},{"line_number":1446,"context_line":""},{"line_number":1447,"context_line":"    def container_request(self, req, start_response):"},{"line_number":1448,"context_line":"        container_ctx \u003d ContainerContext(self.app, self.logger)"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_58709809","line":1445,"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1503,"context_line":"        try:"},{"line_number":1504,"context_line":"            (api_version, account, container, obj) \u003d req.split_path(2, 4, True)"},{"line_number":1505,"context_line":"            bad_path \u003d False"},{"line_number":1506,"context_line":"        except ValueError:"},{"line_number":1507,"context_line":"            bad_path \u003d True"},{"line_number":1508,"context_line":""},{"line_number":1509,"context_line":"        if bad_path:"},{"line_number":1510,"context_line":"            return self.app(env, start_response)"},{"line_number":1511,"context_line":""},{"line_number":1512,"context_line":"        try:"},{"line_number":1513,"context_line":"            if not container:"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_d8ca4817","line":1510,"range":{"start_line":1506,"start_character":8,"end_line":1510,"end_character":48},"updated":"2020-01-08 22:41:42.000000000","message":"Not covered by tests. Should probably also have a\n\n or not valid_api_version(api_version)\n\n(or move that up into where we set the boolean)","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5156649e864434c37822e4c079b3ef4e18ccbb92","unresolved":false,"context_lines":[{"line_number":1503,"context_line":"        try:"},{"line_number":1504,"context_line":"            (api_version, account, container, obj) \u003d req.split_path(2, 4, True)"},{"line_number":1505,"context_line":"            bad_path \u003d False"},{"line_number":1506,"context_line":"        except ValueError:"},{"line_number":1507,"context_line":"            bad_path \u003d True"},{"line_number":1508,"context_line":""},{"line_number":1509,"context_line":"        if bad_path:"},{"line_number":1510,"context_line":"            return self.app(env, start_response)"},{"line_number":1511,"context_line":""},{"line_number":1512,"context_line":"        try:"},{"line_number":1513,"context_line":"            if not container:"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_c2776a8e","line":1510,"range":{"start_line":1506,"start_character":8,"end_line":1510,"end_character":48},"in_reply_to":"3fa7e38b_156730ec","updated":"2020-01-14 20:05:39.000000000","message":"FWIW, the boolean was to clean up some tracebacks on py3 -- there, I\u0027ve learned from experience that I don\u0027t really want to call self.app inside an except block; you get tracebacks like\n\n Jan 14 18:30:24 saio proxy-server: ERROR Unhandled exception in request: \n Traceback (most recent call last):\n   File \"/vagrant/swift/swift/common/middleware/staticweb.py\", line 539, in __call__\n     split_path(env[\u0027PATH_INFO\u0027], 2, 4, True)\n   File \"/vagrant/swift/swift/common/utils.py\", line 1674, in split_path\n     raise ValueError(\u0027Invalid path: %s\u0027 % quote(path))\n ValueError: Invalid path: /info\n \n During handling of the above exception, another exception occurred:\n \n Traceback (most recent call last):\n   File \"/vagrant/swift/swift/common/middleware/versioned_writes/object_versioning.py\", line 1433, in __call__\n     (api_version, account, container, obj) \u003d req.split_path(2, 4, True)\n   File \"/vagrant/swift/swift/common/swob.py\", line 1186, in split_path\n     minsegs, maxsegs, rest_with_last)\n   File \"/vagrant/swift/swift/common/utils.py\", line 1674, in split_path\n     raise ValueError(\u0027Invalid path: %s\u0027 % quote(path))\n ValueError: Invalid path: /info\n \n During handling of the above exception, another exception occurred:\n \n Traceback (most recent call last):\n   File \"/vagrant/swift/swift/common/middleware/crypto/keymaster.py\", line 268, in __call__\n     parts \u003d req.split_path(2, 4, True)\n   File \"/vagrant/swift/swift/common/swob.py\", line 1186, in split_path\n     minsegs, maxsegs, rest_with_last)\n   File \"/vagrant/swift/swift/common/utils.py\", line 1674, in split_path\n     raise ValueError(\u0027Invalid path: %s\u0027 % quote(path))\n ValueError: Invalid path: /info\n \n During handling of the above exception, another exception occurred:\n \n Traceback (most recent call last):\n   File \"/vagrant/swift/swift/proxy/server.py\", line 523, in handle_request\n     controller \u003d controller(self, **path_parts)\n   File \"/vagrant/swift/swift/proxy/controllers/info.py\", line 32, in __init__\n     Boom()\n NameError: name \u0027Boom\u0027 is not defined (txn: txca966b5b962d4562a2e17-005e1e08c0)\n\n(Looks like there are a few more places I need to clean up...)","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"fe337410415f7ab51783ce1b7ec64f96fa386cd2","unresolved":false,"context_lines":[{"line_number":1503,"context_line":"        try:"},{"line_number":1504,"context_line":"            (api_version, account, container, obj) \u003d req.split_path(2, 4, True)"},{"line_number":1505,"context_line":"            bad_path \u003d False"},{"line_number":1506,"context_line":"        except ValueError:"},{"line_number":1507,"context_line":"            bad_path \u003d True"},{"line_number":1508,"context_line":""},{"line_number":1509,"context_line":"        if bad_path:"},{"line_number":1510,"context_line":"            return self.app(env, start_response)"},{"line_number":1511,"context_line":""},{"line_number":1512,"context_line":"        try:"},{"line_number":1513,"context_line":"            if not container:"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_de8e5ed6","line":1510,"range":{"start_line":1506,"start_character":8,"end_line":1510,"end_character":48},"in_reply_to":"3fa7e38b_c2776a8e","updated":"2020-01-15 01:00:00.000000000","message":"ouch, putting the boolean back, thanks for the heads up","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":1503,"context_line":"        try:"},{"line_number":1504,"context_line":"            (api_version, account, container, obj) \u003d req.split_path(2, 4, True)"},{"line_number":1505,"context_line":"            bad_path \u003d False"},{"line_number":1506,"context_line":"        except ValueError:"},{"line_number":1507,"context_line":"            bad_path \u003d True"},{"line_number":1508,"context_line":""},{"line_number":1509,"context_line":"        if bad_path:"},{"line_number":1510,"context_line":"            return self.app(env, start_response)"},{"line_number":1511,"context_line":""},{"line_number":1512,"context_line":"        try:"},{"line_number":1513,"context_line":"            if not container:"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_156730ec","line":1510,"range":{"start_line":1506,"start_character":8,"end_line":1510,"end_character":48},"in_reply_to":"3fa7e38b_d8ca4817","updated":"2020-01-13 06:48:32.000000000","message":"removed the boolean all together, not sure what the intent was...","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1515,"context_line":"                                            start_response)"},{"line_number":1516,"context_line":"            if container and not obj:"},{"line_number":1517,"context_line":"                return self.container_request(req, start_response)"},{"line_number":1518,"context_line":"            elif obj:"},{"line_number":1519,"context_line":"                return self.object_request("},{"line_number":1520,"context_line":"                    req, api_version, account, container,"},{"line_number":1521,"context_line":"                    obj)(env, start_response)"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_58de58db","line":1518,"range":{"start_line":1518,"start_character":12,"end_line":1518,"end_character":21},"updated":"2020-01-08 22:41:42.000000000","message":"Should this just be an else? Can we get to this point and still not have an obj?","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":1515,"context_line":"                                            start_response)"},{"line_number":1516,"context_line":"            if container and not obj:"},{"line_number":1517,"context_line":"                return self.container_request(req, start_response)"},{"line_number":1518,"context_line":"            elif obj:"},{"line_number":1519,"context_line":"                return self.object_request("},{"line_number":1520,"context_line":"                    req, api_version, account, container,"},{"line_number":1521,"context_line":"                    obj)(env, start_response)"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_35626cda","line":1518,"range":{"start_line":1518,"start_character":12,"end_line":1518,"end_character":21},"in_reply_to":"3fa7e38b_58de58db","updated":"2020-01-13 06:48:32.000000000","message":"Done","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":1522,"context_line":"        except HTTPException as error_response:"},{"line_number":1523,"context_line":"            return error_response(env, start_response)"},{"line_number":1524,"context_line":""},{"line_number":1525,"context_line":"        return self.app(env, start_response)"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_38f11c6b","line":1525,"updated":"2020-01-08 22:41:42.000000000","message":"I don\u0027t think we can ever get here.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"1396bc90d1cba039977ab4af97a4fd2e46725c3b","unresolved":false,"context_lines":[{"line_number":1522,"context_line":"        except HTTPException as error_response:"},{"line_number":1523,"context_line":"            return error_response(env, start_response)"},{"line_number":1524,"context_line":""},{"line_number":1525,"context_line":"        return self.app(env, start_response)"}],"source_content_type":"text/x-python","patch_set":70,"id":"3fa7e38b_d55c381b","line":1525,"in_reply_to":"3fa7e38b_38f11c6b","updated":"2020-01-13 06:48:32.000000000","message":"done, removed.","commit_id":"1c38c1aa66d2f229351fa3738167ecf30a77dde8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5156649e864434c37822e4c079b3ef4e18ccbb92","unresolved":false,"context_lines":[{"line_number":603,"context_line":"            # if there\u0027s any other kind of error with a broken link..."},{"line_number":604,"context_line":"            # I guess give up?"},{"line_number":605,"context_line":"            self._check_response_error(req, hresp)"},{"line_number":606,"context_line":"            if hresp.headers.get(SYSMETA_VERSIONS_SYMLINK) \u003d\u003d \u0027true\u0027:"},{"line_number":607,"context_line":"                symlink_target \u003d hresp.headers.get(TGT_OBJ_SYMLINK_HDR)"},{"line_number":608,"context_line":"        close_if_possible(hresp.app_iter)"},{"line_number":609,"context_line":"        return head_is_tombstone, symlink_target"}],"source_content_type":"text/x-python","patch_set":71,"id":"3fa7e38b_42713a45","line":606,"updated":"2020-01-14 20:05:39.000000000","message":"Oh good, we\u0027re smart and look for our flag before setting symlink_target here. For a moment, I was worried about whether the new functional test should try with a (client-created) symlink as the null version, too.","commit_id":"737b85326f2a2ef1faaa9858d4731c5cacb73395"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"fe337410415f7ab51783ce1b7ec64f96fa386cd2","unresolved":false,"context_lines":[{"line_number":603,"context_line":"            # if there\u0027s any other kind of error with a broken link..."},{"line_number":604,"context_line":"            # I guess give up?"},{"line_number":605,"context_line":"            self._check_response_error(req, hresp)"},{"line_number":606,"context_line":"            if hresp.headers.get(SYSMETA_VERSIONS_SYMLINK) \u003d\u003d \u0027true\u0027:"},{"line_number":607,"context_line":"                symlink_target \u003d hresp.headers.get(TGT_OBJ_SYMLINK_HDR)"},{"line_number":608,"context_line":"        close_if_possible(hresp.app_iter)"},{"line_number":609,"context_line":"        return head_is_tombstone, symlink_target"}],"source_content_type":"text/x-python","patch_set":71,"id":"3fa7e38b_9ee306a1","line":606,"in_reply_to":"3fa7e38b_42713a45","updated":"2020-01-15 01:00:00.000000000","message":"Done","commit_id":"737b85326f2a2ef1faaa9858d4731c5cacb73395"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5156649e864434c37822e4c079b3ef4e18ccbb92","unresolved":false,"context_lines":[{"line_number":621,"context_line":"        versions_obj \u003d self._build_versions_object_name("},{"line_number":622,"context_line":"            object_name, version)"},{"line_number":623,"context_line":""},{"line_number":624,"context_line":"        if (head_is_tombstone or not symlink_target or ("},{"line_number":625,"context_line":"            symlink_target and wsgi_unquote(symlink_target) !\u003d wsgi_unquote("},{"line_number":626,"context_line":"                \u0027%s/%s\u0027 % (versions_cont, versions_obj)))):"},{"line_number":627,"context_line":"            # if current version links to another version, then"},{"line_number":628,"context_line":"            # just delete the version issue requested to delete"},{"line_number":629,"context_line":"            req.path_info \u003d \"/%s/%s/%s/%s\" % ("}],"source_content_type":"text/x-python","patch_set":71,"id":"3fa7e38b_7782f6a8","line":626,"range":{"start_line":624,"start_character":8,"end_line":626,"end_character":59},"updated":"2020-01-14 20:05:39.000000000","message":"This is getting a little unwieldy to reason about... I think we can drop the \"symlink_target and\" now?","commit_id":"737b85326f2a2ef1faaa9858d4731c5cacb73395"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"fe337410415f7ab51783ce1b7ec64f96fa386cd2","unresolved":false,"context_lines":[{"line_number":621,"context_line":"        versions_obj \u003d self._build_versions_object_name("},{"line_number":622,"context_line":"            object_name, version)"},{"line_number":623,"context_line":""},{"line_number":624,"context_line":"        if (head_is_tombstone or not symlink_target or ("},{"line_number":625,"context_line":"            symlink_target and wsgi_unquote(symlink_target) !\u003d wsgi_unquote("},{"line_number":626,"context_line":"                \u0027%s/%s\u0027 % (versions_cont, versions_obj)))):"},{"line_number":627,"context_line":"            # if current version links to another version, then"},{"line_number":628,"context_line":"            # just delete the version issue requested to delete"},{"line_number":629,"context_line":"            req.path_info \u003d \"/%s/%s/%s/%s\" % ("}],"source_content_type":"text/x-python","patch_set":71,"id":"3fa7e38b_dee97e82","line":626,"range":{"start_line":624,"start_character":8,"end_line":626,"end_character":59},"in_reply_to":"3fa7e38b_7782f6a8","updated":"2020-01-15 01:00:00.000000000","message":"Done","commit_id":"737b85326f2a2ef1faaa9858d4731c5cacb73395"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5156649e864434c37822e4c079b3ef4e18ccbb92","unresolved":false,"context_lines":[{"line_number":719,"context_line":"        elif not versions_cont and version !\u003d \u0027null\u0027:"},{"line_number":720,"context_line":"            raise HTTPBadRequest("},{"line_number":721,"context_line":"                \u0027version-aware operations require that the container is \u0027"},{"line_number":722,"context_line":"                \u0027versioned\u0027, request\u003dreq)"},{"line_number":723,"context_line":"        if version !\u003d \u0027null\u0027:"},{"line_number":724,"context_line":"            try:"},{"line_number":725,"context_line":"                Timestamp(version)"}],"source_content_type":"text/x-python","patch_set":71,"id":"3fa7e38b_a2182e1f","line":722,"updated":"2020-01-14 20:05:39.000000000","message":"Should this 404 when the primary container doesn\u0027t exist? See https://review.opendev.org/#/c/701643/1/test/probe/test_object_versioning.py@132","commit_id":"737b85326f2a2ef1faaa9858d4731c5cacb73395"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"fe337410415f7ab51783ce1b7ec64f96fa386cd2","unresolved":false,"context_lines":[{"line_number":719,"context_line":"        elif not versions_cont and version !\u003d \u0027null\u0027:"},{"line_number":720,"context_line":"            raise HTTPBadRequest("},{"line_number":721,"context_line":"                \u0027version-aware operations require that the container is \u0027"},{"line_number":722,"context_line":"                \u0027versioned\u0027, request\u003dreq)"},{"line_number":723,"context_line":"        if version !\u003d \u0027null\u0027:"},{"line_number":724,"context_line":"            try:"},{"line_number":725,"context_line":"                Timestamp(version)"}],"source_content_type":"text/x-python","patch_set":71,"id":"3fa7e38b_be8122c5","line":722,"in_reply_to":"3fa7e38b_a2182e1f","updated":"2020-01-15 01:00:00.000000000","message":"the challenge here is how users would interpret the 404, is it a 404 the object doesn\u0027t exist or 404 the container doesn\u0027t exist. I almost prefer the 400 to indicate there\u0027s something else going? maybe??","commit_id":"737b85326f2a2ef1faaa9858d4731c5cacb73395"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"68a2739b65e4f34d36c68d36640c2385959aef60","unresolved":false,"context_lines":[{"line_number":719,"context_line":"        elif not versions_cont and version !\u003d \u0027null\u0027:"},{"line_number":720,"context_line":"            raise HTTPBadRequest("},{"line_number":721,"context_line":"                \u0027version-aware operations require that the container is \u0027"},{"line_number":722,"context_line":"                \u0027versioned\u0027, request\u003dreq)"},{"line_number":723,"context_line":"        if version !\u003d \u0027null\u0027:"},{"line_number":724,"context_line":"            try:"},{"line_number":725,"context_line":"                Timestamp(version)"}],"source_content_type":"text/x-python","patch_set":71,"id":"3fa7e38b_b907fc17","line":722,"in_reply_to":"3fa7e38b_be8122c5","updated":"2020-01-15 01:06:00.000000000","message":"But then the user *also* can\u0027t discern the 400-does-not-exist case from 400-exists-but-unversioned... Like, either way we lose some information.\n\nIt felt particularly odd around https://review.opendev.org/#/c/701643/2/test/probe/test_object_versioning.py@133 where I just got done checking that all those container operations 404, then try an object operation and it 400s where any \"normal\" object operations would *also 404* :-/\n\nI can live with it, for sure, though.","commit_id":"737b85326f2a2ef1faaa9858d4731c5cacb73395"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5156649e864434c37822e4c079b3ef4e18ccbb92","unresolved":false,"context_lines":[{"line_number":1343,"context_line":"                # those containers to listing so users can be aware and"},{"line_number":1344,"context_line":"                # clean them up"},{"line_number":1345,"context_line":"                for key, item in versions_dict.items():"},{"line_number":1346,"context_line":"                    item[\u0027name\u0027] \u003d key"},{"line_number":1347,"context_line":"                    listing.append(item)"},{"line_number":1348,"context_line":""},{"line_number":1349,"context_line":"                body \u003d build_listing("}],"source_content_type":"text/x-python","patch_set":71,"id":"3fa7e38b_02f9021b","line":1346,"updated":"2020-01-14 20:05:39.000000000","message":"Could we add an extra key here or something?\n\n item[\u0027versions_only\u0027] \u003d True\n\n?\n\n item[\u0027missing_primary_container\u0027] \u003d True\n\n? *Something* that will hopefully indicate to the user that they might want to take some corrective action.","commit_id":"737b85326f2a2ef1faaa9858d4731c5cacb73395"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f14e31c7a9ec68f381265b2058e6b059896053fe","unresolved":false,"context_lines":[{"line_number":1343,"context_line":"                # those containers to listing so users can be aware and"},{"line_number":1344,"context_line":"                # clean them up"},{"line_number":1345,"context_line":"                for key, item in versions_dict.items():"},{"line_number":1346,"context_line":"                    item[\u0027name\u0027] \u003d key"},{"line_number":1347,"context_line":"                    listing.append(item)"},{"line_number":1348,"context_line":""},{"line_number":1349,"context_line":"                body \u003d build_listing("}],"source_content_type":"text/x-python","patch_set":71,"id":"3fa7e38b_de9ade73","line":1346,"in_reply_to":"3fa7e38b_02f9021b","updated":"2020-01-14 23:54:32.000000000","message":"Ah! Here\u0027s the flag to add:\n\n item[\u0027count\u0027] \u003d 0\n\nSince there\u0027s no primary container, there are no *current* versions, so none of them should count in the listing!","commit_id":"737b85326f2a2ef1faaa9858d4731c5cacb73395"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"fe337410415f7ab51783ce1b7ec64f96fa386cd2","unresolved":false,"context_lines":[{"line_number":1343,"context_line":"                # those containers to listing so users can be aware and"},{"line_number":1344,"context_line":"                # clean them up"},{"line_number":1345,"context_line":"                for key, item in versions_dict.items():"},{"line_number":1346,"context_line":"                    item[\u0027name\u0027] \u003d key"},{"line_number":1347,"context_line":"                    listing.append(item)"},{"line_number":1348,"context_line":""},{"line_number":1349,"context_line":"                body \u003d build_listing("}],"source_content_type":"text/x-python","patch_set":71,"id":"3fa7e38b_beb042de","line":1346,"in_reply_to":"3fa7e38b_de9ade73","updated":"2020-01-15 01:00:00.000000000","message":"Done","commit_id":"737b85326f2a2ef1faaa9858d4731c5cacb73395"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"90eee107721d215157fd971684b18d2cf592cc32","unresolved":false,"context_lines":[{"line_number":386,"context_line":"        if is_client_error(resp.status_int):"},{"line_number":387,"context_line":"            # missing container or bad permissions"},{"line_number":388,"context_line":"            if resp.status_int \u003d\u003d 404:"},{"line_number":389,"context_line":"                raise HTTPPreconditionFailed(request\u003dreq)"},{"line_number":390,"context_line":"            raise HTTPException(body\u003dresp.body, status\u003dresp.status,"},{"line_number":391,"context_line":"                                headers\u003dresp.headers)"},{"line_number":392,"context_line":"        # could not version the data, bail"}],"source_content_type":"text/x-python","patch_set":74,"id":"3fa7e38b_61907f43","line":389,"range":{"start_line":389,"start_character":22,"end_line":389,"end_character":44},"updated":"2020-01-22 13:38:57.000000000","message":"Do we have to carry this bad status code around with us forever? There were no If-* headers on this at all!\n\nIn fact, given the current state of the patch, I don\u0027t think it should be a client error at all -- there\u0027s nothing a normal client can do to remedy this situation; an operator needs to go behind the scenes and re-create the container.","commit_id":"1d45385db321803470abb2678a7df55e37a27402"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"97644411b4a69ea97a4a38f5472a1f98d4e3cfb1","unresolved":false,"context_lines":[{"line_number":737,"context_line":"        if version \u003d\u003d \u0027null\u0027:"},{"line_number":738,"context_line":"            resp \u003d req.get_response(self.app)"},{"line_number":739,"context_line":"            if resp.is_success:"},{"line_number":740,"context_line":"                if get_reserved_name(\u0027versions\u0027, \u0027\u0027) in resp.headers.get("},{"line_number":741,"context_line":"                        \u0027Content-Location\u0027, \u0027\u0027):"},{"line_number":742,"context_line":"                    # Have a latest version, but it\u0027s got a real version-id."},{"line_number":743,"context_line":"                    # Since the user specifically asked for null, return 404"},{"line_number":744,"context_line":"                    close_if_possible(resp.app_iter)"}],"source_content_type":"text/x-python","patch_set":74,"id":"3fa7e38b_97a13995","line":741,"range":{"start_line":740,"start_character":16,"end_line":741,"end_character":48},"updated":"2020-01-22 15:39:37.000000000","message":"Isn\u0027t Content-Location quoted? test_versioning_obj_read_not_exist_null in the ceph tests is failing on the S3 patch, having found data when it wasn\u0027t expecting to :-/","commit_id":"1d45385db321803470abb2678a7df55e37a27402"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2c0b3ed584754862e48372e1d0a93f96a41ebc8c","unresolved":false,"context_lines":[{"line_number":737,"context_line":"        if version \u003d\u003d \u0027null\u0027:"},{"line_number":738,"context_line":"            resp \u003d req.get_response(self.app)"},{"line_number":739,"context_line":"            if resp.is_success:"},{"line_number":740,"context_line":"                if get_reserved_name(\u0027versions\u0027, \u0027\u0027) in resp.headers.get("},{"line_number":741,"context_line":"                        \u0027Content-Location\u0027, \u0027\u0027):"},{"line_number":742,"context_line":"                    # Have a latest version, but it\u0027s got a real version-id."},{"line_number":743,"context_line":"                    # Since the user specifically asked for null, return 404"},{"line_number":744,"context_line":"                    close_if_possible(resp.app_iter)"}],"source_content_type":"text/x-python","patch_set":74,"id":"3fa7e38b_a26652ed","line":741,"range":{"start_line":740,"start_character":16,"end_line":741,"end_character":48},"in_reply_to":"3fa7e38b_97a13995","updated":"2020-01-24 18:24:55.000000000","message":"Done","commit_id":"1d45385db321803470abb2678a7df55e37a27402"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2c0b3ed584754862e48372e1d0a93f96a41ebc8c","unresolved":false,"context_lines":[{"line_number":349,"context_line":"        req.ensure_x_timestamp()"},{"line_number":350,"context_line":"        req.headers[\u0027X-Timestamp\u0027] \u003d Timestamp("},{"line_number":351,"context_line":"            req.timestamp, offset\u003d1).internal"},{"line_number":352,"context_line":"        req.headers[TGT_ETAG_SYSMETA_SYMLINK_HDR] \u003d put_etag"},{"line_number":353,"context_line":"        req.headers[TGT_BYTES_SYSMETA_SYMLINK_HDR] \u003d put_bytes"},{"line_number":354,"context_line":"        # N.B. in stack mode DELETE we use content_type from listing"},{"line_number":355,"context_line":"        req.headers[\u0027Content-Type\u0027] \u003d put_content_type"},{"line_number":356,"context_line":"        req.headers[TGT_OBJ_SYMLINK_HDR] \u003d wsgi_quote(\u0027%s/%s\u0027 % ("}],"source_content_type":"text/x-python","patch_set":78,"id":"3fa7e38b_2234a2ab","line":353,"range":{"start_line":352,"start_character":8,"end_line":353,"end_character":62},"updated":"2020-01-24 18:24:55.000000000","message":"Now that we\u0027ve got env[\u0027swift.symlink_override\u0027] for container sync, we could set that here, too, and use the client-facing headers...\n\nMeh. No rush.","commit_id":"92a02a4a4c1defff6d345b739f6963b0fdbdb793"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"198173da97fb80be4739152a75dcc4575b2457d1","unresolved":false,"context_lines":[{"line_number":349,"context_line":"        req.ensure_x_timestamp()"},{"line_number":350,"context_line":"        req.headers[\u0027X-Timestamp\u0027] \u003d Timestamp("},{"line_number":351,"context_line":"            req.timestamp, offset\u003d1).internal"},{"line_number":352,"context_line":"        req.headers[TGT_ETAG_SYSMETA_SYMLINK_HDR] \u003d put_etag"},{"line_number":353,"context_line":"        req.headers[TGT_BYTES_SYSMETA_SYMLINK_HDR] \u003d put_bytes"},{"line_number":354,"context_line":"        # N.B. in stack mode DELETE we use content_type from listing"},{"line_number":355,"context_line":"        req.headers[\u0027Content-Type\u0027] \u003d put_content_type"},{"line_number":356,"context_line":"        req.headers[TGT_OBJ_SYMLINK_HDR] \u003d wsgi_quote(\u0027%s/%s\u0027 % ("}],"source_content_type":"text/x-python","patch_set":78,"id":"3fa7e38b_2bcf9db3","line":353,"range":{"start_line":352,"start_character":8,"end_line":353,"end_character":62},"in_reply_to":"3fa7e38b_2234a2ab","updated":"2020-01-25 01:20:50.000000000","message":"I take it back; if we try to skip validation like that, we write down MD5_OF_EMPTY_STRING and 0 bytes over in test_versioned_staticlink... now to figure out how going straight to sysmeta helps :/","commit_id":"92a02a4a4c1defff6d345b739f6963b0fdbdb793"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2c0b3ed584754862e48372e1d0a93f96a41ebc8c","unresolved":false,"context_lines":[{"line_number":357,"context_line":"            versions_cont, put_vers_obj_name))"},{"line_number":358,"context_line":"        req.headers[SYSMETA_VERSIONS_SYMLINK] \u003d \u0027true\u0027"},{"line_number":359,"context_line":"        req.headers[SYMLOOP_EXTEND] \u003d \u0027true\u0027"},{"line_number":360,"context_line":"        req.headers[ALLOW_RESERVED_NAMES] \u003d \u0027true\u0027"},{"line_number":361,"context_line":"        req.headers[\u0027X-Backend-Allow-Reserved-Names\u0027] \u003d \u0027true\u0027"},{"line_number":362,"context_line":"        not_for_symlink_headers \u003d ("},{"line_number":363,"context_line":"            \u0027ETag\u0027, \u0027X-If-Delete-At\u0027, TGT_ACCT_SYMLINK_HDR,"},{"line_number":364,"context_line":"            \u0027X-Object-Manifest\u0027, \u0027X-Static-Large-Object\u0027,"}],"source_content_type":"text/x-python","patch_set":78,"id":"3fa7e38b_82b31635","line":361,"range":{"start_line":360,"start_character":8,"end_line":361,"end_character":62},"updated":"2020-01-24 18:24:55.000000000","message":"Note: This looks redundant, but isn\u0027t :-/","commit_id":"92a02a4a4c1defff6d345b739f6963b0fdbdb793"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e40b2d46bc37083e4e4957297f8e8b40fc170358","unresolved":true,"context_lines":[{"line_number":353,"context_line":"                                put_etag, put_bytes, put_content_type):"},{"line_number":354,"context_line":""},{"line_number":355,"context_line":"        req.method \u003d \u0027PUT\u0027"},{"line_number":356,"context_line":"        # inch x-timestamp forward, just in case"},{"line_number":357,"context_line":"        req.ensure_x_timestamp()"},{"line_number":358,"context_line":"        req.headers[\u0027X-Timestamp\u0027] \u003d Timestamp("},{"line_number":359,"context_line":"            req.timestamp, offset\u003d1).internal"}],"source_content_type":"text/x-python","patch_set":80,"id":"c0f19092_24e4caa3","line":356,"updated":"2026-02-09 17:58:02.000000000","message":"does anyone remember why?","commit_id":"2759d5d51c5e3c684081e066f9efeb495c141524"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"c52c3cf5cb9b2fac1b5b9b95d0b82559fa26f850","unresolved":false,"context_lines":[{"line_number":702,"context_line":"            else:"},{"line_number":703,"context_line":"                raise HTTPInternalServerError("},{"line_number":704,"context_line":"                    request\u003dreq, content_type\u003d\u0027text/plain\u0027,"},{"line_number":705,"context_line":"                    body\u003db\u0027The versions container does not exist. You may \u0027"},{"line_number":706,"context_line":"                         b\u0027want to re-enable object versioning.\u0027)"},{"line_number":707,"context_line":""},{"line_number":708,"context_line":"        self._check_response_error(req, head_resp)"}],"source_content_type":"text/x-python","patch_set":80,"id":"3fa7e38b_3cbb5e75","line":705,"range":{"start_line":705,"start_character":27,"end_line":705,"end_character":64},"updated":"2020-01-27 08:09:37.000000000","message":"I think this sentence might be confusing to users, ideally they wouldn\u0027t even know about the existence of a \u0027versions\u0027 container. It might raise more questions than answers as even after re-enabling versioning they would still not see a \u0027versions\u0027 container.\n\nHow about: \u0027Error writing versioned object. You may want to re-enable object versioning.\u0027 ?","commit_id":"2759d5d51c5e3c684081e066f9efeb495c141524"}],"swift/proxy/controllers/base.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"15aba94d6a6789f5c16cf1eb988001215a0d8215","unresolved":false,"context_lines":[{"line_number":358,"context_line":"            (swift_source or \u0027GET_CONTAINER_INFO\u0027))"},{"line_number":359,"context_line":"        # XXX: where is the better place to do this right?"},{"line_number":360,"context_line":"        if config_true_value(env.get(\u0027HTTP_X_BACKEND_ALLOW_RESERVED_NAMES\u0027)):"},{"line_number":361,"context_line":"            req.headers[\u0027X-Backend-Allow-Reserved-Names\u0027] \u003d \u0027true\u0027"},{"line_number":362,"context_line":"        resp \u003d req.get_response(app)"},{"line_number":363,"context_line":"        close_if_possible(resp.app_iter)"},{"line_number":364,"context_line":"        # Check in infocache to see if the proxy (or anyone else) already"}],"source_content_type":"text/x-python","patch_set":20,"id":"3fa7e38b_f6ee9a89","line":361,"updated":"2019-10-24 20:36:58.000000000","message":"So this was an annoying find","commit_id":"4680ee8a591513ad176b4915566dfae3ed66b3bc"}],"test/functional/test_object_versioning.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"41d5b31c27b1c37c7d4ec12c1587cd56d63d165a","unresolved":false,"context_lines":[{"line_number":120,"context_line":"            cls.account2.delete_containers()"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"class TestCrossPolicyObjectVersioningEnv(BaseEnv):"},{"line_number":124,"context_line":"    # tri-state: None initially, then True/False"},{"line_number":125,"context_line":"    versioning_enabled \u003d None"},{"line_number":126,"context_line":"    multiple_policies_enabled \u003d None"}],"source_content_type":"text/x-python","patch_set":8,"id":"3fa7e38b_8a0b417b","line":123,"range":{"start_line":123,"start_character":10,"end_line":123,"end_character":21},"updated":"2019-09-25 20:56:31.000000000","message":"Do we have any control over the archive container\u0027s storage policy yet?","commit_id":"21294d0e267677926715271f7a803fb63ce3139f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":120,"context_line":"            cls.account2.delete_containers()"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"class TestCrossPolicyObjectVersioningEnv(BaseEnv):"},{"line_number":124,"context_line":"    # tri-state: None initially, then True/False"},{"line_number":125,"context_line":"    versioning_enabled \u003d None"},{"line_number":126,"context_line":"    multiple_policies_enabled \u003d None"}],"source_content_type":"text/x-python","patch_set":8,"id":"3fa7e38b_6c0eb63e","line":123,"range":{"start_line":123,"start_character":10,"end_line":123,"end_character":21},"in_reply_to":"3fa7e38b_8a0b417b","updated":"2019-12-17 01:30:58.000000000","message":"Removed in PS 25.","commit_id":"21294d0e267677926715271f7a803fb63ce3139f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":140,"context_line":"        # make sure versioning is enabled,"},{"line_number":141,"context_line":"        # since it gets disabled in tearDown"},{"line_number":142,"context_line":"        self.env.container.update_metadata("},{"line_number":143,"context_line":"            hdrs\u003d{self.env.versions_header_key: \u0027True\u0027})"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"    def _tear_down_files(self, container):"},{"line_number":146,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":52,"id":"3fa7e38b_cc048ac8","line":143,"updated":"2019-12-17 01:30:58.000000000","message":"Can repro the 404 here as part of test.functional.test_object_versioning.TestSloWithVersioning ... looks like we want a PUT instead of POST? Or... something.","commit_id":"8c5555ddb9d2583d26a13befd0ea0adea3edca2c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4df3a1920ba46bd67cd4692ac9ddbbd9c4f9b32e","unresolved":false,"context_lines":[{"line_number":140,"context_line":"        # make sure versioning is enabled,"},{"line_number":141,"context_line":"        # since it gets disabled in tearDown"},{"line_number":142,"context_line":"        self.env.container.update_metadata("},{"line_number":143,"context_line":"            hdrs\u003d{self.env.versions_header_key: \u0027True\u0027})"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"    def _tear_down_files(self, container):"},{"line_number":146,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":52,"id":"3fa7e38b_063bb39a","line":143,"in_reply_to":"3fa7e38b_cc048ac8","updated":"2020-01-08 22:41:42.000000000","message":"Func tests were happy again in PS 53.","commit_id":"8c5555ddb9d2583d26a13befd0ea0adea3edca2c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":2120,"context_line":"        super(TestVersionsLocationWithVersioning, self).setUp()"},{"line_number":2121,"context_line":""},{"line_number":2122,"context_line":"        if six.PY2:"},{"line_number":2123,"context_line":"            # avoid getting a prefix that stops halfway through an encoded"},{"line_number":2124,"context_line":"            # character"},{"line_number":2125,"context_line":"            prefix \u003d Utils.create_name().decode(\"utf-8\")[:10].encode(\"utf-8\")"},{"line_number":2126,"context_line":"        else:"},{"line_number":2127,"context_line":"            prefix \u003d Utils.create_name()[:10]"}],"source_content_type":"text/x-python","patch_set":52,"id":"3fa7e38b_8ce9b280","line":2124,"range":{"start_line":2123,"start_character":12,"end_line":2124,"end_character":23},"updated":"2019-12-17 01:30:58.000000000","message":"Does this mean we should have UTF8 variations of these, too? I don\u0027t know that they\u0027re really increase our coverage much, honestly.","commit_id":"8c5555ddb9d2583d26a13befd0ea0adea3edca2c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"97644411b4a69ea97a4a38f5472a1f98d4e3cfb1","unresolved":false,"context_lines":[{"line_number":433,"context_line":"        # 10 plus delete marker"},{"line_number":434,"context_line":"        self.assertTotalVersions(self.env.container, 11)"},{"line_number":435,"context_line":""},{"line_number":436,"context_line":"        return (versioned_obj, expected_content_types)"},{"line_number":437,"context_line":""},{"line_number":438,"context_line":"    def test_overwriting(self):"},{"line_number":439,"context_line":"        versioned_obj, expected_content_types \u003d \\"}],"source_content_type":"text/x-python","patch_set":74,"id":"3fa7e38b_97f7f9d1","line":436,"updated":"2020-01-22 15:39:37.000000000","message":"I don\u0027t think this actually needs to return anything. Also, this seems better named as just \"_test_overwriting\" rather than \"_test_overwriting_setup\".","commit_id":"1d45385db321803470abb2678a7df55e37a27402"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2c0b3ed584754862e48372e1d0a93f96a41ebc8c","unresolved":false,"context_lines":[{"line_number":2313,"context_line":"        }"},{"line_number":2314,"context_line":"        self.assertEqual([expected], obj_list)"},{"line_number":2315,"context_line":""},{"line_number":2316,"context_line":"        status \u003d file_item.conn.make_request("},{"line_number":2317,"context_line":"            \u0027DELETE\u0027, file_item.path,"},{"line_number":2318,"context_line":"            hdrs\u003d{\u0027Accept\u0027: \u0027application/json\u0027},"},{"line_number":2319,"context_line":"            parms\u003d{\u0027multipart-manifest\u0027: \u0027delete\u0027,"},{"line_number":2320,"context_line":"                   \u0027version-id\u0027: v1_version_id})"},{"line_number":2321,"context_line":"        body \u003d file_item.conn.response.read()"},{"line_number":2322,"context_line":"        self.assertEqual(status, 200, body)"},{"line_number":2323,"context_line":"        resp \u003d json.loads(body)"},{"line_number":2324,"context_line":"        self.assertEqual(resp[\u0027Response Status\u0027], \u0027200 OK\u0027)"},{"line_number":2325,"context_line":"        self.assertEqual(resp[\u0027Errors\u0027], [])"},{"line_number":2326,"context_line":"        self.assertEqual(resp[\u0027Number Deleted\u0027], 2)"},{"line_number":2327,"context_line":""},{"line_number":2328,"context_line":"        self.assertTotalVersions(self.container, 3)"},{"line_number":2329,"context_line":"        # Since we included the ?multipart-manifest\u003ddelete, segments"},{"line_number":2330,"context_line":"        # got cleaned up and now the current version is busted"},{"line_number":2331,"context_line":"        with self.assertRaises(ResponseError) as caught:"},{"line_number":2332,"context_line":"            file_item.read()"},{"line_number":2333,"context_line":"        self.assertEqual(409, caught.exception.status)"},{"line_number":2334,"context_line":""},{"line_number":2335,"context_line":"    def test_links_to_slo(self):"},{"line_number":2336,"context_line":"        file_item, v1_version_id \u003d self._create_manifest(\u0027a\u0027)"}],"source_content_type":"text/x-python","patch_set":78,"id":"3fa7e38b_82855655","line":2333,"range":{"start_line":2316,"start_character":8,"end_line":2333,"end_character":54},"updated":"2020-01-24 18:24:55.000000000","message":"Calling out this test addition that required the extra plumbing through slo and bulk.","commit_id":"92a02a4a4c1defff6d345b739f6963b0fdbdb793"}],"test/probe/test_object_versioning.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e60c20e3481131434cdab8c5baa702022a1f7f1d","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        self.assertEqual(len(all_versions), 3)"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"        # directly delete primary container to leave an orphan hidden"},{"line_number":101,"context_line":"        # container"},{"line_number":102,"context_line":"        self.direct_delete_container(container\u003dcontainer_name)"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"        # Get to final state"}],"source_content_type":"text/x-python","patch_set":74,"id":"3fa7e38b_7f5fda0f","line":101,"updated":"2020-01-20 18:40:31.000000000","message":"I think it\u0027s worth investigating the converse of this: What happens when a versions container goes missing? Maybe it\u0027s just temporarily unavailable, maybe it got deleted.\n\nIf it\u0027s not a transient error, I think it\u0027s going to require operator intervention to fix it... I tried disabling and re-enabling versioning; there was no new PUT :-/","commit_id":"1d45385db321803470abb2678a7df55e37a27402"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"4f4c4781b9fece1bc961a2266df62ca010ed8a63","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        self.assertEqual(len(all_versions), 3)"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"        # directly delete primary container to leave an orphan hidden"},{"line_number":101,"context_line":"        # container"},{"line_number":102,"context_line":"        self.direct_delete_container(container\u003dcontainer_name)"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"        # Get to final state"}],"source_content_type":"text/x-python","patch_set":74,"id":"3fa7e38b_e247b151","line":101,"in_reply_to":"3fa7e38b_7f5fda0f","updated":"2020-01-20 19:48:26.000000000","message":"Yeah, currently disable/enable won\u0027t fix it, maybe adding a check to see if container exists during enable? or going back to the idea of removing `SYSMETA_VERSIONS_CONT` all together would help?","commit_id":"1d45385db321803470abb2678a7df55e37a27402"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6227e3cc4b1722e5f4eecbeec530fe41cb7031f8","unresolved":false,"context_lines":[{"line_number":211,"context_line":"        client.delete_object(self.url, self.token, container_name, obj_name,"},{"line_number":212,"context_line":"                             query_string\u003d\u0027version-id\u003dnull\u0027)"},{"line_number":213,"context_line":""},{"line_number":214,"context_line":"        # Re-enabling versioning should square us"},{"line_number":215,"context_line":"        hdrs \u003d {versions_header_key: \u0027True\u0027}"},{"line_number":216,"context_line":"        client.post_container(self.url, self.token, container_name, hdrs)"},{"line_number":217,"context_line":""}],"source_content_type":"text/x-python","patch_set":77,"id":"3fa7e38b_5f1ad7c6","line":214,"updated":"2020-01-24 17:37:07.000000000","message":"awesome!","commit_id":"96e8a5107610cb74fa666e66ecd04dea5f94c028"}],"test/unit/common/middleware/test_object_versioning.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"cc7acf485eb94063c21bc65485c5d42157958d77","unresolved":false,"context_lines":[{"line_number":119,"context_line":"        return status[0], headers[0], body"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    def call_ov(self, req):"},{"line_number":122,"context_line":"        return self.call_app(req, app\u003dself.ov)"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    def assertRequestEqual(self, req, other):"},{"line_number":125,"context_line":"        self.assertEqual(req.method, other.method)"}],"source_content_type":"text/x-python","patch_set":40,"id":"3fa7e38b_6035b9f5","line":122,"updated":"2019-11-21 00:20:44.000000000","message":"This is the only caller of call_app, yeah? Should we just consolidate these functions?","commit_id":"212a6cb43be190a990ac2c4e44ccfd925201b588"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":119,"context_line":"        return status[0], headers[0], body"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    def call_ov(self, req):"},{"line_number":122,"context_line":"        return self.call_app(req, app\u003dself.ov)"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    def assertRequestEqual(self, req, other):"},{"line_number":125,"context_line":"        self.assertEqual(req.method, other.method)"}],"source_content_type":"text/x-python","patch_set":40,"id":"3fa7e38b_67c6cf9f","line":122,"in_reply_to":"3fa7e38b_6035b9f5","updated":"2019-12-17 01:30:58.000000000","message":"Addressed in PS 41.","commit_id":"212a6cb43be190a990ac2c4e44ccfd925201b588"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"cc7acf485eb94063c21bc65485c5d42157958d77","unresolved":false,"context_lines":[{"line_number":1349,"context_line":"class ObjectVersioningTestCopy(ObjectVersioningBaseTestCase):"},{"line_number":1350,"context_line":"    def setUp(self):"},{"line_number":1351,"context_line":"        super(ObjectVersioningTestCopy, self).setUp()"},{"line_number":1352,"context_line":"        self.ov \u003d copy.filter_factory({})(self.ov)"},{"line_number":1353,"context_line":""},{"line_number":1354,"context_line":"    @mock.patch(\u0027swift.common.middleware.versioned_writes.object_versioning.\u0027"},{"line_number":1355,"context_line":"                \u0027time.time\u0027, return_value\u003d1234)"}],"source_content_type":"text/x-python","patch_set":40,"id":"3fa7e38b_fbaf1add","line":1352,"updated":"2019-11-21 00:20:44.000000000","message":"Is there really much downside to doing this all the time?","commit_id":"212a6cb43be190a990ac2c4e44ccfd925201b588"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":1349,"context_line":"class ObjectVersioningTestCopy(ObjectVersioningBaseTestCase):"},{"line_number":1350,"context_line":"    def setUp(self):"},{"line_number":1351,"context_line":"        super(ObjectVersioningTestCopy, self).setUp()"},{"line_number":1352,"context_line":"        self.ov \u003d copy.filter_factory({})(self.ov)"},{"line_number":1353,"context_line":""},{"line_number":1354,"context_line":"    @mock.patch(\u0027swift.common.middleware.versioned_writes.object_versioning.\u0027"},{"line_number":1355,"context_line":"                \u0027time.time\u0027, return_value\u003d1234)"}],"source_content_type":"text/x-python","patch_set":40,"id":"3fa7e38b_87cbcba2","line":1352,"in_reply_to":"3fa7e38b_fbaf1add","updated":"2019-12-17 01:30:58.000000000","message":"Addressed in PS 41.","commit_id":"212a6cb43be190a990ac2c4e44ccfd925201b588"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"adaad0dd0b7533a8cc204f919a0a0fcac6ae5d01","unresolved":false,"context_lines":[{"line_number":1809,"context_line":"            environ\u003d{\u0027swift.cache\u0027: self.cache_version_on},"},{"line_number":1810,"context_line":"            params\u003d{\u0027version-id\u0027: timestamp.normal})"},{"line_number":1811,"context_line":"        status, headers, body \u003d self.call_ov(req)"},{"line_number":1812,"context_line":"        self.assertEqual(status, \u0027412 Precondition Failed\u0027)"},{"line_number":1813,"context_line":""},{"line_number":1814,"context_line":"    def test_PUT_version_invalid(self):"},{"line_number":1815,"context_line":"        invalid_versions \u003d (\u0027null\u0027, \u0027something\u0027, \u0027-10\u0027)"}],"source_content_type":"text/x-python","patch_set":74,"id":"3fa7e38b_2d8111a1","line":1812,"updated":"2020-01-23 02:45:46.000000000","message":"This seems a little funny -- I feel like a 404 would be more obvious :-/","commit_id":"1d45385db321803470abb2678a7df55e37a27402"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6afe341a0d4a4dc5054af39c5ee637c37afed5a9","unresolved":false,"context_lines":[{"line_number":1809,"context_line":"            environ\u003d{\u0027swift.cache\u0027: self.cache_version_on},"},{"line_number":1810,"context_line":"            params\u003d{\u0027version-id\u0027: timestamp.normal})"},{"line_number":1811,"context_line":"        status, headers, body \u003d self.call_ov(req)"},{"line_number":1812,"context_line":"        self.assertEqual(status, \u0027412 Precondition Failed\u0027)"},{"line_number":1813,"context_line":""},{"line_number":1814,"context_line":"    def test_PUT_version_invalid(self):"},{"line_number":1815,"context_line":"        invalid_versions \u003d (\u0027null\u0027, \u0027something\u0027, \u0027-10\u0027)"}],"source_content_type":"text/x-python","patch_set":74,"id":"3fa7e38b_a2abb2d4","line":1812,"in_reply_to":"3fa7e38b_2d8111a1","updated":"2020-01-24 18:12:53.000000000","message":"Tim convinced me 412 is not the best we can do here, let\u0027s respin","commit_id":"1d45385db321803470abb2678a7df55e37a27402"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"198173da97fb80be4739152a75dcc4575b2457d1","unresolved":false,"context_lines":[{"line_number":1809,"context_line":"            environ\u003d{\u0027swift.cache\u0027: self.cache_version_on},"},{"line_number":1810,"context_line":"            params\u003d{\u0027version-id\u0027: timestamp.normal})"},{"line_number":1811,"context_line":"        status, headers, body \u003d self.call_ov(req)"},{"line_number":1812,"context_line":"        self.assertEqual(status, \u0027412 Precondition Failed\u0027)"},{"line_number":1813,"context_line":""},{"line_number":1814,"context_line":"    def test_PUT_version_invalid(self):"},{"line_number":1815,"context_line":"        invalid_versions \u003d (\u0027null\u0027, \u0027something\u0027, \u0027-10\u0027)"}],"source_content_type":"text/x-python","patch_set":74,"id":"3fa7e38b_cbf049dd","line":1812,"in_reply_to":"3fa7e38b_a2abb2d4","updated":"2020-01-25 01:20:50.000000000","message":"Done","commit_id":"1d45385db321803470abb2678a7df55e37a27402"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"198173da97fb80be4739152a75dcc4575b2457d1","unresolved":false,"context_lines":[{"line_number":1835,"context_line":"            params\u003d{\u0027version-id\u0027: timestamp.normal})"},{"line_number":1836,"context_line":"        status, headers, body \u003d self.call_ov(req)"},{"line_number":1837,"context_line":"        self.assertEqual(status, \u0027404 Not Found\u0027)"},{"line_number":1838,"context_line":"        self.assertIn(b\u0027version does not exist\u0027, body)"},{"line_number":1839,"context_line":""},{"line_number":1840,"context_line":"    def test_PUT_version_container_not_found(self):"},{"line_number":1841,"context_line":"        timestamp \u003d next(self.ts)"}],"source_content_type":"text/x-python","patch_set":79,"id":"3fa7e38b_0b0bc1d3","line":1838,"updated":"2020-01-25 01:20:50.000000000","message":"I think I like these errors more.","commit_id":"393fb11229784ea17efbb00729d7fb634ce8f8af"}],"test/unit/common/middleware/test_slo.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2c0b3ed584754862e48372e1d0a93f96a41ebc8c","unresolved":false,"context_lines":[{"line_number":1311,"context_line":"            set([(\u0027GET\u0027,"},{"line_number":1312,"context_line":"                  \u0027/v1/AUTH_test/deltest/man?multipart-manifest\u003dget\u0027),"},{"line_number":1313,"context_line":"                 (\u0027DELETE\u0027,"},{"line_number":1314,"context_line":"                  \u0027/v1/AUTH_test/deltest/gone?multipart-manifest\u003ddelete\u0027),"},{"line_number":1315,"context_line":"                 (\u0027DELETE\u0027,"},{"line_number":1316,"context_line":"                  \u0027/v1/AUTH_test/deltest/b_2?multipart-manifest\u003ddelete\u0027),"},{"line_number":1317,"context_line":"                 (\u0027DELETE\u0027,"}],"source_content_type":"text/x-python","patch_set":78,"id":"3fa7e38b_e24f6a66","side":"PARENT","line":1314,"range":{"start_line":1314,"start_character":46,"end_line":1314,"end_character":71},"updated":"2020-01-24 18:24:55.000000000","message":"Do we care that this has gone missing? I don\u0027t know that *I* do...","commit_id":"1d5d8ce720b4796b6a247a0762b89f3b5a5b6efb"}],"test/unit/common/test_wsgi.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f80d1fd38f5e2bb278fd922fcb53d8f37c856dac","unresolved":false,"context_lines":[{"line_number":1815,"context_line":"        for _ in range(1000):"},{"line_number":1816,"context_line":"            # TODO fix this:"},{"line_number":1817,"context_line":"            # This seems like a horrible hack to account for the fact"},{"line_number":1818,"context_line":"            # versioning has two diferent Middlewares classes"},{"line_number":1819,"context_line":"            if app.__class__.__module__ in version_cls:"},{"line_number":1820,"context_line":"                if \u0027swift.common.middleware.versioned_writes\u0027 not in pipe:"},{"line_number":1821,"context_line":"                    pipe.append(\u0027swift.common.middleware.versioned_writes\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_f366a129","line":1818,"updated":"2019-09-23 19:00:36.000000000","message":"FWIW, I think making ObjectVersioningMiddleware insertion conditional on an off-by-default config option should reduce the delta here a good bit.","commit_id":"1b4c596a5845618a86c3c12b5564f8aef0559a7f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"01f7c59a6a67b1cb1730876afeb130d31daef268","unresolved":false,"context_lines":[{"line_number":1815,"context_line":"        for _ in range(1000):"},{"line_number":1816,"context_line":"            # TODO fix this:"},{"line_number":1817,"context_line":"            # This seems like a horrible hack to account for the fact"},{"line_number":1818,"context_line":"            # versioning has two diferent Middlewares classes"},{"line_number":1819,"context_line":"            if app.__class__.__module__ in version_cls:"},{"line_number":1820,"context_line":"                if \u0027swift.common.middleware.versioned_writes\u0027 not in pipe:"},{"line_number":1821,"context_line":"                    pipe.append(\u0027swift.common.middleware.versioned_writes\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_2c451e17","line":1818,"in_reply_to":"3fa7e38b_f366a129","updated":"2019-12-17 01:30:58.000000000","message":"Addressed in PS5","commit_id":"1b4c596a5845618a86c3c12b5564f8aef0559a7f"}]}
