Support plugin-subordinate request for db_migration

Change-Id: Iaefcb81fff5ed8a9441c93ac4c8bac3fa12eef15
This commit is contained in:
Frode Nordahl 2019-09-25 17:12:26 +02:00
parent 831729dc98
commit 925b2caca7
2 changed files with 60 additions and 13 deletions

View File

@ -23,21 +23,24 @@ from subprocess import (
) )
from charmhelpers.core.hookenv import ( from charmhelpers.core.hookenv import (
DEBUG,
ERROR,
Hooks, Hooks,
UnregisteredHookError, UnregisteredHookError,
config, config,
is_leader,
leader_get,
leader_set,
local_unit, local_unit,
log, log,
DEBUG, open_port,
ERROR, related_units,
relation_get, relation_get,
relation_id,
relation_ids, relation_ids,
relation_set, relation_set,
status_set, status_set,
open_port,
unit_get, unit_get,
related_units,
is_leader,
) )
from charmhelpers.core.host import ( from charmhelpers.core.host import (
@ -607,12 +610,28 @@ def ha_changed():
'neutron-plugin-api-subordinate-relation-changed') 'neutron-plugin-api-subordinate-relation-changed')
@restart_on_change(restart_map(), stopstart=True) @restart_on_change(restart_map(), stopstart=True)
def neutron_plugin_api_subordinate_relation_joined(relid=None): def neutron_plugin_api_subordinate_relation_joined(relid=None):
''' relation_data = {}
-changed handles relation data set by a subordinate. if is_db_initialised():
''' db_migration_key = 'migrate-database-nonce'
relation_data = {'neutron-api-ready': 'no'} if not relid:
relid = relation_id()
leader_key = '{}-{}'.format(db_migration_key, relid)
for unit in related_units(relid):
nonce = relation_get(db_migration_key, rid=relid, unit=unit)
if nonce:
if is_leader() and leader_get(leader_key) != nonce:
migrate_neutron_database(upgrade=True)
# track nonce in leader storage to avoid superfluous
# migrations
leader_set({leader_key: nonce})
# set nonce back on relation to signal completion to other end
# we do this regardless of leadership status so that
# subordinates connected to non-leader units can proceed.
relation_data[db_migration_key] = nonce
relation_data['neutron-api-ready'] = 'no'
if is_api_ready(CONFIGS): if is_api_ready(CONFIGS):
relation_data['neutron-api-ready'] = "yes" relation_data['neutron-api-ready'] = 'yes'
if not manage_plugin(): if not manage_plugin():
neutron_cc_ctxt = NeutronCCContext()() neutron_cc_ctxt = NeutronCCContext()()
plugin_instance = NeutronApiSDNContext() plugin_instance = NeutronApiSDNContext()

View File

@ -950,15 +950,43 @@ class NeutronAPIHooksTests(CharmTestCase):
**{'neutron-api-ready': 'no'}, relation_id=None) **{'neutron-api-ready': 'no'}, relation_id=None)
self.CONFIGS.write_all.assert_called_once_with() self.CONFIGS.write_all.assert_called_once_with()
self.relation_set.reset_mock() self.relation_set.reset_mock()
self.CONFIGS.reset_mock()
_manage_plugin.return_value = False _manage_plugin.return_value = False
ncc_instance = _NeutronCCContext.return_value ncc_instance = _NeutronCCContext.return_value
ncc_instance.return_value = {'core_plugin': 'aPlugin'} ncc_instance.return_value = {'core_plugin': 'aPlugin'}
napisdn_instance = _NeutronApiSDNContext.return_value napisdn_instance = _NeutronApiSDNContext.return_value
napisdn_instance.is_allowed.return_value = True napisdn_instance.is_allowed.return_value = True
self._call_hook('neutron-plugin-api-subordinate-relation-changed') self._call_hook('neutron-plugin-api-subordinate-relation-changed')
hooks.neutron_plugin_api_subordinate_relation_joined() self.relation_set.assert_called_once_with(
self.relation_set.assert_called_with(
**{'neutron-api-ready': 'no', **{'neutron-api-ready': 'no',
'neutron_config_data': json.dumps({'core_plugin': 'aPlugin'})}, 'neutron_config_data': json.dumps({'core_plugin': 'aPlugin'})},
relation_id=None) relation_id=None)
self.CONFIGS.write_all.assert_called_with() self.CONFIGS.write_all.assert_called_once_with()
@patch.object(hooks, 'manage_plugin')
@patch.object(hooks, 'is_api_ready')
@patch.object(hooks, 'leader_set')
@patch.object(hooks, 'migrate_neutron_database')
@patch.object(hooks, 'leader_get')
@patch.object(hooks, 'relation_id')
@patch.object(hooks, 'is_db_initialised')
def test_neutron_plugin_api_subordinate_relation_db_migration(
self, _is_db_initialised, _relation_id, _leader_get,
_migrate_neutron_database, _leader_set, _is_api_ready,
_manage_plugin):
_is_db_initialised.return_value = True
_relation_id.return_value = 'neutron-plugin-api-subordinate:42'
self.related_units.return_value = ['aUnit']
self.is_leader.return_value = True
self.relation_get.side_effect = None
self.relation_get.return_value = 'fake-uuid'
_leader_get.return_value = (
'migrate-database-nonce-neutron-plugin-api-subordinate:42')
_is_api_ready.return_value = True
_manage_plugin.return_value = True
self._call_hook('neutron-plugin-api-subordinate-relation-changed')
_migrate_neutron_database.assert_called_once_with(upgrade=True)
self.relation_set.assert_called_once_with(
relation_id='neutron-plugin-api-subordinate:42',
**{'migrate-database-nonce': 'fake-uuid',
'neutron-api-ready': 'yes'})