From eae27412d233b6be5b1c2226a5d0ca380626f4ea Mon Sep 17 00:00:00 2001 From: Tim Burke Date: Fri, 17 Apr 2020 10:22:43 -0700 Subject: [PATCH] sharding: Don't inject shard ranges when user says quit When an operator does a `find_and_replace` on a DB that already has shard ranges, they get a prompt like: This will delete existing 58 shard ranges. Do you want to show the existing ranges [s], delete the existing ranges [yes] or quit without deleting [q]? Previously, if they selected `q`, we would skip the delete but still do the merge (!) and immediately warn about how there are now invalid shard ranges. Now, quit without merging. Change-Id: I7d869b137a6fbade59bb8ba16e4f3e9663e18822 --- swift/cli/manage_shard_ranges.py | 4 +++- test/unit/cli/test_manage_shard_ranges.py | 19 ++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/swift/cli/manage_shard_ranges.py b/swift/cli/manage_shard_ranges.py index 667304d573..e482e7f689 100644 --- a/swift/cli/manage_shard_ranges.py +++ b/swift/cli/manage_shard_ranges.py @@ -343,7 +343,9 @@ def _replace_shard_ranges(broker, args, shard_data, timeout=0): # Crank up the timeout in an effort to *make sure* this succeeds with broker.updated_timeout(max(timeout, args.replace_timeout)): - delete_shard_ranges(broker, args) + delete_status = delete_shard_ranges(broker, args) + if delete_status != 0: + return delete_status broker.merge_shard_ranges(shard_ranges) print('Injected %d shard ranges.' % len(shard_ranges)) diff --git a/test/unit/cli/test_manage_shard_ranges.py b/test/unit/cli/test_manage_shard_ranges.py index 11f6420e4c..65bcd0dd61 100644 --- a/test/unit/cli/test_manage_shard_ranges.py +++ b/test/unit/cli/test_manage_shard_ranges.py @@ -358,6 +358,23 @@ class TestManageShardRanges(unittest.TestCase): self.assertEqual(['Loaded db broker for a/c.'], err.getvalue().splitlines()) self._assert_enabled(broker, now) + found_shard_ranges = broker.get_shard_ranges() self.assertEqual( [(data['lower'], data['upper']) for data in self.shard_data], - [(sr.lower_str, sr.upper_str) for sr in broker.get_shard_ranges()]) + [(sr.lower_str, sr.upper_str) for sr in found_shard_ranges]) + + # Do another find & replace but quit when prompted about existing + # shard ranges + out = StringIO() + err = StringIO() + to_patch = 'swift.cli.manage_shard_ranges.input' + with mock.patch('sys.stdout', out), mock.patch('sys.stderr', err), \ + mock_timestamp_now() as now, \ + mock.patch(to_patch, return_value='q'): + main([broker.db_file, 'find_and_replace', '10']) + # Shard ranges haven't changed at all + self.assertEqual(found_shard_ranges, broker.get_shard_ranges()) + expected = ['This will delete existing 10 shard ranges.'] + self.assertEqual(expected, out.getvalue().splitlines()) + self.assertEqual(['Loaded db broker for a/c.'], + err.getvalue().splitlines())