Create a node for each device. Fixes LP Bug#1479938

This commit is contained in:
David Ames
2015-10-12 15:02:35 -07:00
parent c5428de52b
commit d661ff39cf
3 changed files with 25 additions and 22 deletions

View File

@@ -228,11 +228,15 @@ def storage_changed():
# Allow for multiple devs per unit, passed along as a : separated list # Allow for multiple devs per unit, passed along as a : separated list
# Update and balance rings. # Update and balance rings.
nodes = []
devs = relation_get('device') devs = relation_get('device')
if devs: if devs:
node_settings['devices'] = devs.split(':') for dev in devs.split(':'):
node = {k: v for k, v in node_settings.items()}
node['device'] = dev
nodes.append(node)
update_rings(node_settings) update_rings(nodes)
if not is_paused(): if not is_paused():
# Restart proxy here in case no config changes made (so # Restart proxy here in case no config changes made (so
# pause_aware_restart_on_change() ineffective). # pause_aware_restart_on_change() ineffective).

View File

@@ -402,18 +402,13 @@ def initialize_ring(path, part_power, replicas, min_hours):
_write_ring(ring, path) _write_ring(ring, path)
def exists_in_ring(ring_path, node, blockdev): def exists_in_ring(ring_path, node):
ring = _load_builder(ring_path).to_dict() ring = _load_builder(ring_path).to_dict()
node['port'] = ring_port(ring_path, node) node['port'] = ring_port(ring_path, node)
# Make a nodecopy dict, to add a 'device' key for the purpose
# of below comparison, as it doesn't have a single-valued 'device'
# but a list as e.g. 'devices': ['sdb', 'sdc', ...]
nodecopy = {k: v for k, v in node.items()}
nodecopy['device'] = blockdev
for dev in ring['devs']: for dev in ring['devs']:
d = [(i, dev[i]) for i in dev if i in nodecopy and i != 'zone'] d = [(i, dev[i]) for i in dev if i in node and i != 'zone']
n = [(i, nodecopy[i]) for i in nodecopy if i in dev and i != 'zone'] n = [(i, node[i]) for i in node if i in dev and i != 'zone']
if sorted(d) == sorted(n): if sorted(d) == sorted(n):
log('Node already exists in ring (%s).' % ring_path, level=INFO) log('Node already exists in ring (%s).' % ring_path, level=INFO)
@@ -422,7 +417,7 @@ def exists_in_ring(ring_path, node, blockdev):
return False return False
def add_to_ring(ring_path, node, device): def add_to_ring(ring_path, node):
ring = _load_builder(ring_path) ring = _load_builder(ring_path)
port = ring_port(ring_path, node) port = ring_port(ring_path, node)
@@ -436,7 +431,7 @@ def add_to_ring(ring_path, node, device):
'zone': node['zone'], 'zone': node['zone'],
'ip': node['ip'], 'ip': node['ip'],
'port': port, 'port': port,
'device': device, 'device': node['device'],
'weight': 100, 'weight': 100,
'meta': '', 'meta': '',
} }
@@ -787,7 +782,7 @@ def sync_builders_and_rings_if_changed(f):
@sync_builders_and_rings_if_changed @sync_builders_and_rings_if_changed
def update_rings(node_settings=None, min_part_hours=None): def update_rings(nodes=[], min_part_hours=None):
"""Update builder with node settings and balance rings if necessary. """Update builder with node settings and balance rings if necessary.
Also update min_part_hours if provided. Also update min_part_hours if provided.
@@ -819,11 +814,10 @@ def update_rings(node_settings=None, min_part_hours=None):
else: else:
balance_required = True balance_required = True
if node_settings: for node in nodes:
for blockdev in node_settings.get('devices', []):
for ring in SWIFT_RINGS.itervalues(): for ring in SWIFT_RINGS.itervalues():
if not exists_in_ring(ring, node_settings, blockdev): if not exists_in_ring(ring, node):
add_to_ring(ring, node_settings, blockdev) add_to_ring(ring, node)
balance_required = True balance_required = True
if balance_required: if balance_required:

View File

@@ -129,13 +129,18 @@ class SwiftUtilsTestCase(unittest.TestCase):
'account_port': 6002, 'account_port': 6002,
'zone': 1, 'zone': 1,
'ip': '1.2.3.4', 'ip': '1.2.3.4',
'devices': devices
} }
for path in swift_utils.SWIFT_RINGS.itervalues(): for path in swift_utils.SWIFT_RINGS.itervalues():
swift_utils.initialize_ring(path, 8, 3, 0) swift_utils.initialize_ring(path, 8, 3, 0)
# verify all devices added to each ring # verify all devices added to each ring
swift_utils.update_rings(node_settings) nodes = []
for dev in devices:
node = {k: v for k, v in node_settings.items()}
node['device'] = dev
nodes.append(node)
swift_utils.update_rings(nodes)
for path in swift_utils.SWIFT_RINGS.itervalues(): for path in swift_utils.SWIFT_RINGS.itervalues():
devs = swift_utils._load_builder(path).to_dict()['devs'] devs = swift_utils._load_builder(path).to_dict()['devs']
added_devices = [dev['device'] for dev in devs] added_devices = [dev['device'] for dev in devs]
@@ -143,7 +148,7 @@ class SwiftUtilsTestCase(unittest.TestCase):
# try re-adding, assert add_to_ring was not called # try re-adding, assert add_to_ring was not called
with mock.patch('swift_utils.add_to_ring') as mock_add_to_ring: with mock.patch('swift_utils.add_to_ring') as mock_add_to_ring:
swift_utils.update_rings(node_settings) swift_utils.update_rings(nodes)
self.assertFalse(mock_add_to_ring.called) self.assertFalse(mock_add_to_ring.called)
@mock.patch('lib.swift_utils.get_broker_token') @mock.patch('lib.swift_utils.get_broker_token')