py3: add support for switching workloads from py2->py3

For migration of services to execution under Python 3 add support
for a Charm class to declare a set of packages to purge on upgrade.

This allows the target release Charm class to remove Python 2
modules installed as part of prior charm versions.

After the purge call, autoremove will also be called to purge any
other packages that where indirectly installed.

Add new python_version attribute for charm classes, supporting
conditional install of python{3}-memcache for token caching.

Change-Id: I17a93524fb7ec134b4a3a61cd0e86977daf49c4e
This commit is contained in:
James Page 2018-09-09 08:34:31 +01:00
parent 194a2d65a9
commit 97128ae340
4 changed files with 33 additions and 1 deletions

View File

@ -67,6 +67,12 @@ class OpenStackCharm(BaseOpenStackCharm,
# List of packages to install
packages = []
# List of packages to purge
purge_packages = []
# Python version used to execute installed workload
python_version = 2
# List of snaps to install
snaps = []
@ -232,7 +238,10 @@ class OpenStackAPICharm(OpenStackCharm):
"""
packages = []
if self.enable_memcache(release=release):
packages.extend(['memcached', 'python-memcache'])
if self.python_version == 2:
packages.extend(['memcached', 'python-memcache'])
else:
packages.extend(['memcached', 'python3-memcache'])
return packages
def get_amqp_credentials(self):

View File

@ -949,6 +949,17 @@ class BaseOpenStackCharmActions(object):
packages=self.all_packages,
options=dpkg_opts,
fatal=True)
if self.purge_packages:
# NOTE(jamespage):
# Ensure packages that should be purged are actually installed
installed_packages = list(
set(self.purge_packages) -
set(fetch.filter_installed_packages(self.purge_packages))
)
if installed_packages:
fetch.apt_purge(packages=installed_packages,
fatal=True)
fetch.apt_autoremove(purge=True, fatal=True)
self.release = new_os_rel
def do_openstack_upgrade_config_render(self, interfaces_list):

View File

@ -24,6 +24,7 @@ class MyOpenStackCharm(chm_classes.OpenStackCharm):
release = 'icehouse'
name = 'my-charm'
packages = ['p1', 'p2', 'p3', 'package-to-filter']
purge_packages = ['python-obsolete', 'python-notinstalled']
snaps = ['mysnap']
version_package = 'p2'
version_snap = 'mysnap'

View File

@ -789,6 +789,11 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest):
self.patch_object(chm_core.charmhelpers.fetch, 'apt_update')
self.patch_object(chm_core.charmhelpers.fetch, 'apt_upgrade')
self.patch_object(chm_core.charmhelpers.fetch, 'apt_install')
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.patch_object(chm_core.os_utils, 'snap_install_requested',
return_value=False)
self.target.do_openstack_pkg_upgrade()
@ -806,6 +811,12 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest):
'--option', 'Dpkg::Options::=--force-confnew', '--option',
'Dpkg::Options::=--force-confdef'],
fatal=True)
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_do_openstack_pkg_upgrade_snap(self):
self.patch_target('config',