)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"5cc104b7a4713f440ae3103395a21c8b19d9a06a","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":" * push-marker"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    If a current version exists in the versioned container, it is copied"},{"line_number":26,"context_line":"    to the versions container. Then an empty \"delete marker\" object is"},{"line_number":27,"context_line":"    put into the versioned container. Subsequent GETs or HEADs will"},{"line_number":28,"context_line":"    return a 404. Subsequent DELETEs will either restore the previous"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"fa1b9901_7a1b00cb","line":25,"updated":"2015-08-24 20:10:46.000000000","message":"what does a container list show in this case? I was wondering if it would make more sense to have a marker in the versions container??? That way the \u0027source\u0027 container stays clean and the versions container has a marker that the file was deleted at some point in the past...","commit_id":"2d916fb15821d8cad5a07d2c2ff74b50440fb007"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"76756356f2c3e66b8cefac7e0274ad39217e010a","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":" * push-marker"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    If a current version exists in the versioned container, it is copied"},{"line_number":26,"context_line":"    to the versions container. Then an empty \"delete marker\" object is"},{"line_number":27,"context_line":"    put into the versioned container. Subsequent GETs or HEADs will"},{"line_number":28,"context_line":"    return a 404. Subsequent DELETEs will either restore the previous"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"fa1b9901_847c6e73","line":25,"in_reply_to":"fa1b9901_7a1b00cb","updated":"2015-08-25 01:41:39.000000000","message":"The container listing will include the deleted object. If the client will accept XML or JSON, it will at least have a Content-Type of application/x-delete-marker as an indication that it isn\u0027t really there. Not definitive, but it\u0027s something.\n\n(FWIW, if/when symlinks get implemented, we\u0027ll have the same issue of having objects that appear in container listings but 404 on GET or HEAD.)\n\nI understand the desire to only record the marker in the versions container, but doing so would introduce considerable complexity and even more race conditions than versioning already has.\n\nThe push-marker path wouldn\u0027t be too bad: create a COPY request, create a PUT request, then let the user\u0027s DELETE go through. It\u0027s one more request than we currently do, but nothing terrible.\n\nThe pop-version path would be horrendous, though:\n\n if object_exists_in_versioned_container:\n     if previous_version_is_delete_marker:\n         delete_current_version\n     else:\n         copy_previous_version\n         delete_previous_version\n else:\n     if previous_version_is_delete_marker:\n         delete_previous_version\n         if not previous_previous_version_is_delete_marker:\n             copy_previous_previous_version\n             delete_previous_previous_version\n     else:\n         # Inconsistent state. I guess this is the most sane\n         # thing to do? It\u0027s what we currently do, anyway.\n         copy_previous_version\n         delete_previous_version\n\nAnd that\u0027s leaving aside the need to walk versions until we find one that doesn\u0027t 404. Every condition is an extra HEAD (If-Match/If-None-Match aren\u0027t useful in a COPY), and by the time we\u0027re acting on a condition, we have no guarantee that it\u0027s still true.","commit_id":"2d916fb15821d8cad5a07d2c2ff74b50440fb007"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"5cc104b7a4713f440ae3103395a21c8b19d9a06a","unresolved":false,"context_lines":[{"line_number":26,"context_line":"    to the versions container. Then an empty \"delete marker\" object is"},{"line_number":27,"context_line":"    put into the versioned container. Subsequent GETs or HEADs will"},{"line_number":28,"context_line":"    return a 404. Subsequent DELETEs will either restore the previous"},{"line_number":29,"context_line":"    version or copy the delete marker to the versions container,"},{"line_number":30,"context_line":"    depending upon delete mode."},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"Example:"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"fa1b9901_3a07c882","line":29,"updated":"2015-08-24 20:10:46.000000000","message":"this idea of subsequent DELETEs seems a bit strange. If it restores the previous versions, then it became a \u0027pop-version\u0027 option. If it keeps copying the delete marker to the versions container, what\u0027s the benefit?","commit_id":"2d916fb15821d8cad5a07d2c2ff74b50440fb007"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"76756356f2c3e66b8cefac7e0274ad39217e010a","unresolved":false,"context_lines":[{"line_number":26,"context_line":"    to the versions container. Then an empty \"delete marker\" object is"},{"line_number":27,"context_line":"    put into the versioned container. Subsequent GETs or HEADs will"},{"line_number":28,"context_line":"    return a 404. Subsequent DELETEs will either restore the previous"},{"line_number":29,"context_line":"    version or copy the delete marker to the versions container,"},{"line_number":30,"context_line":"    depending upon delete mode."},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"Example:"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"fa1b9901_01829094","line":29,"in_reply_to":"fa1b9901_3a07c882","updated":"2015-08-25 01:41:39.000000000","message":"Yes, to restore the previous version, the user should send a DELETE with a pop-version mode.\n\nThe ability to push an extra delete marker is for consistency of behavior as much as anything. A delete marker is just another version, and a push-marker DELETE always gets translated to COPY-then-PUT.","commit_id":"2d916fb15821d8cad5a07d2c2ff74b50440fb007"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"39d81a2dacc3d73e420de3a47fd81959b09af4c5","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    If the most-recent version in the versions container is a delete"},{"line_number":37,"context_line":"    marker and a current version exists in the versioned container, the"},{"line_number":38,"context_line":"    current version is deleted. If the most-recent version in the"},{"line_number":39,"context_line":"    versions container is a delete marker and no current version exists"},{"line_number":40,"context_line":"    in the versioned container, we copy the next-most-recent version"},{"line_number":41,"context_line":"    from the versions container into the versioned container (assuming"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"9a1a9d01_a582b792","line":38,"updated":"2015-09-28 20:05:02.000000000","message":"There are a few use cases here, so it gets a bit hard to follow. For this case:\n\"If the most-recent version in the versions container is a delete marker and a current version exists in the versioned container, the current version is deleted.\"\n\nis anything ever copied back to the versioned container? (i.e., the next-most-recent version) or the versions container stays without any previous copy of the object?","commit_id":"bfb7bcd7e92620ed563f58b9f47801cbe1bc7fb5"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7d3609d0f0d88cdd70d9c7a828ace277420316b2","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    If the most-recent version in the versions container is a delete"},{"line_number":37,"context_line":"    marker and a current version exists in the versioned container, the"},{"line_number":38,"context_line":"    current version is deleted. If the most-recent version in the"},{"line_number":39,"context_line":"    versions container is a delete marker and no current version exists"},{"line_number":40,"context_line":"    in the versioned container, we copy the next-most-recent version"},{"line_number":41,"context_line":"    from the versions container into the versioned container (assuming"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"9a1a9d01_f0dce674","line":38,"in_reply_to":"9a1a9d01_a582b792","updated":"2015-09-28 22:55:56.000000000","message":"\u003e There are a few use cases here, so it gets a bit hard to follow.\n\nThat was one of the things I liked about the old way, with the marker in the versioned container: it was much more straightforward :P\n\nNo, nothing will be copied in that case. The current version is deleted, and nothing is done with any objects in the versions container. It should restore the container to the just-pushed-a-delete-marker state.","commit_id":"bfb7bcd7e92620ed563f58b9f47801cbe1bc7fb5"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"37e5513fc29aaf4d902ce1e592e0c8455e81b891","unresolved":false,"context_lines":[{"line_number":18,"context_line":"    current version if one exists) and then deleted from the versions"},{"line_number":19,"context_line":"    container. This preserves the previous behavior."},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"    If the most-recent version in the versions container is a delete"},{"line_number":22,"context_line":"    marker and a current version exists in the versioned container, the"},{"line_number":23,"context_line":"    current version is deleted. If the most-recent version in the"},{"line_number":24,"context_line":"    versions container is a delete marker and no current version exists"},{"line_number":25,"context_line":"    in the versioned container, we copy the next-most-recent version"},{"line_number":26,"context_line":"    from the versions container into the versioned container (assuming"},{"line_number":27,"context_line":"    it exists and is not a delete marker) and delete both the"},{"line_number":28,"context_line":"    most-recent version (i.e., the delete marker) and the just-copied"},{"line_number":29,"context_line":"    next-most-recent version from the versions container."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":14,"id":"bab6814e_5f879eb4","line":26,"range":{"start_line":21,"start_character":4,"end_line":26,"end_character":60},"updated":"2016-05-26 20:13:47.000000000","message":"If I understood this correctly, for this special use case, a user would need to send 2 DELETE requests to pop off the stack?\n1st DELETE would just DELETE the current version.\n2nd DELETE would copy the next-most-recent version and delete the marker.\nWhy not do the whole thing in one request?","commit_id":"9d491859283093a3cc31f5711c53e5f3b5169b91"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"aec645c79f3860784bf9b37fbcbde2df703e0887","unresolved":false,"context_lines":[{"line_number":18,"context_line":"    current version if one exists) and then deleted from the versions"},{"line_number":19,"context_line":"    container. This preserves the previous behavior."},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"    If the most-recent version in the versions container is a delete"},{"line_number":22,"context_line":"    marker and a current version exists in the versioned container, the"},{"line_number":23,"context_line":"    current version is deleted. If the most-recent version in the"},{"line_number":24,"context_line":"    versions container is a delete marker and no current version exists"},{"line_number":25,"context_line":"    in the versioned container, we copy the next-most-recent version"},{"line_number":26,"context_line":"    from the versions container into the versioned container (assuming"},{"line_number":27,"context_line":"    it exists and is not a delete marker) and delete both the"},{"line_number":28,"context_line":"    most-recent version (i.e., the delete marker) and the just-copied"},{"line_number":29,"context_line":"    next-most-recent version from the versions container."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":14,"id":"1aa78d24_924b68b0","line":26,"range":{"start_line":21,"start_character":4,"end_line":26,"end_character":60},"in_reply_to":"9abb7d3a_f9cbd9a1","updated":"2016-07-06 18:25:56.000000000","message":"This doesn\u0027t seem intuitive to me. why should the user need to send a second DELETE when there\u0027s nothing to delete. the versioned container does not have any object anymore and the user is sending a DELETE request, which is really just a pop cmd. Plus, if the user is in stack mode, they basically don\u0027t care about delete markers\n\nI was thinking something more in the lines of:\n\nA Delete to the stack\n  * obj.t3 \u003c-- in versioned container, has real data\n  * obj.t2 \u003c-- in versions container, is delete marker\n  * obj.t1 \u003c-- in versions container, has real data\nwould get us to\n  * obj.t1 \u003c-- now in the versioned container.\n\njust my 2c","commit_id":"9d491859283093a3cc31f5711c53e5f3b5169b91"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4f82980d7828d82f7edb453c89cd9a6cde460d2d","unresolved":false,"context_lines":[{"line_number":18,"context_line":"    current version if one exists) and then deleted from the versions"},{"line_number":19,"context_line":"    container. This preserves the previous behavior."},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"    If the most-recent version in the versions container is a delete"},{"line_number":22,"context_line":"    marker and a current version exists in the versioned container, the"},{"line_number":23,"context_line":"    current version is deleted. If the most-recent version in the"},{"line_number":24,"context_line":"    versions container is a delete marker and no current version exists"},{"line_number":25,"context_line":"    in the versioned container, we copy the next-most-recent version"},{"line_number":26,"context_line":"    from the versions container into the versioned container (assuming"},{"line_number":27,"context_line":"    it exists and is not a delete marker) and delete both the"},{"line_number":28,"context_line":"    most-recent version (i.e., the delete marker) and the just-copied"},{"line_number":29,"context_line":"    next-most-recent version from the versions container."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":14,"id":"9abb7d3a_f9cbd9a1","line":26,"range":{"start_line":21,"start_character":4,"end_line":26,"end_character":60},"in_reply_to":"bab6814e_5f879eb4","updated":"2016-06-08 21:19:45.000000000","message":"In stack mode, each DELETE removes a version from the stack, and this includes delete markers. For example, a DELETE to the stack\n\n- obj.t3 \u003c-- in versioned container, has real data\n- obj.t2 \u003c-- in versions container, is delete marker\n- obj.t1 \u003c-- in versions container, has real data\n\nshould get us to\n\n- obj.t2 \u003c-- still in the versions container!\n- obj.t1\n\nwith nothing in the versioned container. A second DELETE gets us to\n\n- obj.t1 \u003c-- now in the versioned container\n\nwith nothing in the versions container.","commit_id":"9d491859283093a3cc31f5711c53e5f3b5169b91"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"4aa0704ed39b8d62f52568b4722fa1560bc89d41","unresolved":false,"context_lines":[{"line_number":56,"context_line":"cluster have been upgraded. Attempting to use the \"history\" mode during"},{"line_number":57,"context_line":"a rolling upgrade may result in some requests being served by proxies"},{"line_number":58,"context_line":"running old code (which necessarily uses the \"stack\" mode), leading to"},{"line_number":59,"context_line":"data loss."},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"Example session:"},{"line_number":62,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"bacf61ea_98c72c63","line":59,"updated":"2016-08-02 10:13:28.000000000","message":"Is this docs in swift/common/middlewre/versioned_writes.py itself? It seems very important how we can upgrade so that I\u0027d like to make it into auto-generated docs page.","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f3d9903a0825c5294d8e9a960be869b9e9f60b9b","unresolved":false,"context_lines":[{"line_number":56,"context_line":"cluster have been upgraded. Attempting to use the \"history\" mode during"},{"line_number":57,"context_line":"a rolling upgrade may result in some requests being served by proxies"},{"line_number":58,"context_line":"running old code (which necessarily uses the \"stack\" mode), leading to"},{"line_number":59,"context_line":"data loss."},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"Example session:"},{"line_number":62,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"bacf61ea_3803750f","line":59,"in_reply_to":"bacf61ea_98c72c63","updated":"2016-08-04 00:26:58.000000000","message":"Done","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"4aa0704ed39b8d62f52568b4722fa1560bc89d41","unresolved":false,"context_lines":[{"line_number":113,"context_line":"    # (includes versions for \u0027Hello\u0027, \u0027World\u0027, the delete marker, and"},{"line_number":114,"context_line":"    # \u0027Hola\u0027)"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"    # Toggle the mode, and start popping versions"},{"line_number":117,"context_line":"    $ curl -v -H \"X-Auth-Token: $OS_AUTH_TOKEN\" \\"},{"line_number":118,"context_line":"        $OS_STORAGE_URL/test_container -X POST \\"},{"line_number":119,"context_line":"        -H \u0027X-Versions-Mode: stack\u0027"},{"line_number":120,"context_line":"    $ curl -v -H \"X-Auth-Token: $OS_AUTH_TOKEN\" \\"},{"line_number":121,"context_line":"        $OS_STORAGE_URL/test_container/object -X DELETE"},{"line_number":122,"context_line":"    $ curl -v -H \"X-Auth-Token: $OS_AUTH_TOKEN\" \\"},{"line_number":123,"context_line":"        $OS_STORAGE_URL/test_container/object"},{"line_number":124,"context_line":"    # (returns \u0027Hola\u0027)"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"    $ curl -v -H \"X-Auth-Token: $OS_AUTH_TOKEN\" \\"},{"line_number":127,"context_line":"        $OS_STORAGE_URL/test_container/object -X DELETE"},{"line_number":128,"context_line":"    $ curl -v -H \"X-Auth-Token: $OS_AUTH_TOKEN\" \\"},{"line_number":129,"context_line":"        $OS_STORAGE_URL/test_container/object"},{"line_number":130,"context_line":"    # (returns 404)"},{"line_number":131,"context_line":"    $ curl -v -H \"X-Auth-Token: $OS_AUTH_TOKEN\" \\"},{"line_number":132,"context_line":"        $OS_STORAGE_URL/test_container"},{"line_number":133,"context_line":"    # (does not include \u0027object\u0027)"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"    $ curl -v -H \"X-Auth-Token: $OS_AUTH_TOKEN\" \\"},{"line_number":136,"context_line":"        $OS_STORAGE_URL/test_container/object -X DELETE"},{"line_number":137,"context_line":"    $ curl -v -H \"X-Auth-Token: $OS_AUTH_TOKEN\" \\"},{"line_number":138,"context_line":"        $OS_STORAGE_URL/test_container/object"},{"line_number":139,"context_line":"    # (returns \u0027World\u0027)"},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"    $ curl -v -H \"X-Auth-Token: $OS_AUTH_TOKEN\" \\"},{"line_number":142,"context_line":"        $OS_STORAGE_URL/test_container/object -X DELETE"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"bacf61ea_f80d888f","line":139,"range":{"start_line":116,"start_character":0,"end_line":139,"end_character":23},"updated":"2016-08-02 10:13:28.000000000","message":"Hah, they are so interesting. Those mean if delete_marker in the versioning container (but using STACK mode), we can restore nothing(empty? no object?) via DELETE object.","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f3d9903a0825c5294d8e9a960be869b9e9f60b9b","unresolved":false,"context_lines":[{"line_number":113,"context_line":"    # (includes versions for \u0027Hello\u0027, \u0027World\u0027, the delete marker, and"},{"line_number":114,"context_line":"    # \u0027Hola\u0027)"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"    # Toggle the mode, and start popping versions"},{"line_number":117,"context_line":"    $ curl -v -H \"X-Auth-Token: $OS_AUTH_TOKEN\" \\"},{"line_number":118,"context_line":"        $OS_STORAGE_URL/test_container -X POST \\"},{"line_number":119,"context_line":"        -H \u0027X-Versions-Mode: stack\u0027"},{"line_number":120,"context_line":"    $ curl -v -H \"X-Auth-Token: $OS_AUTH_TOKEN\" \\"},{"line_number":121,"context_line":"        $OS_STORAGE_URL/test_container/object -X DELETE"},{"line_number":122,"context_line":"    $ curl -v -H \"X-Auth-Token: $OS_AUTH_TOKEN\" \\"},{"line_number":123,"context_line":"        $OS_STORAGE_URL/test_container/object"},{"line_number":124,"context_line":"    # (returns \u0027Hola\u0027)"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"    $ curl -v -H \"X-Auth-Token: $OS_AUTH_TOKEN\" \\"},{"line_number":127,"context_line":"        $OS_STORAGE_URL/test_container/object -X DELETE"},{"line_number":128,"context_line":"    $ curl -v -H \"X-Auth-Token: $OS_AUTH_TOKEN\" \\"},{"line_number":129,"context_line":"        $OS_STORAGE_URL/test_container/object"},{"line_number":130,"context_line":"    # (returns 404)"},{"line_number":131,"context_line":"    $ curl -v -H \"X-Auth-Token: $OS_AUTH_TOKEN\" \\"},{"line_number":132,"context_line":"        $OS_STORAGE_URL/test_container"},{"line_number":133,"context_line":"    # (does not include \u0027object\u0027)"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"    $ curl -v -H \"X-Auth-Token: $OS_AUTH_TOKEN\" \\"},{"line_number":136,"context_line":"        $OS_STORAGE_URL/test_container/object -X DELETE"},{"line_number":137,"context_line":"    $ curl -v -H \"X-Auth-Token: $OS_AUTH_TOKEN\" \\"},{"line_number":138,"context_line":"        $OS_STORAGE_URL/test_container/object"},{"line_number":139,"context_line":"    # (returns \u0027World\u0027)"},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"    $ curl -v -H \"X-Auth-Token: $OS_AUTH_TOKEN\" \\"},{"line_number":142,"context_line":"        $OS_STORAGE_URL/test_container/object -X DELETE"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"bacf61ea_382a557f","line":139,"range":{"start_line":116,"start_character":0,"end_line":139,"end_character":23},"in_reply_to":"bacf61ea_f80d888f","updated":"2016-08-04 00:26:58.000000000","message":"Yup, a delete-marker is just another version as far as stack-mode is concerned.","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"}],"api-ref/source/parameters.yaml":[{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"d31aed9887d49d1ec08b7163ce318ade08174e53","unresolved":false,"context_lines":[{"line_number":735,"context_line":"    disable versioning, set the header to an empty string."},{"line_number":736,"context_line":"  in: header"},{"line_number":737,"context_line":"  required: true"},{"line_number":738,"context_line":"  type: string"},{"line_number":739,"context_line":""},{"line_number":740,"context_line":"# variables in path"},{"line_number":741,"context_line":"account:"}],"source_content_type":"text/x-yaml","patch_set":19,"id":"bacf61ea_31cb0b55","side":"PARENT","line":738,"updated":"2016-08-05 08:58:24.000000000","message":"Ah? what\u0027s this actually?","commit_id":"a2c548b2af6d3e0db85de7716075ee09f12eb58e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d9707e817113e6d355824e469cb8ef4b4406b3f5","unresolved":false,"context_lines":[{"line_number":735,"context_line":"    disable versioning, set the header to an empty string."},{"line_number":736,"context_line":"  in: header"},{"line_number":737,"context_line":"  required: true"},{"line_number":738,"context_line":"  type: string"},{"line_number":739,"context_line":""},{"line_number":740,"context_line":"# variables in path"},{"line_number":741,"context_line":"account:"}],"source_content_type":"text/x-yaml","patch_set":19,"id":"9ad45d7e_876b5db6","side":"PARENT","line":738,"in_reply_to":"bacf61ea_31cb0b55","updated":"2016-08-11 23:23:07.000000000","message":"If you look at the Containers -\u003e HEAD section of http://developer.openstack.org/api-ref-objectstorage-v1.html you\u0027ll see a required (or rather, non-optional) X-Versions-Location response parameter. Looks like the \u0027_1\u0027 got lost in the repo migration; see https://review.openstack.org/#/c/312315/11/api-ref/source/storage-container-services.inc@411\n\nCome to think of it, both of these probably need to be added to the description of GET responses...","commit_id":"a2c548b2af6d3e0db85de7716075ee09f12eb58e"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"d31aed9887d49d1ec08b7163ce318ade08174e53","unresolved":false,"context_lines":[{"line_number":724,"context_line":"    previous versions of objects. If not set, versioning is disabled"},{"line_number":725,"context_line":"    for this container. For more information about object versioning,"},{"line_number":726,"context_line":"    see `Object versioning \u003chttp://docs.openstack.org/developer/"},{"line_number":727,"context_line":"    swift/api/object_versioning.html\u003e`_."},{"line_number":728,"context_line":"  in: header"},{"line_number":729,"context_line":"  required: false"},{"line_number":730,"context_line":"  type: string"}],"source_content_type":"text/x-yaml","patch_set":19,"id":"bacf61ea_51703f40","line":727,"updated":"2016-08-05 08:58:24.000000000","message":"great docs!","commit_id":"ed948e5065e997b9db22a0cf350b4b6f5dd70760"}],"doc/source/api/object_versioning.rst":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4dd3a2d3fe9f603178ced51a59d469bef9b7ed86","unresolved":false,"context_lines":[{"line_number":29,"context_line":"container automatically create non-current versions in the ``archive``"},{"line_number":30,"context_line":"container."},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"The ``X-Versions-Mode`` header defines how ``DELETE`` requests to objects"},{"line_number":33,"context_line":"in the versioned container. In the default ``stack`` mode, deleting an"},{"line_number":34,"context_line":"object will restore the most-recent version from the ``archive`` container,"},{"line_number":35,"context_line":"overwriting the curent version. Alternatively you may specify ``history``"},{"line_number":36,"context_line":"mode, where deleting an object will copy the current version to the"}],"source_content_type":"text/x-rst","patch_set":19,"id":"3ac371cc_b3459fb4","line":33,"range":{"start_line":32,"start_character":39,"end_line":33,"end_character":26},"updated":"2016-08-16 04:08:01.000000000","message":"I can haz grammar.","commit_id":"ed948e5065e997b9db22a0cf350b4b6f5dd70760"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"a49942beeec2c7ed221dfa9e2ff2b1a6027370e0","unresolved":false,"context_lines":[{"line_number":36,"context_line":"mode, where deleting an object will copy the current version to the"},{"line_number":37,"context_line":"``archive`` then remove it from the ``current`` container."},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"Here\u0027s an example demonstrating ``stack`` mode:"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"#.   Create the ``current`` container:"},{"line_number":42,"context_line":""}],"source_content_type":"text/x-rst","patch_set":19,"id":"9ad45d7e_b2d3595f","line":39,"updated":"2016-08-11 14:01:48.000000000","message":"Any reason for not adding \u0027history\u0027 mode example to this file?","commit_id":"ed948e5065e997b9db22a0cf350b4b6f5dd70760"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"f0090f76bd36ac7663cc0e163141354912755a9c","unresolved":false,"context_lines":[{"line_number":36,"context_line":"mode, where deleting an object will copy the current version to the"},{"line_number":37,"context_line":"``archive`` then remove it from the ``current`` container."},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"Here\u0027s an example demonstrating ``stack`` mode:"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"#.   Create the ``current`` container:"},{"line_number":42,"context_line":""}],"source_content_type":"text/x-rst","patch_set":19,"id":"1ac06dbe_4202d73f","line":39,"in_reply_to":"9ad45d7e_84a6bbab","updated":"2016-08-19 12:53:07.000000000","message":":) thanks for addressing in next patchset.","commit_id":"ed948e5065e997b9db22a0cf350b4b6f5dd70760"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d9707e817113e6d355824e469cb8ef4b4406b3f5","unresolved":false,"context_lines":[{"line_number":36,"context_line":"mode, where deleting an object will copy the current version to the"},{"line_number":37,"context_line":"``archive`` then remove it from the ``current`` container."},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"Here\u0027s an example demonstrating ``stack`` mode:"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"#.   Create the ``current`` container:"},{"line_number":42,"context_line":""}],"source_content_type":"text/x-rst","patch_set":19,"id":"9ad45d7e_84a6bbab","line":39,"in_reply_to":"9ad45d7e_b2d3595f","updated":"2016-08-11 23:23:07.000000000","message":"Laziness :-)\n\nWill add it in the next patchset.","commit_id":"ed948e5065e997b9db22a0cf350b4b6f5dd70760"}],"swift/common/middleware/versioned_writes.py":[{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"fb1bbfc0346e1eafdf82e1ea937a8eee6e6c2768","unresolved":false,"context_lines":[{"line_number":428,"context_line":"        marker_req \u003d make_pre_authed_request("},{"line_number":429,"context_line":"            req.environ, path\u003dmarker_path,"},{"line_number":430,"context_line":"            headers\u003dmarker_headers, method\u003d\u0027PUT\u0027, swift_source\u003d\u0027VW\u0027)"},{"line_number":431,"context_line":"        marker_req.environ[\u0027swift.content_type_overridden\u0027] \u003d True"},{"line_number":432,"context_line":"        marker_resp \u003d marker_req.get_response(self.app)"},{"line_number":433,"context_line":"        self._check_response_error(req, marker_resp)"},{"line_number":434,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"1aa78d24_211e3a70","line":431,"updated":"2016-07-11 19:53:44.000000000","message":"should x-auth-token be added to the header of marker_req like in L326?","commit_id":"cbf077e522d9217ad235b93d6ccb15b3f76aba5b"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"19509460cbca1d6ef7bfaf15fcde3079d260c5fa","unresolved":false,"context_lines":[{"line_number":428,"context_line":"        marker_req \u003d make_pre_authed_request("},{"line_number":429,"context_line":"            req.environ, path\u003dmarker_path,"},{"line_number":430,"context_line":"            headers\u003dmarker_headers, method\u003d\u0027PUT\u0027, swift_source\u003d\u0027VW\u0027)"},{"line_number":431,"context_line":"        marker_req.environ[\u0027swift.content_type_overridden\u0027] \u003d True"},{"line_number":432,"context_line":"        marker_resp \u003d marker_req.get_response(self.app)"},{"line_number":433,"context_line":"        self._check_response_error(req, marker_resp)"},{"line_number":434,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"1aa78d24_7813c8b8","line":431,"in_reply_to":"1aa78d24_104702bd","updated":"2016-07-11 22:06:55.000000000","message":"oops, missed that, thanks!","commit_id":"cbf077e522d9217ad235b93d6ccb15b3f76aba5b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f9b8e93494f64754a7f5b9a462c3bceb2e671fb0","unresolved":false,"context_lines":[{"line_number":428,"context_line":"        marker_req \u003d make_pre_authed_request("},{"line_number":429,"context_line":"            req.environ, path\u003dmarker_path,"},{"line_number":430,"context_line":"            headers\u003dmarker_headers, method\u003d\u0027PUT\u0027, swift_source\u003d\u0027VW\u0027)"},{"line_number":431,"context_line":"        marker_req.environ[\u0027swift.content_type_overridden\u0027] \u003d True"},{"line_number":432,"context_line":"        marker_resp \u003d marker_req.get_response(self.app)"},{"line_number":433,"context_line":"        self._check_response_error(req, marker_resp)"},{"line_number":434,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"1aa78d24_104702bd","line":431,"in_reply_to":"1aa78d24_211e3a70","updated":"2016-07-11 21:28:58.000000000","message":"It is -- L427.","commit_id":"cbf077e522d9217ad235b93d6ccb15b3f76aba5b"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"31bd7ad60a218920d1e1db9419cb18f02e2d1a5a","unresolved":false,"context_lines":[{"line_number":530,"context_line":"            else:"},{"line_number":531,"context_line":"                # there are older versions so copy the previous version to the"},{"line_number":532,"context_line":"                # current object and delete the previous version"},{"line_number":533,"context_line":"                prev_obj_name \u003d previous_version[\u0027name\u0027].encode(\u0027utf-8\u0027)"},{"line_number":534,"context_line":""},{"line_number":535,"context_line":"                get_path \u003d \"/%s/%s/%s/%s\" % ("},{"line_number":536,"context_line":"                    api_version, account_name, versions_cont, prev_obj_name)"}],"source_content_type":"text/x-python","patch_set":15,"id":"1aa78d24_606c8ad0","line":533,"updated":"2016-07-06 21:02:32.000000000","message":"L533-L551 looks identical to L491-L510. How about breaking it out into a helper method?","commit_id":"cbf077e522d9217ad235b93d6ccb15b3f76aba5b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f9b8e93494f64754a7f5b9a462c3bceb2e671fb0","unresolved":false,"context_lines":[{"line_number":530,"context_line":"            else:"},{"line_number":531,"context_line":"                # there are older versions so copy the previous version to the"},{"line_number":532,"context_line":"                # current object and delete the previous version"},{"line_number":533,"context_line":"                prev_obj_name \u003d previous_version[\u0027name\u0027].encode(\u0027utf-8\u0027)"},{"line_number":534,"context_line":""},{"line_number":535,"context_line":"                get_path \u003d \"/%s/%s/%s/%s\" % ("},{"line_number":536,"context_line":"                    api_version, account_name, versions_cont, prev_obj_name)"}],"source_content_type":"text/x-python","patch_set":15,"id":"1aa78d24_10fa6243","line":533,"in_reply_to":"1aa78d24_24a768be","updated":"2016-07-11 21:28:58.000000000","message":"I\u0027m in favor of some _restore_data helper, but I think combining it with _copy_current is building the wrong abstraction. *Maybe* if we had a generic COPY helper... but that\u0027s growing scope more than I\u0027d like.","commit_id":"cbf077e522d9217ad235b93d6ccb15b3f76aba5b"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"fb1bbfc0346e1eafdf82e1ea937a8eee6e6c2768","unresolved":false,"context_lines":[{"line_number":530,"context_line":"            else:"},{"line_number":531,"context_line":"                # there are older versions so copy the previous version to the"},{"line_number":532,"context_line":"                # current object and delete the previous version"},{"line_number":533,"context_line":"                prev_obj_name \u003d previous_version[\u0027name\u0027].encode(\u0027utf-8\u0027)"},{"line_number":534,"context_line":""},{"line_number":535,"context_line":"                get_path \u003d \"/%s/%s/%s/%s\" % ("},{"line_number":536,"context_line":"                    api_version, account_name, versions_cont, prev_obj_name)"}],"source_content_type":"text/x-python","patch_set":15,"id":"1aa78d24_24a768be","line":533,"in_reply_to":"1aa78d24_606c8ad0","updated":"2016-07-11 19:53:44.000000000","message":"this is actually very close to copy_current. wondering if it\u0027s worth doing a little bit of refactoring....","commit_id":"cbf077e522d9217ad235b93d6ccb15b3f76aba5b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f9b8e93494f64754a7f5b9a462c3bceb2e671fb0","unresolved":false,"context_lines":[{"line_number":554,"context_line":"                # version object - we already auth\u0027d original req so make a"},{"line_number":555,"context_line":"                # pre-authed request"},{"line_number":556,"context_line":"                req \u003d make_pre_authed_request("},{"line_number":557,"context_line":"                    req.environ, path\u003dget_path, method\u003d\u0027DELETE\u0027,"},{"line_number":558,"context_line":"                    swift_source\u003d\u0027VW\u0027)"},{"line_number":559,"context_line":""},{"line_number":560,"context_line":"            # remove \u0027X-If-Delete-At\u0027, since it is not for the older copy"}],"source_content_type":"text/x-python","patch_set":15,"id":"1aa78d24_a40cf3ec","line":557,"updated":"2016-07-11 21:28:58.000000000","message":"*This* one was missing x-auth-token, though...","commit_id":"cbf077e522d9217ad235b93d6ccb15b3f76aba5b"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"4aa0704ed39b8d62f52568b4722fa1560bc89d41","unresolved":false,"context_lines":[{"line_number":54,"context_line":"    a zero-byte \"delete marker\" object that notes when the delete took place,"},{"line_number":55,"context_line":"    and delete the object from the versioned container. The object will no"},{"line_number":56,"context_line":"    longer appear in container listings for the versioned container and future"},{"line_number":57,"context_line":"    requests there  will return 404 Not Found. However, the content will still"},{"line_number":58,"context_line":"    be recoverable from the versions container."},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"--------------------------------------------------"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_426668ed","line":57,"range":{"start_line":57,"start_character":19,"end_line":57,"end_character":20},"updated":"2016-08-02 10:13:28.000000000","message":"nits) make the doubled spaces to be single.","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f3d9903a0825c5294d8e9a960be869b9e9f60b9b","unresolved":false,"context_lines":[{"line_number":54,"context_line":"    a zero-byte \"delete marker\" object that notes when the delete took place,"},{"line_number":55,"context_line":"    and delete the object from the versioned container. The object will no"},{"line_number":56,"context_line":"    longer appear in container listings for the versioned container and future"},{"line_number":57,"context_line":"    requests there  will return 404 Not Found. However, the content will still"},{"line_number":58,"context_line":"    be recoverable from the versions container."},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"--------------------------------------------------"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_b83645e5","line":57,"range":{"start_line":57,"start_character":19,"end_line":57,"end_character":20},"in_reply_to":"bacf61ea_426668ed","updated":"2016-08-04 00:26:58.000000000","message":"Done","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"4aa0704ed39b8d62f52568b4722fa1560bc89d41","unresolved":false,"context_lines":[{"line_number":118,"context_line":"http://\u003cstorage_url\u003e/versions?prefix\u003d008myobject/"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"Now switch to ``stack`` mode and delete the (currently-missing) object. The"},{"line_number":121,"context_line":"previous version is restored, and the original version remains in \"versions\"::"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"    curl -i -XPUT -H \"X-Auth-Token: \u003ctoken\u003e\" -H \"X-Versions-Mode: stack\" \\"},{"line_number":124,"context_line":"http://\u003cstorage_url\u003e/container"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_c2bb78c2","line":121,"updated":"2016-08-02 10:13:28.000000000","message":"So this means we can change the versions mode so that we should care about split brain right?\n\nIn my feeling, history to stack seems safe but stack to history may be dangerous because we couldn\u0027t ensure the status change even if PUT container returns 2xx response (we could see old \u0027stack mode\u0027 container info) and it could delete actual object unfortunately...","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"a5d1fe5100c2cb996ebc20d74631c3e738e78018","unresolved":false,"context_lines":[{"line_number":118,"context_line":"http://\u003cstorage_url\u003e/versions?prefix\u003d008myobject/"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"Now switch to ``stack`` mode and delete the (currently-missing) object. The"},{"line_number":121,"context_line":"previous version is restored, and the original version remains in \"versions\"::"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"    curl -i -XPUT -H \"X-Auth-Token: \u003ctoken\u003e\" -H \"X-Versions-Mode: stack\" \\"},{"line_number":124,"context_line":"http://\u003cstorage_url\u003e/container"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_82e0f997","line":121,"in_reply_to":"bacf61ea_c2bb78c2","updated":"2016-08-03 20:44:26.000000000","message":"That is a good thing to think about.  So currently for posting x-versions-location to an existing container, you could also end up issuing a PUT to what might be the old container that is not versioned, correct?","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f3d9903a0825c5294d8e9a960be869b9e9f60b9b","unresolved":false,"context_lines":[{"line_number":118,"context_line":"http://\u003cstorage_url\u003e/versions?prefix\u003d008myobject/"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"Now switch to ``stack`` mode and delete the (currently-missing) object. The"},{"line_number":121,"context_line":"previous version is restored, and the original version remains in \"versions\"::"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"    curl -i -XPUT -H \"X-Auth-Token: \u003ctoken\u003e\" -H \"X-Versions-Mode: stack\" \\"},{"line_number":124,"context_line":"http://\u003cstorage_url\u003e/container"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_f8f8bd4b","line":121,"in_reply_to":"bacf61ea_c2bb78c2","updated":"2016-08-04 00:26:58.000000000","message":"We can\u0027t avoid worrying about split-brain -- even if we said that the mode had to be set on container creation (which I still oppose), we\u0027d need to worry about things like one client creating the versioned container with history mode, then another client on another continent trying to use it (and, like swiftclient, attempting to create it in the process) shortly afterward.\n\nNote that versioned_writes is already chock-full of similar issues:\n\n* Adding or changing X-Versions-Location has the exact same problem.\n* If there are multiple small writes over a single large (say, 1G) file, at least one small write is gone forever.\n* If a DELETE comes in under stack mode and there are aync pendings, we may restore the wrong item. Assuming the error is even noticed, naive attempts to rectify the issue will result in a mangled history.\n\nI\u0027m in favor of clarifying some of the pitfalls associated with versioned_writes, but I\u0027m not sure on the wording.","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"4aa0704ed39b8d62f52568b4722fa1560bc89d41","unresolved":false,"context_lines":[{"line_number":175,"context_line":""},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"VERSIONING_MODES \u003d (\u0027stack\u0027, \u0027history\u0027)"},{"line_number":178,"context_line":"DELETE_MARKER_CONTENT_TYPE \u003d \u0027application/x-deleted;swift_versions_deleted\u003d1\u0027"},{"line_number":179,"context_line":""},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"class VersionedWritesContext(WSGIContext):"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_a21f64b5","line":178,"range":{"start_line":178,"start_character":42,"end_line":178,"end_character":51},"updated":"2016-08-02 10:13:28.000000000","message":"it seems sort of \u0027delete-marker\u0027?","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"f03a46505e16b599bf2ff5a5d6fd0f7316b3b43c","unresolved":false,"context_lines":[{"line_number":175,"context_line":""},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"VERSIONING_MODES \u003d (\u0027stack\u0027, \u0027history\u0027)"},{"line_number":178,"context_line":"DELETE_MARKER_CONTENT_TYPE \u003d \u0027application/x-deleted;swift_versions_deleted\u003d1\u0027"},{"line_number":179,"context_line":""},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"class VersionedWritesContext(WSGIContext):"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_65e13d2a","line":178,"range":{"start_line":178,"start_character":42,"end_line":178,"end_character":51},"in_reply_to":"bacf61ea_189311fc","updated":"2016-08-16 02:09:55.000000000","message":"good reason :P","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f3d9903a0825c5294d8e9a960be869b9e9f60b9b","unresolved":false,"context_lines":[{"line_number":175,"context_line":""},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"VERSIONING_MODES \u003d (\u0027stack\u0027, \u0027history\u0027)"},{"line_number":178,"context_line":"DELETE_MARKER_CONTENT_TYPE \u003d \u0027application/x-deleted;swift_versions_deleted\u003d1\u0027"},{"line_number":179,"context_line":""},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"class VersionedWritesContext(WSGIContext):"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_189311fc","line":178,"range":{"start_line":178,"start_character":42,"end_line":178,"end_character":51},"in_reply_to":"bacf61ea_a21f64b5","updated":"2016-08-04 00:26:58.000000000","message":"As much as anything, I just wanted to keep it on one line :P","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"4aa0704ed39b8d62f52568b4722fa1560bc89d41","unresolved":false,"context_lines":[{"line_number":339,"context_line":"        # could not version the data, bail"},{"line_number":340,"context_line":"        raise HTTPServiceUnavailable(request\u003dreq)"},{"line_number":341,"context_line":""},{"line_number":342,"context_line":"    def _build_versions_object(self, object_name, ts\u003dNone):"},{"line_number":343,"context_line":"        return \u0027%03x%s/%s\u0027 % ("},{"line_number":344,"context_line":"            len(object_name),"},{"line_number":345,"context_line":"            object_name,"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_e24cbc9f","line":342,"updated":"2016-08-02 10:13:28.000000000","message":"nits) build_versions_object_name or build_versions_object_path, strictly?","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f3d9903a0825c5294d8e9a960be869b9e9f60b9b","unresolved":false,"context_lines":[{"line_number":339,"context_line":"        # could not version the data, bail"},{"line_number":340,"context_line":"        raise HTTPServiceUnavailable(request\u003dreq)"},{"line_number":341,"context_line":""},{"line_number":342,"context_line":"    def _build_versions_object(self, object_name, ts\u003dNone):"},{"line_number":343,"context_line":"        return \u0027%03x%s/%s\u0027 % ("},{"line_number":344,"context_line":"            len(object_name),"},{"line_number":345,"context_line":"            object_name,"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_8e2f82a0","line":342,"in_reply_to":"bacf61ea_e24cbc9f","updated":"2016-08-04 00:26:58.000000000","message":"Done","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"4aa0704ed39b8d62f52568b4722fa1560bc89d41","unresolved":false,"context_lines":[{"line_number":343,"context_line":"        return \u0027%03x%s/%s\u0027 % ("},{"line_number":344,"context_line":"            len(object_name),"},{"line_number":345,"context_line":"            object_name,"},{"line_number":346,"context_line":"            \u0027\u0027 if ts is None else Timestamp(ts).internal)"},{"line_number":347,"context_line":""},{"line_number":348,"context_line":"    def _copy_current(self, req, versions_cont, api_version, account_name,"},{"line_number":349,"context_line":"                      object_name):"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_7d450d41","line":346,"range":{"start_line":346,"start_character":11,"end_line":346,"end_character":57},"updated":"2016-08-02 10:13:28.000000000","message":"memo) Before this patch, the object path must include timestamp string so this syntax change seems to make an impact, is it safe?\n\nah...ts will be None if we need only prefix. make sense but i\u0027m feeling it\u0027s better to make another method like make_prefix and then call it here, IMHO, to prevent unexpected ts\u003dNone calls.","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f3d9903a0825c5294d8e9a960be869b9e9f60b9b","unresolved":false,"context_lines":[{"line_number":343,"context_line":"        return \u0027%03x%s/%s\u0027 % ("},{"line_number":344,"context_line":"            len(object_name),"},{"line_number":345,"context_line":"            object_name,"},{"line_number":346,"context_line":"            \u0027\u0027 if ts is None else Timestamp(ts).internal)"},{"line_number":347,"context_line":""},{"line_number":348,"context_line":"    def _copy_current(self, req, versions_cont, api_version, account_name,"},{"line_number":349,"context_line":"                      object_name):"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_6e2a0e92","line":346,"range":{"start_line":346,"start_character":11,"end_line":346,"end_character":57},"in_reply_to":"bacf61ea_7d450d41","updated":"2016-08-04 00:26:58.000000000","message":"Done","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"4aa0704ed39b8d62f52568b4722fa1560bc89d41","unresolved":false,"context_lines":[{"line_number":352,"context_line":"        if \u0027X-Object-Manifest\u0027 in get_resp.headers:"},{"line_number":353,"context_line":"            # do not version DLO manifest, proceed with original request"},{"line_number":354,"context_line":"            close_if_possible(get_resp.app_iter)"},{"line_number":355,"context_line":"            return self.app"},{"line_number":356,"context_line":"        if get_resp.status_int \u003d\u003d HTTP_NOT_FOUND:"},{"line_number":357,"context_line":"            # nothing to version, proceed with original request"},{"line_number":358,"context_line":"            close_if_possible(get_resp.app_iter)"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_3d7a7524","line":355,"updated":"2016-08-02 10:13:28.000000000","message":"the return value of _copy_current is never maintained so just \u0027return\u0027 seems enough.","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f3d9903a0825c5294d8e9a960be869b9e9f60b9b","unresolved":false,"context_lines":[{"line_number":352,"context_line":"        if \u0027X-Object-Manifest\u0027 in get_resp.headers:"},{"line_number":353,"context_line":"            # do not version DLO manifest, proceed with original request"},{"line_number":354,"context_line":"            close_if_possible(get_resp.app_iter)"},{"line_number":355,"context_line":"            return self.app"},{"line_number":356,"context_line":"        if get_resp.status_int \u003d\u003d HTTP_NOT_FOUND:"},{"line_number":357,"context_line":"            # nothing to version, proceed with original request"},{"line_number":358,"context_line":"            close_if_possible(get_resp.app_iter)"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_0e443272","line":355,"in_reply_to":"bacf61ea_3d7a7524","updated":"2016-08-04 00:26:58.000000000","message":"Done","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"4aa0704ed39b8d62f52568b4722fa1560bc89d41","unresolved":false,"context_lines":[{"line_number":402,"context_line":"                                        object_name):"},{"line_number":403,"context_line":"        \"\"\""},{"line_number":404,"context_line":"        Copy current version of object to versions_container and write a"},{"line_number":405,"context_line":"        delete marker before proceding with original request."},{"line_number":406,"context_line":""},{"line_number":407,"context_line":"        :param req: original request."},{"line_number":408,"context_line":"        :param versions_cont: container where previous versions of the object"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_080e518b","line":405,"updated":"2016-08-02 10:13:28.000000000","message":"nits) it might be helpful that adding a doc like _push is for history mode.","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f3d9903a0825c5294d8e9a960be869b9e9f60b9b","unresolved":false,"context_lines":[{"line_number":402,"context_line":"                                        object_name):"},{"line_number":403,"context_line":"        \"\"\""},{"line_number":404,"context_line":"        Copy current version of object to versions_container and write a"},{"line_number":405,"context_line":"        delete marker before proceding with original request."},{"line_number":406,"context_line":""},{"line_number":407,"context_line":"        :param req: original request."},{"line_number":408,"context_line":"        :param versions_cont: container where previous versions of the object"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_8cff8b00","line":405,"in_reply_to":"bacf61ea_080e518b","updated":"2016-08-04 00:26:58.000000000","message":"Done","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"4aa0704ed39b8d62f52568b4722fa1560bc89d41","unresolved":false,"context_lines":[{"line_number":460,"context_line":"                                       account_name, container_name,"},{"line_number":461,"context_line":"                                       object_name):"},{"line_number":462,"context_line":"        \"\"\""},{"line_number":463,"context_line":"        Delete current version of object and pop previous version in its place."},{"line_number":464,"context_line":""},{"line_number":465,"context_line":"        :param req: original request."},{"line_number":466,"context_line":"        :param versions_cont: container where previous versions of the object"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_8871a10e","line":463,"updated":"2016-08-02 10:13:28.000000000","message":"memo) And _pop is for stack mode.","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f3d9903a0825c5294d8e9a960be869b9e9f60b9b","unresolved":false,"context_lines":[{"line_number":460,"context_line":"                                       account_name, container_name,"},{"line_number":461,"context_line":"                                       object_name):"},{"line_number":462,"context_line":"        \"\"\""},{"line_number":463,"context_line":"        Delete current version of object and pop previous version in its place."},{"line_number":464,"context_line":""},{"line_number":465,"context_line":"        :param req: original request."},{"line_number":466,"context_line":"        :param versions_cont: container where previous versions of the object"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_6c02170b","line":463,"in_reply_to":"bacf61ea_8871a10e","updated":"2016-08-04 00:26:58.000000000","message":"Done","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f3d9903a0825c5294d8e9a960be869b9e9f60b9b","unresolved":false,"context_lines":[{"line_number":493,"context_line":"                # check whether we have data in the versioned container"},{"line_number":494,"context_line":"                head_req \u003d make_pre_authed_request("},{"line_number":495,"context_line":"                    req.environ, path\u003dreq.path_info, method\u003d\u0027HEAD\u0027,"},{"line_number":496,"context_line":"                    headers\u003dauth_token_header, swift_source\u003d\u0027VW\u0027)"},{"line_number":497,"context_line":"                hresp \u003d head_req.get_response(self.app)"},{"line_number":498,"context_line":""},{"line_number":499,"context_line":"                if hresp.status_int !\u003d HTTP_NOT_FOUND:"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_303aac99","line":496,"updated":"2016-08-04 00:26:58.000000000","message":"Bah. I\u0027m not convinced I can drop the X-Newest here (cf patchset 16)...","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"51ba9a22d6647b9f3fafe8d38a00ced1bf77e5db","unresolved":false,"context_lines":[{"line_number":574,"context_line":"        if location:"},{"line_number":575,"context_line":"            self._response_headers.extend([(\u0027X-Versions-Location\u0027, location)])"},{"line_number":576,"context_line":"        if mode:"},{"line_number":577,"context_line":"            self._response_headers.extend([(\u0027X-Versions-Mode\u0027, mode)])"},{"line_number":578,"context_line":""},{"line_number":579,"context_line":"        start_response(self._response_status,"},{"line_number":580,"context_line":"                       self._response_headers,"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_d9717b79","line":577,"updated":"2016-08-03 02:38:37.000000000","message":"there are no test cases that are asserting \u0027X-Versions-Mode\u0027 is put in the response headers in this situation.  If you comment this part out and run tests, nothing fails.","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f3d9903a0825c5294d8e9a960be869b9e9f60b9b","unresolved":false,"context_lines":[{"line_number":574,"context_line":"        if location:"},{"line_number":575,"context_line":"            self._response_headers.extend([(\u0027X-Versions-Location\u0027, location)])"},{"line_number":576,"context_line":"        if mode:"},{"line_number":577,"context_line":"            self._response_headers.extend([(\u0027X-Versions-Mode\u0027, mode)])"},{"line_number":578,"context_line":""},{"line_number":579,"context_line":"        start_response(self._response_status,"},{"line_number":580,"context_line":"                       self._response_headers,"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_cf5855fd","line":577,"in_reply_to":"bacf61ea_d9717b79","updated":"2016-08-04 00:26:58.000000000","message":"Good catch! Fixed.","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"51ba9a22d6647b9f3fafe8d38a00ced1bf77e5db","unresolved":false,"context_lines":[{"line_number":634,"context_line":"        if \u0027X-Versions-Mode\u0027 in req.headers:"},{"line_number":635,"context_line":"            val \u003d req.headers.pop(\u0027X-Versions-Mode\u0027)"},{"line_number":636,"context_line":"            if val:"},{"line_number":637,"context_line":"                if not config_true_value(enabled) and \\"},{"line_number":638,"context_line":"                        req.method in (\u0027PUT\u0027, \u0027POST\u0027):"},{"line_number":639,"context_line":"                    raise HTTPPreconditionFailed("},{"line_number":640,"context_line":"                        request\u003dreq, content_type\u003d\u0027text/plain\u0027,"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_19c83374","line":637,"updated":"2016-08-03 02:38:37.000000000","message":"technically as the class is written, I don\u0027t think we can get here if enabled is not true.  But maybe this is just a sanity check?","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f3d9903a0825c5294d8e9a960be869b9e9f60b9b","unresolved":false,"context_lines":[{"line_number":634,"context_line":"        if \u0027X-Versions-Mode\u0027 in req.headers:"},{"line_number":635,"context_line":"            val \u003d req.headers.pop(\u0027X-Versions-Mode\u0027)"},{"line_number":636,"context_line":"            if val:"},{"line_number":637,"context_line":"                if not config_true_value(enabled) and \\"},{"line_number":638,"context_line":"                        req.method in (\u0027PUT\u0027, \u0027POST\u0027):"},{"line_number":639,"context_line":"                    raise HTTPPreconditionFailed("},{"line_number":640,"context_line":"                        request\u003dreq, content_type\u003d\u0027text/plain\u0027,"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_ec3c47c1","line":637,"in_reply_to":"bacf61ea_19c83374","updated":"2016-08-04 00:26:58.000000000","message":"I was mirroring the code for X-Versions-Location.\n\nLooks like we still need it, though (in both places). Down in __call__, we haven\u0027t turned allow_versioned_writes into a bool yet, so the\n\n if allow_versioned_writes and ...\n\nis just checking that the string isn\u0027t empty. Thanks, test_container_allow_versioned_writes_false!","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"f03a46505e16b599bf2ff5a5d6fd0f7316b3b43c","unresolved":false,"context_lines":[{"line_number":634,"context_line":"        if \u0027X-Versions-Mode\u0027 in req.headers:"},{"line_number":635,"context_line":"            val \u003d req.headers.pop(\u0027X-Versions-Mode\u0027)"},{"line_number":636,"context_line":"            if val:"},{"line_number":637,"context_line":"                if not config_true_value(enabled) and \\"},{"line_number":638,"context_line":"                        req.method in (\u0027PUT\u0027, \u0027POST\u0027):"},{"line_number":639,"context_line":"                    raise HTTPPreconditionFailed("},{"line_number":640,"context_line":"                        request\u003dreq, content_type\u003d\u0027text/plain\u0027,"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_450d193d","line":637,"in_reply_to":"bacf61ea_ec3c47c1","updated":"2016-08-16 02:09:55.000000000","message":"That\u0027s what I\u0027d like to solve with https://review.openstack.org/#/c/209315/9/swift/common/middleware/versioned_writes.py\n\nenabled will be true IIF versioned_writes explicitly appeared in the pipeline and set allow_versioned_writes\u003dTrue. that will be false when versioned_writes inserted automatically, IIRC.","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"a26c25cfb4d682fd1270c74c741bea17b7564dc6","unresolved":false,"context_lines":[{"line_number":673,"context_line":"        versions_cont \u003d container_info.get("},{"line_number":674,"context_line":"            \u0027sysmeta\u0027, {}).get(\u0027versions-location\u0027)"},{"line_number":675,"context_line":"        versioning_mode \u003d container_info.get("},{"line_number":676,"context_line":"            \u0027sysmeta\u0027, {}).get(\u0027versions-mode\u0027, \u0027stack\u0027)"},{"line_number":677,"context_line":"        if not versions_cont:"},{"line_number":678,"context_line":"            versions_cont \u003d container_info.get(\u0027versions\u0027)"},{"line_number":679,"context_line":"            # if allow_versioned_writes is not set in the configuration files"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_6da2ed4c","line":676,"range":{"start_line":676,"start_character":48,"end_line":676,"end_character":55},"updated":"2016-07-29 18:41:02.000000000","message":"suggestion: left\u0027s offer operators the option to set the default mode in the config files.\n\nGreen field installations might want to just default to history and not have users have to pass in the additional headers every time they set versioning on a container.","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"84cd0cfd3aead310435400e1437350daef14f22f","unresolved":false,"context_lines":[{"line_number":55,"context_line":"    and delete the object from the versioned container. The object will no"},{"line_number":56,"context_line":"    longer appear in container listings for the versioned container and future"},{"line_number":57,"context_line":"    requests there will return 404 Not Found. However, the content will still"},{"line_number":58,"context_line":"    be recoverable from the versions container."},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"To restore a previous version of an object, find the desired version in the"},{"line_number":61,"context_line":"versions container then issue a ``COPY`` with a ``Destination`` header"}],"source_content_type":"text/x-python","patch_set":19,"id":"9ad45d7e_eec5a50a","line":58,"range":{"start_line":58,"start_character":28,"end_line":58,"end_character":46},"updated":"2016-08-12 15:17:21.000000000","message":"I noticed in another doc \u0027versions container\u0027 being referenced as \u0027archive container\u0027. We should come up with a common terminology.\n\nI\u0027m not a big fan of versions and versioned container just because they are easy to confuse. Is \u0027archive\u0027 better?? What is typically used in the industry? Are there any UX experts?","commit_id":"ed948e5065e997b9db22a0cf350b4b6f5dd70760"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4dd3a2d3fe9f603178ced51a59d469bef9b7ed86","unresolved":false,"context_lines":[{"line_number":55,"context_line":"    and delete the object from the versioned container. The object will no"},{"line_number":56,"context_line":"    longer appear in container listings for the versioned container and future"},{"line_number":57,"context_line":"    requests there will return 404 Not Found. However, the content will still"},{"line_number":58,"context_line":"    be recoverable from the versions container."},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"To restore a previous version of an object, find the desired version in the"},{"line_number":61,"context_line":"versions container then issue a ``COPY`` with a ``Destination`` header"}],"source_content_type":"text/x-python","patch_set":19,"id":"3ac371cc_53f42bf1","line":58,"range":{"start_line":58,"start_character":28,"end_line":58,"end_character":46},"in_reply_to":"9ad45d7e_eec5a50a","updated":"2016-08-16 04:08:01.000000000","message":"Done. I rather like \u0027archive\u0027.","commit_id":"ed948e5065e997b9db22a0cf350b4b6f5dd70760"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"d31aed9887d49d1ec08b7163ce318ade08174e53","unresolved":false,"context_lines":[{"line_number":96,"context_line":"have been upgraded to a version of Swift that supports it. Attempting to use"},{"line_number":97,"context_line":"the \u0027history\u0027 mode during a rolling upgrade may result in some requests being"},{"line_number":98,"context_line":"served by proxies running old code (which necessarily uses the \u0027stack\u0027 mode),"},{"line_number":99,"context_line":"leading to data loss."},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"-----------------------"},{"line_number":102,"context_line":"Examples Using ``curl``"}],"source_content_type":"text/x-python","patch_set":19,"id":"bacf61ea_2f49e631","line":99,"updated":"2016-08-05 08:58:24.000000000","message":"Looking at here, I\u0027m realizing it\u0027s good to register the available mode info into /info?\n\nThe draft is https://review.openstack.org/351540","commit_id":"ed948e5065e997b9db22a0cf350b4b6f5dd70760"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d9707e817113e6d355824e469cb8ef4b4406b3f5","unresolved":false,"context_lines":[{"line_number":96,"context_line":"have been upgraded to a version of Swift that supports it. Attempting to use"},{"line_number":97,"context_line":"the \u0027history\u0027 mode during a rolling upgrade may result in some requests being"},{"line_number":98,"context_line":"served by proxies running old code (which necessarily uses the \u0027stack\u0027 mode),"},{"line_number":99,"context_line":"leading to data loss."},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"-----------------------"},{"line_number":102,"context_line":"Examples Using ``curl``"}],"source_content_type":"text/x-python","patch_set":19,"id":"9ad45d7e_874ebd38","line":99,"in_reply_to":"bacf61ea_2f49e631","updated":"2016-08-11 23:23:07.000000000","message":"Good idea. I might use the VERSIONING_MODES constant instead of the explicit list, but I\u0027ll squash it in.","commit_id":"ed948e5065e997b9db22a0cf350b4b6f5dd70760"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"84cd0cfd3aead310435400e1437350daef14f22f","unresolved":false,"context_lines":[{"line_number":133,"context_line":"    curl -i -H \"X-Auth-Token: \u003ctoken\u003e\" \\"},{"line_number":134,"context_line":"http://\u003cstorage_url\u003e/versions?prefix\u003d008myobject/"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"Now switch to ``stack`` mode and delete the (currently-missing) object. The"},{"line_number":137,"context_line":"previous version is restored, and the original version remains in \"versions\"::"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"    curl -i -XPUT -H \"X-Auth-Token: \u003ctoken\u003e\" -H \"X-Versions-Mode: stack\" \\"}],"source_content_type":"text/x-python","patch_set":19,"id":"9ad45d7e_c2c4f560","line":136,"updated":"2016-08-12 15:17:21.000000000","message":"I\u0027m not a big fan of documenting changing from history to stack as if it is a feature. Much like we don\u0027t document enabling and disabling versioned writes and seeing the results of that when users PUT objects in each state.\n\nI\u0027d prefer to see we document how it functions in history mode, indluding setting history mode, sending writes, sending deletes and how to restore a previous version.\n\nAnd then repeat the same for stack mode.\n\nWe could/should document the toggling of modes more as a P.S. e.g., \"It is probably not a good idea, but if you do that, this is what happens...\"","commit_id":"ed948e5065e997b9db22a0cf350b4b6f5dd70760"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4dd3a2d3fe9f603178ced51a59d469bef9b7ed86","unresolved":false,"context_lines":[{"line_number":133,"context_line":"    curl -i -H \"X-Auth-Token: \u003ctoken\u003e\" \\"},{"line_number":134,"context_line":"http://\u003cstorage_url\u003e/versions?prefix\u003d008myobject/"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"Now switch to ``stack`` mode and delete the (currently-missing) object. The"},{"line_number":137,"context_line":"previous version is restored, and the original version remains in \"versions\"::"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"    curl -i -XPUT -H \"X-Auth-Token: \u003ctoken\u003e\" -H \"X-Versions-Mode: stack\" \\"}],"source_content_type":"text/x-python","patch_set":19,"id":"3ac371cc_93dea36b","line":136,"in_reply_to":"9ad45d7e_c2c4f560","updated":"2016-08-16 04:08:01.000000000","message":"Done","commit_id":"ed948e5065e997b9db22a0cf350b4b6f5dd70760"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"d31aed9887d49d1ec08b7163ce318ade08174e53","unresolved":false,"context_lines":[{"line_number":590,"context_line":"        sysmeta_version_hdr \u003d get_sys_meta_prefix(\u0027container\u0027) + \\"},{"line_number":591,"context_line":"            \u0027versions-location\u0027"},{"line_number":592,"context_line":"        sysmeta_mode_hdr \u003d get_sys_meta_prefix(\u0027container\u0027) + \\"},{"line_number":593,"context_line":"            \u0027versions-mode\u0027"},{"line_number":594,"context_line":"        mode \u003d location \u003d \u0027\u0027"},{"line_number":595,"context_line":"        for key, val in self._response_headers:"},{"line_number":596,"context_line":"            if key.lower() \u003d\u003d sysmeta_version_hdr:"}],"source_content_type":"text/x-python","patch_set":19,"id":"bacf61ea_c0d3b736","line":593,"updated":"2016-08-05 08:58:24.000000000","message":"nits) it might be good to make SYSMETA_VERSIONS_HDR and SYSMETA_MODE_HDR in the global scope.","commit_id":"ed948e5065e997b9db22a0cf350b4b6f5dd70760"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d9707e817113e6d355824e469cb8ef4b4406b3f5","unresolved":false,"context_lines":[{"line_number":590,"context_line":"        sysmeta_version_hdr \u003d get_sys_meta_prefix(\u0027container\u0027) + \\"},{"line_number":591,"context_line":"            \u0027versions-location\u0027"},{"line_number":592,"context_line":"        sysmeta_mode_hdr \u003d get_sys_meta_prefix(\u0027container\u0027) + \\"},{"line_number":593,"context_line":"            \u0027versions-mode\u0027"},{"line_number":594,"context_line":"        mode \u003d location \u003d \u0027\u0027"},{"line_number":595,"context_line":"        for key, val in self._response_headers:"},{"line_number":596,"context_line":"            if key.lower() \u003d\u003d sysmeta_version_hdr:"}],"source_content_type":"text/x-python","patch_set":19,"id":"9ad45d7e_a74f8132","line":593,"in_reply_to":"bacf61ea_c0d3b736","updated":"2016-08-11 23:23:07.000000000","message":"Good idea; next patchset.","commit_id":"ed948e5065e997b9db22a0cf350b4b6f5dd70760"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"d31aed9887d49d1ec08b7163ce318ade08174e53","unresolved":false,"context_lines":[{"line_number":601,"context_line":"        if location:"},{"line_number":602,"context_line":"            self._response_headers.extend([(\u0027X-Versions-Location\u0027, location)])"},{"line_number":603,"context_line":"        if mode:"},{"line_number":604,"context_line":"            self._response_headers.extend([(\u0027X-Versions-Mode\u0027, mode)])"},{"line_number":605,"context_line":""},{"line_number":606,"context_line":"        start_response(self._response_status,"},{"line_number":607,"context_line":"                       self._response_headers,"}],"source_content_type":"text/x-python","patch_set":19,"id":"bacf61ea_207a9324","line":604,"updated":"2016-08-05 08:58:24.000000000","message":"So I\u0027m realizing it\u0027s better to set default value (i.e. \"stack\") to X-Versions-Mode header if it is not specified from the client.","commit_id":"ed948e5065e997b9db22a0cf350b4b6f5dd70760"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"f0090f76bd36ac7663cc0e163141354912755a9c","unresolved":false,"context_lines":[{"line_number":601,"context_line":"        if location:"},{"line_number":602,"context_line":"            self._response_headers.extend([(\u0027X-Versions-Location\u0027, location)])"},{"line_number":603,"context_line":"        if mode:"},{"line_number":604,"context_line":"            self._response_headers.extend([(\u0027X-Versions-Mode\u0027, mode)])"},{"line_number":605,"context_line":""},{"line_number":606,"context_line":"        start_response(self._response_status,"},{"line_number":607,"context_line":"                       self._response_headers,"}],"source_content_type":"text/x-python","patch_set":19,"id":"1ac06dbe_c230870a","line":604,"in_reply_to":"9ad45d7e_108e862d","updated":"2016-08-19 12:53:07.000000000","message":"Yes thanks, I tested again and it shows up; Also what you said about \u0027stack\u0027-\u0027history\u0027 mode behavior makes sense.","commit_id":"ed948e5065e997b9db22a0cf350b4b6f5dd70760"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d9707e817113e6d355824e469cb8ef4b4406b3f5","unresolved":false,"context_lines":[{"line_number":601,"context_line":"        if location:"},{"line_number":602,"context_line":"            self._response_headers.extend([(\u0027X-Versions-Location\u0027, location)])"},{"line_number":603,"context_line":"        if mode:"},{"line_number":604,"context_line":"            self._response_headers.extend([(\u0027X-Versions-Mode\u0027, mode)])"},{"line_number":605,"context_line":""},{"line_number":606,"context_line":"        start_response(self._response_status,"},{"line_number":607,"context_line":"                       self._response_headers,"}],"source_content_type":"text/x-python","patch_set":19,"id":"9ad45d7e_108e862d","line":604,"in_reply_to":"bacf61ea_207a9324","updated":"2016-08-11 23:23:07.000000000","message":"\u003e if it is not specified from the client\n\nDuring a PUT or a POST? Only if it\u0027s setting X-Versions-Location, or always?\n\nDuring POST is right out; whether the client sent a new location or not, there may already be a mode set and we don\u0027t want to now override it.\n\nWe *could* do it on PUT, but we\u0027ll still need to deal with mode-less containers regardless (to accommodate pre-existing containers). I\u0027m kind of inclined to leave it as is, and let operators choose to have the mode automatically added via a defaulter config option once https://review.openstack.org/#/c/342857/ lands.\n\n@Mahati, this is where we expose X-Versions-Mode on container GET.","commit_id":"ed948e5065e997b9db22a0cf350b4b6f5dd70760"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"84cd0cfd3aead310435400e1437350daef14f22f","unresolved":false,"context_lines":[{"line_number":700,"context_line":"        versions_cont \u003d container_info.get("},{"line_number":701,"context_line":"            \u0027sysmeta\u0027, {}).get(\u0027versions-location\u0027)"},{"line_number":702,"context_line":"        versioning_mode \u003d container_info.get("},{"line_number":703,"context_line":"            \u0027sysmeta\u0027, {}).get(\u0027versions-mode\u0027, \u0027stack\u0027)"},{"line_number":704,"context_line":"        if not versions_cont:"},{"line_number":705,"context_line":"            versions_cont \u003d container_info.get(\u0027versions\u0027)"},{"line_number":706,"context_line":"            # if allow_versioned_writes is not set in the configuration files"}],"source_content_type":"text/x-python","patch_set":19,"id":"9ad45d7e_22c6b116","line":703,"range":{"start_line":703,"start_character":48,"end_line":703,"end_character":55},"updated":"2016-08-12 15:17:21.000000000","message":"I can understand making \u0027stack;  the default mode for backwards compatibility, but operators should be able to set the default mode from a configuration file so that every new container gets the same mode if they choose to do it that way","commit_id":"ed948e5065e997b9db22a0cf350b4b6f5dd70760"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4dd3a2d3fe9f603178ced51a59d469bef9b7ed86","unresolved":false,"context_lines":[{"line_number":700,"context_line":"        versions_cont \u003d container_info.get("},{"line_number":701,"context_line":"            \u0027sysmeta\u0027, {}).get(\u0027versions-location\u0027)"},{"line_number":702,"context_line":"        versioning_mode \u003d container_info.get("},{"line_number":703,"context_line":"            \u0027sysmeta\u0027, {}).get(\u0027versions-mode\u0027, \u0027stack\u0027)"},{"line_number":704,"context_line":"        if not versions_cont:"},{"line_number":705,"context_line":"            versions_cont \u003d container_info.get(\u0027versions\u0027)"},{"line_number":706,"context_line":"            # if allow_versioned_writes is not set in the configuration files"}],"source_content_type":"text/x-python","patch_set":19,"id":"3ac371cc_f32f173c","line":703,"range":{"start_line":703,"start_character":48,"end_line":703,"end_character":55},"in_reply_to":"9ad45d7e_22c6b116","updated":"2016-08-16 04:08:01.000000000","message":"Only new containers, or all containers that do not explicitly state a mode? I.e., should we\n\n setdefault(VERSIONS_MODE_CLIENT, self.conf[\u0027default_versions_mode\u0027])\n\non all container PUTs, or\n\n get(\u0027versions-mode\u0027, self.conf[\u0027default_versions_mode\u0027])\n\nhere?\n\nIf/when defaulter lands, which should take precedence?","commit_id":"ed948e5065e997b9db22a0cf350b4b6f5dd70760"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"4fda71ef5b7ca3e815531c3403578cc2fa31b7ac","unresolved":false,"context_lines":[{"line_number":815,"context_line":"    conf.update(local_conf)"},{"line_number":816,"context_line":"    if config_true_value(conf.get(\u0027allow_versioned_writes\u0027)):"},{"line_number":817,"context_line":"        register_swift_info(\u0027versioned_writes\u0027,"},{"line_number":818,"context_line":"                            allowed_versions_mode\u003dVERSIONING_MODES)"},{"line_number":819,"context_line":""},{"line_number":820,"context_line":"    def obj_versions_filter(app):"},{"line_number":821,"context_line":"        return VersionedWritesMiddleware(app, conf)"}],"source_content_type":"text/x-python","patch_set":20,"id":"1ac06dbe_ff9ed661","line":818,"updated":"2016-08-24 23:27:42.000000000","message":"this is good!","commit_id":"c7283be4fe9ebaf0e8feba695a1c664eec6fb355"}],"test/unit/common/middleware/test_versioned_writes.py":[{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"31bd7ad60a218920d1e1db9419cb18f02e2d1a5a","unresolved":false,"context_lines":[{"line_number":109,"context_line":""},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"class VersionedWritesTestCase(VersionedWritesBaseTestCase):"},{"line_number":112,"context_line":"    def test_put_container(self):"},{"line_number":113,"context_line":"        self.app.register(\u0027PUT\u0027, \u0027/v1/a/c\u0027, swob.HTTPOk, {}, \u0027passed\u0027)"},{"line_number":114,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c\u0027,"},{"line_number":115,"context_line":"                            headers\u003d{\u0027X-Versions-Location\u0027: \u0027ver_cont\u0027},"}],"source_content_type":"text/x-python","patch_set":15,"id":"1aa78d24_44a35900","line":112,"updated":"2016-07-06 21:02:32.000000000","message":"how about some tests where mode is added, changed, removed? It would improve coverage report around lines 645-661 in versioned_writes.py","commit_id":"cbf077e522d9217ad235b93d6ccb15b3f76aba5b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f9b8e93494f64754a7f5b9a462c3bceb2e671fb0","unresolved":false,"context_lines":[{"line_number":109,"context_line":""},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"class VersionedWritesTestCase(VersionedWritesBaseTestCase):"},{"line_number":112,"context_line":"    def test_put_container(self):"},{"line_number":113,"context_line":"        self.app.register(\u0027PUT\u0027, \u0027/v1/a/c\u0027, swob.HTTPOk, {}, \u0027passed\u0027)"},{"line_number":114,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c\u0027,"},{"line_number":115,"context_line":"                            headers\u003d{\u0027X-Versions-Location\u0027: \u0027ver_cont\u0027},"}],"source_content_type":"text/x-python","patch_set":15,"id":"1aa78d24_9d55c6c3","line":112,"in_reply_to":"1aa78d24_44a35900","updated":"2016-07-11 21:28:58.000000000","message":"Done","commit_id":"cbf077e522d9217ad235b93d6ccb15b3f76aba5b"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"31bd7ad60a218920d1e1db9419cb18f02e2d1a5a","unresolved":false,"context_lines":[{"line_number":635,"context_line":"            \u0027\"content_type\": \"text/plain\"\u0027"},{"line_number":636,"context_line":"            \u0027}]\u0027)"},{"line_number":637,"context_line":"        self.app.register("},{"line_number":638,"context_line":"            \u0027HEAD\u0027, \u0027/v1/a/c/o\u0027, swob.HTTPNotFound, {}, \u0027passed\u0027)"},{"line_number":639,"context_line":"        self.app.register("},{"line_number":640,"context_line":"            \u0027GET\u0027, \u0027/v1/a/ver_cont/001o/1\u0027, swob.HTTPOk, {}, \u0027passed\u0027)"},{"line_number":641,"context_line":"        self.app.register("}],"source_content_type":"text/x-python","patch_set":15,"id":"1aa78d24_c0b45e36","line":638,"range":{"start_line":638,"start_character":33,"end_line":638,"end_character":50},"updated":"2016-07-06 21:02:32.000000000","message":"took me a while to understand the difference between this test and the one above, how about add a comment to make it clear what\u0027s being tested.","commit_id":"cbf077e522d9217ad235b93d6ccb15b3f76aba5b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f9b8e93494f64754a7f5b9a462c3bceb2e671fb0","unresolved":false,"context_lines":[{"line_number":635,"context_line":"            \u0027\"content_type\": \"text/plain\"\u0027"},{"line_number":636,"context_line":"            \u0027}]\u0027)"},{"line_number":637,"context_line":"        self.app.register("},{"line_number":638,"context_line":"            \u0027HEAD\u0027, \u0027/v1/a/c/o\u0027, swob.HTTPNotFound, {}, \u0027passed\u0027)"},{"line_number":639,"context_line":"        self.app.register("},{"line_number":640,"context_line":"            \u0027GET\u0027, \u0027/v1/a/ver_cont/001o/1\u0027, swob.HTTPOk, {}, \u0027passed\u0027)"},{"line_number":641,"context_line":"        self.app.register("}],"source_content_type":"text/x-python","patch_set":15,"id":"1aa78d24_f07b56bc","line":638,"range":{"start_line":638,"start_character":33,"end_line":638,"end_character":50},"in_reply_to":"1aa78d24_c0b45e36","updated":"2016-07-11 21:28:58.000000000","message":"I was hoping that the name would be a give-away :-(\n\nDone.","commit_id":"cbf077e522d9217ad235b93d6ccb15b3f76aba5b"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"4aa0704ed39b8d62f52568b4722fa1560bc89d41","unresolved":false,"context_lines":[{"line_number":668,"context_line":"        cache \u003d FakeCache({\u0027sysmeta\u0027: {\u0027versions-location\u0027: \u0027ver_cont\u0027}})"},{"line_number":669,"context_line":"        req \u003d Request.blank("},{"line_number":670,"context_line":"            \u0027/v1/a/c/o\u0027,"},{"line_number":671,"context_line":"            headers\u003d{\u0027X-If-Delete-At\u0027: 1},"},{"line_number":672,"context_line":"            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027DELETE\u0027, \u0027swift.cache\u0027: cache,"},{"line_number":673,"context_line":"                     \u0027CONTENT_LENGTH\u0027: \u00270\u0027})"},{"line_number":674,"context_line":"        status, headers, body \u003d self.call_vw(req)"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_78e19829","line":671,"updated":"2016-08-02 10:13:28.000000000","message":"So this means object-expirer call safe, right?\n\nHowever, it seems to need to insert versions_write to the internal client pipeline?\n\nIn default, it\u0027s not in the pipeline[1] and internal client doesn\u0027t modify the pipeline unless we add allow_modify_pipeline\u003dTrue explicitly. And also object-expirer doesn\u0027t.\n\nAm i missing something?\n\n\n1: https://github.com/openstack/swift/blob/master/etc/object-expirer.conf-sample#L56\n\n2: https://github.com/openstack/swift/blob/master/swift/common/internal_client.py#L142\n\n3: https://github.com/openstack/swift/blob/master/swift/obj/expirer.py#L56","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f3d9903a0825c5294d8e9a960be869b9e9f60b9b","unresolved":false,"context_lines":[{"line_number":668,"context_line":"        cache \u003d FakeCache({\u0027sysmeta\u0027: {\u0027versions-location\u0027: \u0027ver_cont\u0027}})"},{"line_number":669,"context_line":"        req \u003d Request.blank("},{"line_number":670,"context_line":"            \u0027/v1/a/c/o\u0027,"},{"line_number":671,"context_line":"            headers\u003d{\u0027X-If-Delete-At\u0027: 1},"},{"line_number":672,"context_line":"            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027DELETE\u0027, \u0027swift.cache\u0027: cache,"},{"line_number":673,"context_line":"                     \u0027CONTENT_LENGTH\u0027: \u00270\u0027})"},{"line_number":674,"context_line":"        status, headers, body \u003d self.call_vw(req)"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_924de074","line":671,"in_reply_to":"bacf61ea_78e19829","updated":"2016-08-04 00:26:58.000000000","message":"Honestly, I\u0027ve thought more about how object-expirer might interact with the *versions* container (in particular, how to prevent it from unbounded growth) than the *versioned* container. I\u0027ll look into it some more, but it sounds like you\u0027re right: expiring objects are directly deleted regardless of versioning mode.\n\nIt also sounds like a separate bug, though ;-)","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"f03a46505e16b599bf2ff5a5d6fd0f7316b3b43c","unresolved":false,"context_lines":[{"line_number":668,"context_line":"        cache \u003d FakeCache({\u0027sysmeta\u0027: {\u0027versions-location\u0027: \u0027ver_cont\u0027}})"},{"line_number":669,"context_line":"        req \u003d Request.blank("},{"line_number":670,"context_line":"            \u0027/v1/a/c/o\u0027,"},{"line_number":671,"context_line":"            headers\u003d{\u0027X-If-Delete-At\u0027: 1},"},{"line_number":672,"context_line":"            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027DELETE\u0027, \u0027swift.cache\u0027: cache,"},{"line_number":673,"context_line":"                     \u0027CONTENT_LENGTH\u0027: \u00270\u0027})"},{"line_number":674,"context_line":"        status, headers, body \u003d self.call_vw(req)"}],"source_content_type":"text/x-python","patch_set":17,"id":"bacf61ea_20ad73e9","line":671,"in_reply_to":"bacf61ea_924de074","updated":"2016-08-16 02:09:55.000000000","message":"Ok, we could issue it as another bug because as you suggested in the irc channel, it is not only for history mode but also stack mode. That is fair enough.","commit_id":"9ae296556dc1e7a8158bcebad203623156238a19"}]}
