Deal with obsolete packages during charm upgrade

For Rocky, we switch the payload execution environent from py2->py3
post initial charm release; ensure that any existing py2 based
deployments are automatically switched over to py3 during any
charm upgrade.

This is implemented in the default upgrade-charm handler code; if
packages are removed as part of the upgrade, all services associated
with the charm will be restarted.

Change-Id: Ib5f11d21dd26cb2918f5d5044ed56d688bba3b5d
Closes-Bug: 1803451
This commit is contained in:
James Page 2018-11-15 09:58:58 +00:00
parent cbbf817834
commit b75c8b4161
2 changed files with 64 additions and 1 deletions

View File

@ -826,8 +826,14 @@ class BaseOpenStackCharmActions(object):
that the ports that are closed should be closed. If the charm upgrade
alters the ports then update_api_ports() function will adjust the ports
as needed.
Obsolete packages will also be assessed for removal; if packages are
removed, then services will be restarted to pickup any changes.
"""
self.update_api_ports()
self.install()
if self.remove_obsolete_packages():
self.restart_all()
def update_api_ports(self, ports=None):
"""Update the ports list supplied (or the default ports defined in the
@ -949,6 +955,14 @@ class BaseOpenStackCharmActions(object):
packages=self.all_packages,
options=dpkg_opts,
fatal=True)
self.remove_obsolete_packages()
self.release = new_os_rel
def remove_obsolete_packages(self):
"""Remove any packages that are no longer needed for operation
:returns: boolean indication where packages where removed.
"""
if self.purge_packages:
# NOTE(jamespage):
# Ensure packages that should be purged are actually installed
@ -960,7 +974,8 @@ class BaseOpenStackCharmActions(object):
fetch.apt_purge(packages=installed_packages,
fatal=True)
fetch.apt_autoremove(purge=True, fatal=True)
self.release = new_os_rel
return True
return False
def do_openstack_upgrade_config_render(self, interfaces_list):
"""Render configs after upgrade

View File

@ -780,6 +780,30 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest):
(target_charm.do_openstack_upgrade_db_migration.
assert_called_once_with())
def test_remove_obsolete_packages(self):
self.patch_object(chm_core.charmhelpers.fetch, 'apt_purge')
self.patch_object(chm_core.charmhelpers.fetch, 'apt_autoremove')
self.patch_object(chm_core.charmhelpers.fetch,
'filter_installed_packages',
return_value=['python-notinstalled'])
self.assertTrue(self.target.remove_obsolete_packages())
self.apt_purge.assert_called_once_with(
packages=['python-obsolete'],
fatal=True)
self.apt_autoremove.assert_called_once_with(
purge=True,
fatal=True)
def test_remove_obsolete_packages_noop(self):
self.patch_object(chm_core.charmhelpers.fetch, 'apt_purge')
self.patch_object(chm_core.charmhelpers.fetch, 'apt_autoremove')
self.patch_object(chm_core.charmhelpers.fetch,
'filter_installed_packages',
return_value=self.target.purge_packages)
self.assertFalse(self.target.remove_obsolete_packages())
self.apt_purge.assert_not_called()
self.apt_autoremove.assert_not_called()
def test_do_openstack_pkg_upgrade_package(self):
self.patch_target('config',
new={'openstack-origin': 'cloud:natty-kilo'})
@ -874,3 +898,27 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest):
self.is_leader.return_value = True
self.target.do_openstack_upgrade_db_migration()
self.check_call.assert_called_once_with(['my-sync-cmd', 'param1'])
def test_upgrade_charm(self):
self.target.update_api_ports = mock.MagicMock()
self.target.install = mock.MagicMock()
self.target.remove_obsolete_packages = mock.MagicMock()
self.target.remove_obsolete_packages.return_value = True
self.target.restart_all = mock.MagicMock()
self.target.upgrade_charm()
self.target.update_api_ports.assert_called_once()
self.target.install.assert_called_once()
self.target.remove_obsolete_packages.assert_called_once()
self.target.restart_all.assert_called_once()
def test_upgrade_charm_no_purge(self):
self.target.update_api_ports = mock.MagicMock()
self.target.install = mock.MagicMock()
self.target.remove_obsolete_packages = mock.MagicMock()
self.target.remove_obsolete_packages.return_value = False
self.target.restart_all = mock.MagicMock()
self.target.upgrade_charm()
self.target.update_api_ports.assert_called_once()
self.target.install.assert_called_once()
self.target.remove_obsolete_packages.assert_called_once()
self.target.restart_all.assert_not_called()