[hopem,r=gnuoy]
Provide min-cluster-size config option to get round clustering races until we have leadership election support in Juju. Also ensure that cookie is only distributed by the leader.
This commit is contained in:
commit
c499ab55cb
@ -166,3 +166,9 @@ options:
|
||||
order for this charm to function correctly, the privacy extension must be
|
||||
disabled and a non-temporary address must be configured/available on
|
||||
your network interface.
|
||||
min-cluster-size:
|
||||
type: int
|
||||
default:
|
||||
description: |
|
||||
Minimum number of units expected to exist before charm will attempt to
|
||||
form a rabbitmq cluster.
|
||||
|
@ -194,6 +194,26 @@ def amqp_changed(relation_id=None, remote_unit=None):
|
||||
relation_settings=relation_settings)
|
||||
|
||||
|
||||
def is_sufficient_peers():
|
||||
"""If min-cluster-size has been provided, check that we have sufficient
|
||||
number of peers to proceed with creating rabbitmq cluster.
|
||||
"""
|
||||
min_size = config('min-cluster-size')
|
||||
if min_size:
|
||||
size = 0
|
||||
for rid in relation_ids('cluster'):
|
||||
size = len(related_units(rid))
|
||||
|
||||
# Include this unit
|
||||
size += 1
|
||||
if min_size > size:
|
||||
log("Insufficient number of peer units to form cluster "
|
||||
"(expected=%s, got=%s)" % (min_size, size), level=INFO)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@hooks.hook('cluster-relation-joined')
|
||||
def cluster_joined(relation_id=None):
|
||||
if config('prefer-ipv6'):
|
||||
@ -240,6 +260,11 @@ def cluster_joined(relation_id=None):
|
||||
log('erlang cookie missing from %s' % rabbit.COOKIE_PATH,
|
||||
level=ERROR)
|
||||
return
|
||||
|
||||
if not is_sufficient_peers():
|
||||
return
|
||||
|
||||
if is_elected_leader('res_rabbitmq_vip'):
|
||||
cookie = open(rabbit.COOKIE_PATH, 'r').read().strip()
|
||||
peer_store('cookie', cookie)
|
||||
|
||||
@ -262,6 +287,11 @@ def cluster_changed():
|
||||
whitelist = [a for a in rdata.keys() if a not in blacklist]
|
||||
peer_echo(includes=whitelist)
|
||||
|
||||
if not is_sufficient_peers():
|
||||
# Stop rabbit until leader has finished configuring
|
||||
service_stop('rabbitmq-server')
|
||||
return
|
||||
|
||||
# sync the cookie with peers if necessary
|
||||
update_cookie()
|
||||
|
||||
@ -276,6 +306,7 @@ def cluster_changed():
|
||||
if rabbit.cluster_with():
|
||||
# resync nrpe user after clustering
|
||||
update_nrpe_checks()
|
||||
|
||||
# If cluster has changed peer db may have changed so run amqp_changed
|
||||
# to sync any changes
|
||||
for rid in relation_ids('amqp'):
|
||||
|
@ -129,3 +129,20 @@ class RelationUtil(TestCase):
|
||||
mock_peer_store_and_set.assert_called_with(
|
||||
relation_settings={'private-address': ipv6_addr},
|
||||
relation_id=None)
|
||||
|
||||
@patch.object(rabbitmq_server_relations, 'related_units')
|
||||
@patch.object(rabbitmq_server_relations, 'relation_ids')
|
||||
@patch.object(rabbitmq_server_relations, 'config')
|
||||
def test_is_sufficient_peers(self, mock_config, mock_relation_ids,
|
||||
mock_related_units):
|
||||
_config = {'min-cluster-size': None}
|
||||
mock_config.side_effect = lambda key: _config.get(key)
|
||||
self.assertTrue(rabbitmq_server_relations.is_sufficient_peers())
|
||||
|
||||
mock_relation_ids.return_value = ['cluster:0']
|
||||
mock_related_units.return_value = ['test/0']
|
||||
_config = {'min-cluster-size': 3}
|
||||
self.assertFalse(rabbitmq_server_relations.is_sufficient_peers())
|
||||
|
||||
mock_related_units.return_value = ['test/0', 'test/1']
|
||||
self.assertTrue(rabbitmq_server_relations.is_sufficient_peers())
|
||||
|
Loading…
Reference in New Issue
Block a user