Fix db init notifications
Ensures that leader does not respond to db init
notifications to avoid infitinite looping after
leader switches to a different unit.
Also ensures that leader only restarts its neutron-server
once on db init.
Closes-Bug: #1893008
Change-Id: I59b9d5e0caab62b72380879bf16cb0fd8703bb32
(cherry picked from commit 104626a19f
)
This commit is contained in:
parent
ac01ce1509
commit
e7c233c846
|
@ -53,6 +53,7 @@ from charmhelpers.core.hookenv import (
|
||||||
relation_get,
|
relation_get,
|
||||||
relation_set,
|
relation_set,
|
||||||
local_unit,
|
local_unit,
|
||||||
|
is_leader,
|
||||||
)
|
)
|
||||||
|
|
||||||
from charmhelpers.fetch import (
|
from charmhelpers.fetch import (
|
||||||
|
@ -295,7 +296,8 @@ def check_local_db_actions_complete():
|
||||||
|
|
||||||
NOTE: this must only be called from peer relation context.
|
NOTE: this must only be called from peer relation context.
|
||||||
"""
|
"""
|
||||||
if not is_db_initialised():
|
# leader must not respond to notifications
|
||||||
|
if is_leader() or not is_db_initialised():
|
||||||
return
|
return
|
||||||
|
|
||||||
settings = relation_get() or {}
|
settings = relation_get() or {}
|
||||||
|
@ -314,8 +316,10 @@ def check_local_db_actions_complete():
|
||||||
"initialisation", level=DEBUG)
|
"initialisation", level=DEBUG)
|
||||||
service_restart('neutron-server')
|
service_restart('neutron-server')
|
||||||
|
|
||||||
# Echo notification
|
# Echo notification and ensure init key unset since we are not
|
||||||
relation_set(**{NEUTRON_DB_INIT_ECHO_RKEY: init_id})
|
# leader anymore.
|
||||||
|
relation_set(**{NEUTRON_DB_INIT_ECHO_RKEY: init_id,
|
||||||
|
NEUTRON_DB_INIT_RKEY: None})
|
||||||
|
|
||||||
|
|
||||||
def api_port(service):
|
def api_port(service):
|
||||||
|
@ -789,19 +793,23 @@ def migrate_neutron_database(upgrade=False):
|
||||||
'head']
|
'head']
|
||||||
subprocess.check_output(cmd)
|
subprocess.check_output(cmd)
|
||||||
|
|
||||||
|
if not is_unit_paused_set():
|
||||||
|
log("Restarting neutron-server following database migration",
|
||||||
|
level=DEBUG)
|
||||||
|
service_restart('neutron-server')
|
||||||
|
|
||||||
cluster_rids = relation_ids('cluster')
|
cluster_rids = relation_ids('cluster')
|
||||||
if cluster_rids:
|
if cluster_rids:
|
||||||
# Notify peers so that services get restarted
|
# Notify peers so that services get restarted
|
||||||
log("Notifying peer(s) that db is initialised and restarting services",
|
log("Notifying peer(s) that db is initialised and restarting services",
|
||||||
level=DEBUG)
|
level=DEBUG)
|
||||||
|
# Use the same uuid for all notifications in this cycle to make
|
||||||
|
# them easier to identify.
|
||||||
|
n_id = uuid.uuid4()
|
||||||
for r_id in cluster_rids:
|
for r_id in cluster_rids:
|
||||||
if not is_unit_paused_set():
|
# Notify peers that they should also restart their services
|
||||||
service_restart('neutron-server')
|
|
||||||
|
|
||||||
# Notify peers that tey should also restart their services
|
|
||||||
shared_db_rel_id = (relation_ids('shared-db') or [None])[0]
|
shared_db_rel_id = (relation_ids('shared-db') or [None])[0]
|
||||||
id = "{}-{}-{}".format(local_unit(), shared_db_rel_id,
|
id = "{}-{}-{}".format(local_unit(), shared_db_rel_id, n_id)
|
||||||
uuid.uuid4())
|
|
||||||
relation_set(relation_id=r_id, **{NEUTRON_DB_INIT_RKEY: id})
|
relation_set(relation_id=r_id, **{NEUTRON_DB_INIT_RKEY: id})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -655,31 +655,37 @@ class TestNeutronAPIUtils(CharmTestCase):
|
||||||
'icehouse']
|
'icehouse']
|
||||||
self.subprocess.check_output.assert_called_with(cmd)
|
self.subprocess.check_output.assert_called_with(cmd)
|
||||||
|
|
||||||
|
@patch.object(nutils, 'relation_ids')
|
||||||
@patch.object(nutils, 'relation_set')
|
@patch.object(nutils, 'relation_set')
|
||||||
@patch.object(nutils, 'is_db_initialised', lambda: False)
|
|
||||||
@patch.object(nutils, 'relation_get')
|
@patch.object(nutils, 'relation_get')
|
||||||
|
@patch.object(nutils, 'is_leader')
|
||||||
|
@patch.object(nutils, 'is_db_initialised')
|
||||||
@patch.object(nutils, 'local_unit', lambda *args: 'unit/0')
|
@patch.object(nutils, 'local_unit', lambda *args: 'unit/0')
|
||||||
def test_check_local_db_actions_complete_by_self(self, mock_relation_get,
|
def test_check_local_db_actions_complete_leader(self,
|
||||||
mock_relation_set):
|
mock_is_db_initialised,
|
||||||
mock_relation_get.return_value = {}
|
mock_is_leader,
|
||||||
|
mock_relation_get,
|
||||||
|
mock_relation_set,
|
||||||
|
mock_relation_ids):
|
||||||
|
mock_is_leader.return_value = True
|
||||||
nutils.check_local_db_actions_complete()
|
nutils.check_local_db_actions_complete()
|
||||||
self.assertFalse(mock_relation_set.called)
|
mock_relation_get.assert_not_called()
|
||||||
|
mock_relation_set.assert_not_called()
|
||||||
mock_relation_get.return_value = {nutils.NEUTRON_DB_INIT_RKEY:
|
self.service_restart.assert_not_called()
|
||||||
'unit/0-1234'}
|
|
||||||
nutils.check_local_db_actions_complete()
|
|
||||||
self.assertFalse(mock_relation_set.called)
|
|
||||||
|
|
||||||
@patch.object(nutils, 'relation_ids')
|
@patch.object(nutils, 'relation_ids')
|
||||||
@patch.object(nutils, 'relation_set')
|
@patch.object(nutils, 'relation_set')
|
||||||
@patch.object(nutils, 'relation_get')
|
@patch.object(nutils, 'relation_get')
|
||||||
|
@patch.object(nutils, 'is_leader')
|
||||||
@patch.object(nutils, 'is_db_initialised')
|
@patch.object(nutils, 'is_db_initialised')
|
||||||
@patch.object(nutils, 'local_unit', lambda *args: 'unit/0')
|
@patch.object(nutils, 'local_unit', lambda *args: 'unit/0')
|
||||||
def test_check_local_db_actions_complete(self,
|
def test_check_local_db_actions_complete_non_leader(self,
|
||||||
mock_is_db_initialised,
|
mock_is_db_initialised,
|
||||||
mock_relation_get,
|
mock_is_leader,
|
||||||
mock_relation_set,
|
mock_relation_get,
|
||||||
mock_relation_ids):
|
mock_relation_set,
|
||||||
|
mock_relation_ids):
|
||||||
|
mock_is_leader.return_value = False
|
||||||
shared_db_rel_id = 'shared-db:1'
|
shared_db_rel_id = 'shared-db:1'
|
||||||
mock_relation_ids.return_value = [shared_db_rel_id]
|
mock_relation_ids.return_value = [shared_db_rel_id]
|
||||||
mock_is_db_initialised.return_value = True
|
mock_is_db_initialised.return_value = True
|
||||||
|
@ -697,7 +703,8 @@ class TestNeutronAPIUtils(CharmTestCase):
|
||||||
init_db_val = 'unit/1-{}-1234'.format(shared_db_rel_id)
|
init_db_val = 'unit/1-{}-1234'.format(shared_db_rel_id)
|
||||||
r_settings = {nutils.NEUTRON_DB_INIT_RKEY: init_db_val}
|
r_settings = {nutils.NEUTRON_DB_INIT_RKEY: init_db_val}
|
||||||
nutils.check_local_db_actions_complete()
|
nutils.check_local_db_actions_complete()
|
||||||
calls = [call(**{nutils.NEUTRON_DB_INIT_ECHO_RKEY: init_db_val})]
|
calls = [call(**{nutils.NEUTRON_DB_INIT_ECHO_RKEY: init_db_val,
|
||||||
|
nutils.NEUTRON_DB_INIT_RKEY: None})]
|
||||||
mock_relation_set.assert_has_calls(calls)
|
mock_relation_set.assert_has_calls(calls)
|
||||||
self.service_restart.assert_called_with('neutron-server')
|
self.service_restart.assert_called_with('neutron-server')
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue