Ensure cell0 updated on db/amqp change

Prior to this change, cell1 was updated when there was a database
or rabbitmq-server relation change, but cell0 wasn't. Ensure that
cell0 is also updated.

Change-Id: I670d0295ea339b21166ef7b18509b04a5beaa959
Closes-Bug: #1892904
This commit is contained in:
Corey Bryant 2020-09-08 19:40:10 +00:00
parent dde75693c7
commit 7983d1aaa9
2 changed files with 64 additions and 16 deletions

View File

@ -868,27 +868,47 @@ def get_cell_details():
def update_cell_database():
'''Update the cell1 database properties
'''Update the cell0 and cell1 database_connection/transport_url properties
This should be called whenever a database or rabbitmq-server relation is
changed to update the transport_url in the nova_api cell_mappings table.
The cell0 transport_url is always none:///.
The cell1 transport_url and database_connection are generated from the
config file's [DEFAULT]/transport_url and [database]/connection.
'''
hookenv.log('Updating cell1 properties', level=hookenv.INFO)
cell1_uuid = get_cell_uuid('cell1')
cmd = ['nova-manage', 'cell_v2', 'update_cell', '--cell_uuid', cell1_uuid]
try:
subprocess.check_output(cmd)
except subprocess.CalledProcessError as e:
if e.returncode == 1:
hookenv.log('Cell1 update_cell failed\n{}'.format(e.output),
cells = ['cell0', 'cell1']
for cell in cells:
hookenv.log('Updating {} properties'.format(cell), level=hookenv.INFO)
existing_cells = get_cell_details()
if not existing_cells.get(cell):
hookenv.log(
'Cell {} does not exist.'.format(cell), level=hookenv.DEBUG)
break
cell_uuid = existing_cells[cell]['uuid']
cmd = ['nova-manage', 'cell_v2', 'update_cell', '--cell_uuid',
cell_uuid]
if cell == 'cell0':
db_ctxt = ch_context.SharedDBContext(database='nova_cell0',
relation_prefix='novacell0',
ssl_dir=NOVA_CONF_DIR)()
if not db_ctxt:
hookenv.log(
'Defering updating cell {}, cell db relation not ready.'
.format(cell), level=hookenv.DEBUG)
break
sql_connection = get_sql_uri(db_ctxt)
cmd.extend([
'--transport-url', existing_cells[cell]['amqp'],
'--database_connection', sql_connection])
try:
subprocess.check_output(cmd)
except subprocess.CalledProcessError as e:
hookenv.log('{} update_cell failed\n{}'.format(cell, e.output),
level=hookenv.ERROR)
raise
elif e.returncode == 2:
hookenv.log(
'Cell1 update_cell failure ignored - the properties cannot '
'be set.', level=hookenv.INFO)
else:
hookenv.log('cell1 was successfully updated', level=hookenv.INFO)
else:
hookenv.log('{} was successfully updated'.format(cell),
level=hookenv.INFO)
def map_instances():
@ -1968,7 +1988,7 @@ def get_sql_uri(db_ctxt):
def update_child_cell(name, db_service, amqp_service, skip_acl_check=True):
"""Register cell.
"""Register or update cell.
Registering a cell requires:
1) Complete relation with api db service.

View File

@ -1759,3 +1759,31 @@ class NovaCCUtilsTests(CharmTestCase):
exists.return_value = True
utils.disable_deprecated_nova_placement_apache_site()
self.assertTrue(remove.called)
@patch.object(utils.ch_context, 'SharedDBContext')
@patch.object(utils, 'get_cell_details')
@patch.object(utils, 'get_sql_uri')
@patch.object(utils.subprocess, 'check_output')
def test_update_cell_database(self,
mock_check_output,
mock_get_sql_uri,
mock_get_cell_details,
mock_SharedDBContext):
mock_get_cell_details.return_value = {
'cell0': {'uuid': 'cell0uuid',
'amqp': 'none:///'},
'cell1': {'uuid': 'cell1uuid'},
}
mock_get_sql_uri.return_value = 'db-uri'
utils.update_cell_database()
mock_SharedDBContext.assert_called_once_with(
database='nova_cell0',
relation_prefix='novacell0',
ssl_dir='/etc/nova')
mock_check_output.assert_has_calls([
call(['nova-manage', 'cell_v2', 'update_cell',
'--cell_uuid', 'cell0uuid', '--transport-url', 'none:///',
'--database_connection', 'db-uri']),
call(['nova-manage', 'cell_v2', 'update_cell',
'--cell_uuid', 'cell1uuid']),
])