From 9ff97e429d9ce53f764face1f6a4c395394c97b5 Mon Sep 17 00:00:00 2001 From: Liam Young Date: Thu, 15 Nov 2018 15:13:19 +0000 Subject: [PATCH] Purge old packages on upgrade-charm On charm upgrade the charm may switch to py3 packages. If so, ensure the old py2 packages are purged. If the purge occurs then restart services. Change-Id: I17abef16afbb8c62dae1b725c74c39cec414f4f8 Closes-Bug: 1803451 --- hooks/nova_compute_hooks.py | 8 ++++++++ hooks/nova_compute_utils.py | 25 +++++++++++++++++-------- unit_tests/test_nova_compute_hooks.py | 23 +++++++++++++++++++++++ 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/hooks/nova_compute_hooks.py b/hooks/nova_compute_hooks.py index 1c4b11a1..25c3aac0 100755 --- a/hooks/nova_compute_hooks.py +++ b/hooks/nova_compute_hooks.py @@ -110,6 +110,7 @@ from nova_compute_utils import ( pause_unit_helper, resume_unit_helper, get_availability_zone, + remove_old_packages, ) from charmhelpers.contrib.network.ip import ( @@ -421,9 +422,16 @@ def relation_broken(): @hooks.hook('upgrade-charm') @harden() def upgrade_charm(): + apt_install(determine_packages(), fatal=True) # NOTE: ensure psutil install for hugepages configuration status_set('maintenance', 'Installing apt packages') apt_install(filter_installed_packages(['python-psutil'])) + packages_removed = remove_old_packages() + if packages_removed and not is_unit_paused_set(): + log("Package purge detected, restarting services", "INFO") + for s in services(): + service_restart(s) + for r_id in relation_ids('amqp'): amqp_joined(relation_id=r_id) diff --git a/hooks/nova_compute_utils.py b/hooks/nova_compute_utils.py index 9760ad03..713086b1 100644 --- a/hooks/nova_compute_utils.py +++ b/hooks/nova_compute_utils.py @@ -435,6 +435,22 @@ def determine_purge_packages(): return [] +def remove_old_packages(): + '''Purge any packages that need ot be removed. + + :returns: bool Whether packages were removed. + ''' + installed_packages = filter_missing_packages( + determine_purge_packages() + ) + if installed_packages: + apt_mark(filter_missing_packages(determine_held_packages()), + 'auto') + apt_purge(installed_packages, fatal=True) + apt_autoremove(purge=True, fatal=True) + return bool(installed_packages) + + def determine_held_packages(): '''Return a list of packages to mark as candidates for removal for the current OS release''' @@ -616,14 +632,7 @@ def do_openstack_upgrade(configs): reset_os_release() apt_install(determine_packages(), fatal=True) - installed_packages = filter_missing_packages( - determine_purge_packages() - ) - if installed_packages: - apt_mark(filter_missing_packages(determine_held_packages()), - 'auto') - apt_purge(installed_packages, fatal=True) - apt_autoremove(purge=True, fatal=True) + remove_old_packages() configs.set_release(openstack_release=new_os_rel) configs.write_all() diff --git a/unit_tests/test_nova_compute_hooks.py b/unit_tests/test_nova_compute_hooks.py index 92964343..5b136df9 100644 --- a/unit_tests/test_nova_compute_hooks.py +++ b/unit_tests/test_nova_compute_hooks.py @@ -95,6 +95,8 @@ TO_PATCH = [ 'unitdata', # templating 'render', + 'remove_old_packages', + 'services', ] @@ -739,3 +741,24 @@ class NovaComputeRelationsTests(CharmTestCase): def test_cloud_credentials_changed(self, mock_CONFIGS): hooks.cloud_credentials_changed() mock_CONFIGS.write.assert_called_with('/etc/nova/nova.conf') + + @patch.object(hooks.grp, 'getgrnam') + def test_upgrade_charm(self, getgrnam): + grp_mock = MagicMock() + grp_mock.gr_gid = None + getgrnam.return_value = grp_mock + self.remove_old_packages.return_value = False + hooks.upgrade_charm() + self.remove_old_packages.assert_called_once_with() + self.assertFalse(self.service_restart.called) + + @patch.object(hooks.grp, 'getgrnam') + def test_upgrade_charm_purge(self, getgrnam): + grp_mock = MagicMock() + grp_mock.gr_gid = None + getgrnam.return_value = grp_mock + self.remove_old_packages.return_value = True + self.services.return_value = ['nova-compute'] + hooks.upgrade_charm() + self.remove_old_packages.assert_called_once_with() + self.service_restart.assert_called_once_with('nova-compute')