summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Ames <david.ames@canonical.com>2017-09-07 09:13:12 -0700
committerDavid Ames <david.ames@canonical.com>2017-09-07 14:34:55 -0700
commit0161dde79660a248742e41e67f92ed13af561dd7 (patch)
treee457efcf9b34d01a7a13d47875aa2121cc6f9b64
parent0681179aa30ce3b94c1cfe72e92474830642ce15 (diff)
Resolve OS upgrade bugs
Ensure that the os_release cache is cleared during the openstack upgrade process, ensuring that package list and configuration options are correctly set for the new OpenStack version. Ensure that map_instances gets run on upgrade. This updates the nova_api.instance_mappings table with pre-existing instances. Change-Id: Idfcdc48c25b24d0cc9ded3eda2bc4d13d3b04f6d Closes-Bug: 1715624
Notes
Notes (review): Code-Review+2: Corey Bryant <corey.bryant@canonical.com> Workflow+1: Corey Bryant <corey.bryant@canonical.com> Verified+2: Jenkins Submitted-by: Jenkins Submitted-at: Thu, 07 Sep 2017 21:47:32 +0000 Reviewed-on: https://review.openstack.org/501813 Project: openstack/charm-nova-cloud-controller Branch: refs/heads/master
-rw-r--r--hooks/nova_cc_utils.py50
-rw-r--r--unit_tests/test_nova_cc_utils.py22
2 files changed, 59 insertions, 13 deletions
diff --git a/hooks/nova_cc_utils.py b/hooks/nova_cc_utils.py
index 494771c..e737f6e 100644
--- a/hooks/nova_cc_utils.py
+++ b/hooks/nova_cc_utils.py
@@ -51,6 +51,7 @@ from charmhelpers.contrib.openstack.utils import (
51 incomplete_relation_data, 51 incomplete_relation_data,
52 is_ip, 52 is_ip,
53 os_release, 53 os_release,
54 reset_os_release,
54 save_script_rc as _save_script_rc, 55 save_script_rc as _save_script_rc,
55 is_unit_paused_set, 56 is_unit_paused_set,
56 make_assess_status_func, 57 make_assess_status_func,
@@ -587,12 +588,6 @@ def disable_policy_rcd():
587 os.unlink('/usr/sbin/policy-rc.d') 588 os.unlink('/usr/sbin/policy-rc.d')
588 589
589 590
590def reset_os_release():
591 # Ugly hack to make os_release re-read versions
592 import charmhelpers.contrib.openstack.utils as utils
593 utils.os_rel = None
594
595
596def is_db_initialised(): 591def is_db_initialised():
597 if relation_ids('cluster'): 592 if relation_ids('cluster'):
598 dbsync_state = peer_retrieve('dbsync_state') 593 dbsync_state = peer_retrieve('dbsync_state')
@@ -630,6 +625,7 @@ def _do_openstack_upgrade(new_src):
630 625
631 apt_update(fatal=True) 626 apt_update(fatal=True)
632 apt_upgrade(options=dpkg_opts, fatal=True, dist=True) 627 apt_upgrade(options=dpkg_opts, fatal=True, dist=True)
628 reset_os_release()
633 apt_install(determine_packages(), fatal=True) 629 apt_install(determine_packages(), fatal=True)
634 630
635 disable_policy_rcd() 631 disable_policy_rcd()
@@ -637,7 +633,6 @@ def _do_openstack_upgrade(new_src):
637 # NOTE(jamespage) upgrade with existing config files as the 633 # NOTE(jamespage) upgrade with existing config files as the
638 # havana->icehouse migration enables new service_plugins which 634 # havana->icehouse migration enables new service_plugins which
639 # create issues with db upgrades 635 # create issues with db upgrades
640 reset_os_release()
641 configs = register_configs(release=new_os_rel) 636 configs = register_configs(release=new_os_rel)
642 configs.write_all() 637 configs.write_all()
643 638
@@ -751,12 +746,27 @@ def initialize_cell_databases():
751 # TODO: Update to subprocess.check_call(), but note that rc == 2 is 746 # TODO: Update to subprocess.check_call(), but note that rc == 2 is
752 # not a failure so only allow exception to be raised if rc == 1. 747 # not a failure so only allow exception to be raised if rc == 1.
753 if rc == 0: 748 if rc == 0:
754 log('cell1 mapping was successfully created', level=INFO) 749 log('cell1 was successfully created', level=INFO)
755 elif rc == 1: 750 elif rc == 1:
756 raise Exception("Cannot initialize cell1 because of missing " 751 raise Exception("Cannot initialize cell1 because of missing "
757 "transport_url or database connection") 752 "transport_url or database connection")
758 753
759 754
755def get_cell_uuid(cell):
756 '''Get cell uuid
757 :param cell: string cell name i.e. 'cell1'
758 :returns: string cell uuid
759 '''
760 log("Listing cell, '{}'".format(cell), level=INFO)
761 cmd = ['sudo', 'nova-manage', 'cell_v2', 'list_cells']
762 out = subprocess.check_output(cmd)
763 cell_uuid = out.split(cell, 1)[1].split()[1]
764 if not cell_uuid:
765 raise Exception("Cannot find cell, '{}', in list_cells."
766 "".format(cell))
767 return cell_uuid
768
769
760def update_cell_database(): 770def update_cell_database():
761 '''Update the cell1 database properties 771 '''Update the cell1 database properties
762 772
@@ -764,10 +774,7 @@ def update_cell_database():
764 changed to update the transport_url in the nova_api cell_mappings table. 774 changed to update the transport_url in the nova_api cell_mappings table.
765 ''' 775 '''
766 log('Updating cell1 properties', level=INFO) 776 log('Updating cell1 properties', level=INFO)
767 cmd = ['sudo', 'nova-manage', 'cell_v2', 'list_cells'] 777 cell1_uuid = get_cell_uuid('cell1')
768 out = subprocess.check_output(cmd)
769 cell1_uuid = out.split("cell1", 1)[1].split()[1]
770
771 cmd = ['nova-manage', 'cell_v2', 'update_cell', '--cell_uuid', cell1_uuid] 778 cmd = ['nova-manage', 'cell_v2', 'update_cell', '--cell_uuid', cell1_uuid]
772 rc = subprocess.call(cmd) 779 rc = subprocess.call(cmd)
773 # TODO: Update to subprocess.check_call(), but note that rc == 2 is 780 # TODO: Update to subprocess.check_call(), but note that rc == 2 is
@@ -778,6 +785,22 @@ def update_cell_database():
778 raise Exception("Cannot find cell1 while attempting properties update") 785 raise Exception("Cannot find cell1 while attempting properties update")
779 786
780 787
788def map_instances():
789 '''Map instances
790
791 Updates nova_api.inatance_mappings with pre-existing instances
792 '''
793 log('Cell1 map_instances', level=INFO)
794 cell1_uuid = get_cell_uuid('cell1')
795 cmd = ['nova-manage', 'cell_v2', 'map_instances',
796 '--cell_uuid', cell1_uuid]
797 rc = subprocess.call(cmd)
798 if rc == 0:
799 log('Cell1 map_instances updated successfully', level=INFO)
800 elif rc == 1:
801 raise Exception("map_instances failed")
802
803
781def add_hosts_to_cell(): 804def add_hosts_to_cell():
782 '''Add any new compute hosts to cell1''' 805 '''Add any new compute hosts to cell1'''
783 # TODO: Replace the following checks with a Cellsv2 context check. 806 # TODO: Replace the following checks with a Cellsv2 context check.
@@ -826,6 +849,7 @@ def migrate_nova_databases():
826 migrate_nova_database() 849 migrate_nova_database()
827 online_data_migrations_if_needed() 850 online_data_migrations_if_needed()
828 add_hosts_to_cell() 851 add_hosts_to_cell()
852 map_instances()
829 finalize_migrate_nova_databases() 853 finalize_migrate_nova_databases()
830 854
831 855
@@ -1023,7 +1047,7 @@ def determine_endpoints(public_url, internal_url, admin_url):
1023 '''Generates a dictionary containing all relevant endpoints to be 1047 '''Generates a dictionary containing all relevant endpoints to be
1024 passed to keystone as relation settings.''' 1048 passed to keystone as relation settings.'''
1025 region = config('region') 1049 region = config('region')
1026 os_rel = os_release('nova-common', reset_cache=True) 1050 os_rel = os_release('nova-common')
1027 cmp_os_rel = CompareOpenStackReleases(os_rel) 1051 cmp_os_rel = CompareOpenStackReleases(os_rel)
1028 1052
1029 nova_public_url = ('%s:%s/v2/$(tenant_id)s' % 1053 nova_public_url = ('%s:%s/v2/$(tenant_id)s' %
diff --git a/unit_tests/test_nova_cc_utils.py b/unit_tests/test_nova_cc_utils.py
index a21c7f7..e377646 100644
--- a/unit_tests/test_nova_cc_utils.py
+++ b/unit_tests/test_nova_cc_utils.py
@@ -1367,3 +1367,25 @@ class NovaCCUtilsTests(CharmTestCase):
1367 1367
1368 s_resume.assert_has_calls([call(s) for s in utils.AWS_COMPAT_SERVICES]) 1368 s_resume.assert_has_calls([call(s) for s in utils.AWS_COMPAT_SERVICES])
1369 s_pause.assert_not_called() 1369 s_pause.assert_not_called()
1370
1371 @patch('subprocess.check_output')
1372 def test_get_cell_uuid(self, mock_check_call):
1373 mock_check_call.return_value = ("""
1374 +-------+--------------------------------------+
1375 | Name | UUID |
1376 +-------+--------------------------------------+
1377 | cell0 | 00000000-0000-0000-0000-000000000000 |
1378 | cell1 | c83121db-f1c7-464a-b657-38c28fac84c6 |
1379 +-------+--------------------------------------+""")
1380 expected = 'c83121db-f1c7-464a-b657-38c28fac84c6'
1381 self.assertEqual(expected, utils.get_cell_uuid('cell1'))
1382
1383 @patch.object(utils, 'get_cell_uuid')
1384 @patch('subprocess.call')
1385 def test_map_instances(self, mock_call, mock_get_cell_uuid):
1386 cell_uuid = 'c83121db-f1c7-464a-b657-38c28fac84c6'
1387 mock_get_cell_uuid.return_value = cell_uuid
1388 utils.map_instances()
1389 mock_call.assert_called_with(['nova-manage', 'cell_v2',
1390 'map_instances', '--cell_uuid',
1391 cell_uuid])