From e343452394780b1f555777bc7083912ac68633d3 Mon Sep 17 00:00:00 2001 From: Tim Burke Date: Mon, 8 Jan 2018 20:02:50 +0000 Subject: [PATCH] Support existing builders with None _last_part_moves These were likely written before the first related change, or created from an existing ring file. Also, tolerate missing dispersion when rebalancing -- that may not exist in the builder file. Change-Id: I26e3b4429c747c23206e4671f7c86543bb182a15 Related-Change: Ib165cf974c865d47c2d9e8f7b3641971d2e9f404 Related-Change: Ie239b958fc7e0547ffda2bebf61546bd4ef3d829 Related-Change: I551fcaf274876861feb12848749590f220842d68 --- swift/cli/ringbuilder.py | 3 ++- swift/common/ring/builder.py | 12 ++++++++++-- test/unit/cli/test_ringbuilder.py | 8 ++++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/swift/cli/ringbuilder.py b/swift/cli/ringbuilder.py index eaddb7b0d3..6498c8d1b5 100644 --- a/swift/cli/ringbuilder.py +++ b/swift/cli/ringbuilder.py @@ -945,7 +945,8 @@ swift-ring-builder rebalance [options] balance_changed = ( abs(last_balance - balance) >= 1 or (last_balance == MAX_BALANCE and balance == MAX_BALANCE)) - dispersion_changed = abs(last_dispersion - dispersion) >= 1 + dispersion_changed = last_dispersion is None or ( + abs(last_dispersion - dispersion) >= 1) if balance_changed or dispersion_changed: be_cowardly = False diff --git a/swift/common/ring/builder.py b/swift/common/ring/builder.py index 717dd753a6..0881bad216 100644 --- a/swift/common/ring/builder.py +++ b/swift/common/ring/builder.py @@ -247,7 +247,11 @@ class RingBuilder(object): self.version = builder.version self._replica2part2dev = builder._replica2part2dev self._last_part_moves_epoch = builder._last_part_moves_epoch - self._last_part_moves = builder._last_part_moves + if builder._last_part_moves is None: + self._last_part_moves = array( + 'B', itertools.repeat(0, self.parts)) + else: + self._last_part_moves = builder._last_part_moves self._last_part_gather_start = builder._last_part_gather_start self._remove_devs = builder._remove_devs self._id = getattr(builder, '_id', None) @@ -263,7 +267,11 @@ class RingBuilder(object): self.version = builder['version'] self._replica2part2dev = builder['_replica2part2dev'] self._last_part_moves_epoch = builder['_last_part_moves_epoch'] - self._last_part_moves = builder['_last_part_moves'] + if builder['_last_part_moves'] is None: + self._last_part_moves = array( + 'B', itertools.repeat(0, self.parts)) + else: + self._last_part_moves = builder['_last_part_moves'] self._last_part_gather_start = builder['_last_part_gather_start'] self._dispersion_graph = builder.get('_dispersion_graph', {}) self.dispersion = builder.get('dispersion') diff --git a/test/unit/cli/test_ringbuilder.py b/test/unit/cli/test_ringbuilder.py index 628a9a9a62..7bae4f1b95 100644 --- a/test/unit/cli/test_ringbuilder.py +++ b/test/unit/cli/test_ringbuilder.py @@ -2202,6 +2202,14 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin): argv = ["", backup_file, "write_builder", "24"] self.assertIsNone(ringbuilder.main(argv)) + rb = RingBuilder.load(self.tmpfile + '.builder') + self.assertIsNotNone(rb._last_part_moves) + rb._last_part_moves = None + rb.save(self.tmpfile) + + argv = ["", self.tmpfile + '.builder', "rebalance"] + self.assertSystemExit(EXIT_WARNING, ringbuilder.main, argv) + def test_warn_at_risk(self): # check that warning is generated when rebalance does not achieve # satisfactory balance