)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d327a6879a36ac6630d322b0e00a80ba932b21ac","unresolved":true,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Adds a subcommand to swift-manage-shard-ranges that allows arbitrary"},{"line_number":10,"context_line":"shard ranges to be read from a file and merge into a container DB. The"},{"line_number":11,"context_line":"file should be a JSON serialized list of dicts."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Change-Id: Ic9ffcc042399f3834027a7935b64292d1fffe8d5"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"0a190b73_6fd26b82","line":11,"updated":"2022-08-15 05:12:40.000000000","message":"Seems like a nice, powerful new tool -- I could see this being useful for manually repairing overlaps or gaps, say, or shifting some shard-range bounds.\n\nDo we have a sense (yet) for how to use it safely? Any runbooks we could offer for various operations, ideally with known/expected pitfalls and limitations?\n\nI suppose the idea is that we\u0027ll mostly be using this when things are sufficiently far off the rails that we\u0027re not going to be too worried about some temporary listing gaps, say...","commit_id":"6b6a7695e471a79e5021d855fd952d30a008d2b8"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8921f65d8d3fe4d1f0dc6dad2bbf154887121b21","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"ead7e2a7_452c19b0","updated":"2022-08-08 15:13:48.000000000","message":"it seems like a bit of a foot-gun, but used surgically it should be a very versatile tool","commit_id":"6b6a7695e471a79e5021d855fd952d30a008d2b8"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"ff26c20920df8291b637c3258c4fe81c990be06d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"432ef12e_c61e952d","updated":"2022-08-29 09:30:39.000000000","message":"Added a follow up to address what I was saying. Feel free to squash it in. https://review.opendev.org/c/openstack/swift/+/854976 ","commit_id":"854bd5f051d442b4e65fdb99fb6382f7a9da78d1"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"788259294b232fc722a912fc1adc1b8202615546","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"4ff01cbd_6fbe88dd","updated":"2022-08-29 04:16:19.000000000","message":"the _sift_shard_ranges is actaully a refactor from merge_shard_ranges in the other patch this is pulled from. Rather then redefining this, I feel we should at least do the refactor then full _sift from backend, as that makes sense.","commit_id":"854bd5f051d442b4e65fdb99fb6382f7a9da78d1"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"9802c6d6a11557a413eb82ba8c869c0ff8d05173","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"c95b6a73_1284fa15","updated":"2022-09-09 04:37:33.000000000","message":"I think we can merge this one.","commit_id":"d2edf6646d670597b247ec3cf57b824a8469fa00"}],"swift/cli/manage_shard_ranges.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8921f65d8d3fe4d1f0dc6dad2bbf154887121b21","unresolved":true,"context_lines":[{"line_number":411,"context_line":"    shard_data \u003d _load_and_validate_shard_data(args, require_index\u003dFalse)"},{"line_number":412,"context_line":"    shard_ranges \u003d [ShardRange.from_dict(sr) for sr in shard_data]"},{"line_number":413,"context_line":"    with broker.updated_timeout(args.replace_timeout):"},{"line_number":414,"context_line":"        broker.merge_shard_ranges(shard_ranges)"},{"line_number":415,"context_line":"    print(\u0027Injected %d shard ranges.\u0027 % len(shard_ranges))"},{"line_number":416,"context_line":"    print(\u0027Run container-replicator to replicate them to other nodes.\u0027)"},{"line_number":417,"context_line":"    return EXIT_SUCCESS"}],"source_content_type":"text/x-python","patch_set":1,"id":"7a47ad45_e917ee46","line":414,"updated":"2022-08-08 15:13:48.000000000","message":"maybe before we do this try to provide some sort of warning/confirmation of what\u0027s changing?","commit_id":"6b6a7695e471a79e5021d855fd952d30a008d2b8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"50f60fccf1488b27f1853f7cbe99830fadc5c49e","unresolved":true,"context_lines":[{"line_number":411,"context_line":"    shard_data \u003d _load_and_validate_shard_data(args, require_index\u003dFalse)"},{"line_number":412,"context_line":"    shard_ranges \u003d [ShardRange.from_dict(sr) for sr in shard_data]"},{"line_number":413,"context_line":"    with broker.updated_timeout(args.replace_timeout):"},{"line_number":414,"context_line":"        broker.merge_shard_ranges(shard_ranges)"},{"line_number":415,"context_line":"    print(\u0027Injected %d shard ranges.\u0027 % len(shard_ranges))"},{"line_number":416,"context_line":"    print(\u0027Run container-replicator to replicate them to other nodes.\u0027)"},{"line_number":417,"context_line":"    return EXIT_SUCCESS"}],"source_content_type":"text/x-python","patch_set":1,"id":"7e259beb_42ee5b2d","line":414,"in_reply_to":"5ef2f917_8948d95b","updated":"2022-08-19 14:45:30.000000000","message":"Added some checks and \"here\u0027s the outcome\" but nothing as fancy as a diff. Also added dry run and user prompting to confirm.","commit_id":"6b6a7695e471a79e5021d855fd952d30a008d2b8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d327a6879a36ac6630d322b0e00a80ba932b21ac","unresolved":true,"context_lines":[{"line_number":411,"context_line":"    shard_data \u003d _load_and_validate_shard_data(args, require_index\u003dFalse)"},{"line_number":412,"context_line":"    shard_ranges \u003d [ShardRange.from_dict(sr) for sr in shard_data]"},{"line_number":413,"context_line":"    with broker.updated_timeout(args.replace_timeout):"},{"line_number":414,"context_line":"        broker.merge_shard_ranges(shard_ranges)"},{"line_number":415,"context_line":"    print(\u0027Injected %d shard ranges.\u0027 % len(shard_ranges))"},{"line_number":416,"context_line":"    print(\u0027Run container-replicator to replicate them to other nodes.\u0027)"},{"line_number":417,"context_line":"    return EXIT_SUCCESS"}],"source_content_type":"text/x-python","patch_set":1,"id":"5ef2f917_8948d95b","line":414,"in_reply_to":"7a47ad45_e917ee46","updated":"2022-08-15 05:12:40.000000000","message":"I\u0027m not sure it\u0027s always going to be super-obvious what\u0027s changing :-/ I guess we go looking at each shard range name and see what changed for it? Makes me want to investigate https://docs.python.org/3/library/difflib.html a little...\n\nI could also see it being nice to add something like \"here are the warnings from the before-state shard ranges, compared to these warnings from the after-state.\"","commit_id":"6b6a7695e471a79e5021d855fd952d30a008d2b8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f2614fe0b6ba97da3fb0dc127188f35ed0c1141f","unresolved":false,"context_lines":[{"line_number":411,"context_line":"    shard_data \u003d _load_and_validate_shard_data(args, require_index\u003dFalse)"},{"line_number":412,"context_line":"    shard_ranges \u003d [ShardRange.from_dict(sr) for sr in shard_data]"},{"line_number":413,"context_line":"    with broker.updated_timeout(args.replace_timeout):"},{"line_number":414,"context_line":"        broker.merge_shard_ranges(shard_ranges)"},{"line_number":415,"context_line":"    print(\u0027Injected %d shard ranges.\u0027 % len(shard_ranges))"},{"line_number":416,"context_line":"    print(\u0027Run container-replicator to replicate them to other nodes.\u0027)"},{"line_number":417,"context_line":"    return EXIT_SUCCESS"}],"source_content_type":"text/x-python","patch_set":1,"id":"09731934_5b46af0d","line":414,"in_reply_to":"7e259beb_42ee5b2d","updated":"2022-08-30 12:01:52.000000000","message":"Done","commit_id":"6b6a7695e471a79e5021d855fd952d30a008d2b8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d327a6879a36ac6630d322b0e00a80ba932b21ac","unresolved":true,"context_lines":[{"line_number":919,"context_line":"    # merge"},{"line_number":920,"context_line":"    merge_parser \u003d subparsers.add_parser("},{"line_number":921,"context_line":"        \u0027merge\u0027,"},{"line_number":922,"context_line":"        help\u003d\u0027Merge shard range from file with existing shard ranges.\u0027)"},{"line_number":923,"context_line":"    merge_parser.add_argument(\u0027input\u0027, metavar\u003d\u0027input_file\u0027,"},{"line_number":924,"context_line":"                              type\u003dstr, help\u003d\u0027Name of file\u0027)"},{"line_number":925,"context_line":"    merge_parser.add_argument("}],"source_content_type":"text/x-python","patch_set":1,"id":"4ed7a751_42846990","line":922,"range":{"start_line":922,"start_character":42,"end_line":922,"end_character":68},"updated":"2022-08-15 05:12:40.000000000","message":"Yeah, seems clear enough that if you want to use this to replace what\u0027s there, you need to manage the deletes yourself.","commit_id":"6b6a7695e471a79e5021d855fd952d30a008d2b8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f2614fe0b6ba97da3fb0dc127188f35ed0c1141f","unresolved":false,"context_lines":[{"line_number":919,"context_line":"    # merge"},{"line_number":920,"context_line":"    merge_parser \u003d subparsers.add_parser("},{"line_number":921,"context_line":"        \u0027merge\u0027,"},{"line_number":922,"context_line":"        help\u003d\u0027Merge shard range from file with existing shard ranges.\u0027)"},{"line_number":923,"context_line":"    merge_parser.add_argument(\u0027input\u0027, metavar\u003d\u0027input_file\u0027,"},{"line_number":924,"context_line":"                              type\u003dstr, help\u003d\u0027Name of file\u0027)"},{"line_number":925,"context_line":"    merge_parser.add_argument("}],"source_content_type":"text/x-python","patch_set":1,"id":"59061948_6976ab69","line":922,"range":{"start_line":922,"start_character":42,"end_line":922,"end_character":68},"in_reply_to":"4ed7a751_42846990","updated":"2022-08-30 12:01:52.000000000","message":"Done","commit_id":"6b6a7695e471a79e5021d855fd952d30a008d2b8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1d203ae098789b2fa5227cdaa440ba7b947d2ce2","unresolved":true,"context_lines":[{"line_number":435,"context_line":"    result.extend([ShardRange.from_dict(sr) for sr in to_add])"},{"line_number":436,"context_line":"    return sorted([sr for sr in result if not sr.deleted],"},{"line_number":437,"context_line":"                  key\u003dShardRange.sort_key)"},{"line_number":438,"context_line":""},{"line_number":439,"context_line":""},{"line_number":440,"context_line":"def merge_shard_ranges(broker, args):"},{"line_number":441,"context_line":"    _check_own_shard_range(broker, args)"}],"source_content_type":"text/x-python","patch_set":2,"id":"adf4b05f_1389cf82","line":438,"updated":"2022-08-19 14:47:19.000000000","message":"I lifted these methods from here https://review.opendev.org/c/openstack/swift/+/852905/2/swift/container/backend.py\n\nI want to keep this as a single file patch for now","commit_id":"0683d7bb462251791e0893d6266f88a1dd137555"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f2614fe0b6ba97da3fb0dc127188f35ed0c1141f","unresolved":false,"context_lines":[{"line_number":435,"context_line":"    result.extend([ShardRange.from_dict(sr) for sr in to_add])"},{"line_number":436,"context_line":"    return sorted([sr for sr in result if not sr.deleted],"},{"line_number":437,"context_line":"                  key\u003dShardRange.sort_key)"},{"line_number":438,"context_line":""},{"line_number":439,"context_line":""},{"line_number":440,"context_line":"def merge_shard_ranges(broker, args):"},{"line_number":441,"context_line":"    _check_own_shard_range(broker, args)"}],"source_content_type":"text/x-python","patch_set":2,"id":"87f8b734_28fb03f5","line":438,"in_reply_to":"adf4b05f_1389cf82","updated":"2022-08-30 12:01:52.000000000","message":"Done","commit_id":"0683d7bb462251791e0893d6266f88a1dd137555"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"788259294b232fc722a912fc1adc1b8202615546","unresolved":true,"context_lines":[{"line_number":441,"context_line":"            if (item_ident not in to_add or"},{"line_number":442,"context_line":"                    merge_shards(item, to_add[item_ident])):"},{"line_number":443,"context_line":"                to_add[item_ident] \u003d item"},{"line_number":444,"context_line":"    return to_add.values(), to_delete"},{"line_number":445,"context_line":""},{"line_number":446,"context_line":""},{"line_number":447,"context_line":"def combine_shard_ranges(new_shard_ranges, existing_shard_ranges):"}],"source_content_type":"text/x-python","patch_set":4,"id":"b0327469_0bf9eff8","line":444,"updated":"2022-08-29 04:16:19.000000000","message":"This is actually as pulled directly out of container/backend.py merge_shard_ranges, where it also refactors this out of merge_shard_ranges and into _sift_shard_ranges.\n\nSo if we\u0027re going to land this, I\u0027d rather pull _sift_shard_ranges from container/backend.py and at least do that refactor, so we\u0027re only defining this once.\n\nCombine_shard_ranges below can be defined here for now, and moved to the backend.py when the other patch comes into being, that\u0027s not a blocker to me.","commit_id":"854bd5f051d442b4e65fdb99fb6382f7a9da78d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f2614fe0b6ba97da3fb0dc127188f35ed0c1141f","unresolved":false,"context_lines":[{"line_number":441,"context_line":"            if (item_ident not in to_add or"},{"line_number":442,"context_line":"                    merge_shards(item, to_add[item_ident])):"},{"line_number":443,"context_line":"                to_add[item_ident] \u003d item"},{"line_number":444,"context_line":"    return to_add.values(), to_delete"},{"line_number":445,"context_line":""},{"line_number":446,"context_line":""},{"line_number":447,"context_line":"def combine_shard_ranges(new_shard_ranges, existing_shard_ranges):"}],"source_content_type":"text/x-python","patch_set":4,"id":"8b72ab6c_d48ad9ef","line":444,"in_reply_to":"b0327469_0bf9eff8","updated":"2022-08-30 12:01:52.000000000","message":"Done","commit_id":"854bd5f051d442b4e65fdb99fb6382f7a9da78d1"}]}
