Run nova-manage db online_data_migrations on upgrades
In mitaka an extra operation called online_data_migrations was added to assist rolling upgrades. This patch runs this before and after, this is to make sure the old upgrades where this migration was not being performed are run before installing a newer release. References: - https://git.openstack.org/cgit/openstack/nova/commit/?id=7d5069ce20ec0d792a3974b2c53d01ae005cde98 - https://docs.openstack.org/nova/latest/user/upgrade.html Change-Id: Ic4bc2c5ae86c99c3af2a1d0ee08badb09835d932 Closes-Bug: 1711209
This commit is contained in:
parent
024a34e52a
commit
eacd234ed5
|
@ -526,6 +526,7 @@ def get_step_upgrade_source(new_src):
|
|||
'precise-icehouse/proposed': ('precise-proposed/grizzly',
|
||||
'cloud:precise-havana/proposed'),
|
||||
'trusty-liberty': ('*', 'cloud:trusty-kilo'),
|
||||
'xenial-ocata': ('*', 'cloud:xenial-newton'), # LP: #1711209
|
||||
}
|
||||
try:
|
||||
os_codename = get_os_codename_install_source(new_src)
|
||||
|
@ -551,12 +552,12 @@ def get_step_upgrade_source(new_src):
|
|||
continue
|
||||
|
||||
with open(fpath, 'r') as f:
|
||||
line = f.readline()
|
||||
for target_src, (cur_pocket, step_src) in sources.items():
|
||||
if target_src != new_src:
|
||||
continue
|
||||
if cur_pocket in line:
|
||||
return step_src
|
||||
for line in f.readlines():
|
||||
for target_src, (cur_pocket, step_src) in sources.items():
|
||||
if target_src != new_src:
|
||||
continue
|
||||
if cur_pocket in line:
|
||||
return step_src
|
||||
|
||||
return None
|
||||
|
||||
|
@ -611,6 +612,12 @@ def _do_openstack_upgrade(new_src):
|
|||
if (CompareOpenStackReleases(os_release('nova-common')) == 'kilo' and
|
||||
is_leader()):
|
||||
migrate_nova_flavors()
|
||||
|
||||
# 'nova-manage db online_data_migrations' needs to be run before moving to
|
||||
# the next release for environments upgraded using old charms where this
|
||||
# step was not being executed (LP: #1711209).
|
||||
online_data_migrations_if_needed()
|
||||
|
||||
new_os_rel = get_os_codename_install_source(new_src)
|
||||
cmp_new_os_rel = CompareOpenStackReleases(new_os_rel)
|
||||
log('Performing OpenStack upgrade to %s.' % (new_os_rel))
|
||||
|
@ -655,6 +662,7 @@ def _do_openstack_upgrade(new_src):
|
|||
if is_leader():
|
||||
status_set('maintenance', 'Running nova db migration')
|
||||
migrate_nova_databases()
|
||||
|
||||
if not is_unit_paused_set():
|
||||
[service_start(s) for s in services()]
|
||||
|
||||
|
@ -695,6 +703,16 @@ def migrate_nova_flavors():
|
|||
subprocess.check_output(cmd)
|
||||
|
||||
|
||||
@retry_on_exception(5, base_delay=3, exc_type=subprocess.CalledProcessError)
|
||||
def online_data_migrations_if_needed():
|
||||
'''Runs nova-manage to run online data migrations available since Mitaka'''
|
||||
if (is_leader() and
|
||||
CompareOpenStackReleases(os_release('nova-common')) >= 'mitaka'):
|
||||
log('Running online_data_migrations', level=INFO)
|
||||
subprocess.check_output(['nova-manage', 'db',
|
||||
'online_data_migrations'])
|
||||
|
||||
|
||||
def migrate_nova_api_database():
|
||||
'''Initialize or migrate the nova_api database'''
|
||||
if CompareOpenStackReleases(os_release('nova-common')) >= 'mitaka':
|
||||
|
@ -793,6 +811,7 @@ def migrate_nova_databases():
|
|||
if CompareOpenStackReleases(os_release('nova-common')) < 'ocata':
|
||||
migrate_nova_api_database()
|
||||
migrate_nova_database()
|
||||
online_data_migrations_if_needed()
|
||||
finalize_migrate_nova_databases()
|
||||
|
||||
# TODO: Replace the following checks with a Cellsv2 context check.
|
||||
|
@ -805,6 +824,7 @@ def migrate_nova_databases():
|
|||
migrate_nova_api_database()
|
||||
initialize_cell_databases()
|
||||
migrate_nova_database()
|
||||
online_data_migrations_if_needed()
|
||||
add_hosts_to_cell()
|
||||
finalize_migrate_nova_databases()
|
||||
|
||||
|
|
|
@ -566,9 +566,12 @@ class NovaCCHooksTests(CharmTestCase):
|
|||
self.assertFalse(self.migrate_nova_databases.called)
|
||||
api_joined.asert_called_with(rid='nova-api/0')
|
||||
|
||||
@patch.object(utils, 'is_leader')
|
||||
@patch.object(utils, 'os_release')
|
||||
@patch.object(hooks, 'is_db_initialised')
|
||||
@patch.object(hooks, 'CONFIGS')
|
||||
def test_db_changed_allowed(self, configs, mock_is_db_initialised):
|
||||
def test_db_changed_allowed(self, configs, mock_is_db_initialised,
|
||||
utils_os_release, utils_is_leader):
|
||||
mock_is_db_initialised.return_value = False
|
||||
allowed_units = 'nova-cloud-controller/0 nova-cloud-controller/3'
|
||||
self.test_relation.set({
|
||||
|
@ -576,6 +579,8 @@ class NovaCCHooksTests(CharmTestCase):
|
|||
})
|
||||
self.local_unit.return_value = 'nova-cloud-controller/3'
|
||||
self.os_release.return_value = 'diablo'
|
||||
utils_os_release.return_value = 'diablo'
|
||||
utils_is_leader.return_value = False
|
||||
self._shared_db_test(configs)
|
||||
self.assertTrue(configs.write_all.called)
|
||||
self.migrate_nova_databases.assert_called_with()
|
||||
|
@ -594,23 +599,30 @@ class NovaCCHooksTests(CharmTestCase):
|
|||
self.assertTrue(configs.write_all.called)
|
||||
self.assertFalse(self.migrate_nova_databases.called)
|
||||
|
||||
@patch.object(utils, 'is_leader')
|
||||
@patch.object(utils, 'os_release')
|
||||
@patch.object(hooks, 'quantum_joined')
|
||||
@patch.object(hooks, 'nova_api_relation_joined')
|
||||
@patch.object(hooks, 'is_db_initialised')
|
||||
@patch.object(hooks, 'CONFIGS')
|
||||
def test_postgresql_db_changed(self, configs, mock_is_db_initialised,
|
||||
api_joined, quantum_joined):
|
||||
api_joined, quantum_joined,
|
||||
utils_os_release, utils_is_leader):
|
||||
self.relation_ids.side_effect = [
|
||||
[],
|
||||
['neutron-gateway/0'],
|
||||
['nova-api/0']]
|
||||
mock_is_db_initialised.return_value = False
|
||||
self.os_release.return_value = 'diablo'
|
||||
utils_os_release.return_value = 'diablo'
|
||||
utils_is_leader.return_value = True
|
||||
self._postgresql_db_test(configs)
|
||||
self.assertTrue(configs.write_all.called)
|
||||
self.migrate_nova_databases.assert_called_with()
|
||||
api_joined.assert_called_with(rid='nova-api/0')
|
||||
|
||||
@patch.object(utils, 'is_leader')
|
||||
@patch.object(utils, 'os_release')
|
||||
@patch.object(hooks, 'quantum_joined')
|
||||
@patch.object(hooks, 'is_db_initialised')
|
||||
@patch.object(hooks, 'nova_cell_relation_joined')
|
||||
|
@ -618,7 +630,8 @@ class NovaCCHooksTests(CharmTestCase):
|
|||
@patch.object(hooks, 'CONFIGS')
|
||||
def test_db_changed_remote_restarts(self, configs, comp_joined,
|
||||
cell_joined, mock_is_db_initialised,
|
||||
quantum_joined):
|
||||
quantum_joined, utils_os_release,
|
||||
utils_is_leader):
|
||||
mock_is_db_initialised.return_value = False
|
||||
|
||||
def _relation_ids(rel):
|
||||
|
@ -636,6 +649,8 @@ class NovaCCHooksTests(CharmTestCase):
|
|||
})
|
||||
self.local_unit.return_value = 'nova-cloud-controller/0'
|
||||
self.os_release.return_value = 'diablo'
|
||||
utils_os_release.return_value = 'diablo'
|
||||
utils_is_leader.return_value = False
|
||||
self._shared_db_test(configs)
|
||||
comp_joined.assert_called_with(remote_restart=True,
|
||||
rid='nova-compute/0')
|
||||
|
|
|
@ -505,6 +505,18 @@ class NovaCCUtilsTests(CharmTestCase):
|
|||
step_src = utils.get_step_upgrade_source(OS_ORIGIN_NEWTON_STAGING)
|
||||
self.assertEqual(step_src, None)
|
||||
|
||||
@patch('charmhelpers.contrib.openstack.utils.lsb_release')
|
||||
def test_get_setup_upgrade_source_target_ocata(self, lsb_release):
|
||||
# mitaka -> ocata
|
||||
self.lsb_release.return_value = {'DISTRIB_CODENAME': 'xenial'}
|
||||
lsb_release.return_value = {'DISTRIB_CODENAME': 'xenial'}
|
||||
self.os_release.return_value = 'mitaka'
|
||||
self.get_os_codename_install_source.side_effect = self.originals[
|
||||
'get_os_codename_install_source']
|
||||
|
||||
step_src = utils.get_step_upgrade_source("cloud:xenial-ocata")
|
||||
self.assertEqual(step_src, "cloud:xenial-newton")
|
||||
|
||||
@patch('charmhelpers.contrib.openstack.utils.lsb_release')
|
||||
def test_get_setup_upgrade_source_target_liberty_with_mirror(self,
|
||||
lsb_release):
|
||||
|
@ -691,6 +703,8 @@ class NovaCCUtilsTests(CharmTestCase):
|
|||
self.os_release.return_value = 'diablo'
|
||||
utils.migrate_nova_databases()
|
||||
check_output.assert_called_with(['nova-manage', 'db', 'sync'])
|
||||
self.assertNotIn(call(['nova-manage', 'db', 'online_data_migrations']),
|
||||
check_output.mock_calls)
|
||||
self.peer_store.assert_called_with('dbsync_state', 'complete')
|
||||
self.assertTrue(self.enable_services.called)
|
||||
self.cmd_all_services.assert_called_with('start')
|
||||
|
@ -704,6 +718,7 @@ class NovaCCUtilsTests(CharmTestCase):
|
|||
check_output.assert_has_calls([
|
||||
call(['nova-manage', 'api_db', 'sync']),
|
||||
call(['nova-manage', 'db', 'sync']),
|
||||
call(['nova-manage', 'db', 'online_data_migrations']),
|
||||
])
|
||||
self.peer_store.assert_called_with('dbsync_state', 'complete')
|
||||
self.assertTrue(self.enable_services.called)
|
||||
|
@ -724,6 +739,7 @@ class NovaCCUtilsTests(CharmTestCase):
|
|||
call(['nova-manage', 'api_db', 'sync']),
|
||||
call(['nova-manage', 'cell_v2', 'map_cell0']),
|
||||
call(['nova-manage', 'db', 'sync']),
|
||||
call(['nova-manage', 'db', 'online_data_migrations']),
|
||||
call(['nova-manage', 'cell_v2', 'list_cells']),
|
||||
ANY,
|
||||
])
|
||||
|
|
Loading…
Reference in New Issue