Ensure target charm is used during upgrades

When upgrading openstack components, ensure that the charm class
representing the target release is used for packages and
config file rendering, supporting changes in config files or
packages to be installed.

Also set OPENSTACK_RELEASE_KEY to new release to ensure that
Charm class resolution in future hook executions observes the
current release, rather than the release at install.

Change-Id: I724ae652460e352e24ed7bf2bf57ea181fadff1c
Closes-Bug: 1779062
This commit is contained in:
James Page 2018-07-13 12:06:07 +01:00
parent 537ebe9b5a
commit 0ac8eb2781
3 changed files with 24 additions and 11 deletions

View File

@ -13,6 +13,7 @@ import charmhelpers.contrib.openstack.utils as os_utils
import charmhelpers.core.hookenv as hookenv
import charmhelpers.core.host as ch_host
import charmhelpers.core.templating
import charmhelpers.core.unitdata as unitdata
import charmhelpers.fetch as fetch
import charms.reactive as reactive
import charms.reactive.relations as relations
@ -20,6 +21,8 @@ import charms.reactive.relations as relations
import charms_openstack.adapters as os_adapters
import charms_openstack.ip as os_ip
from charms_openstack.charm import defaults as os_defaults
# _releases{} is a dictionary of release -> class that is instantiated
# according to the the release that is being requested. i.e. a charm can
# handle more than one release. The BaseOpenStackCharm() derived class sets the
@ -892,9 +895,14 @@ class BaseOpenStackCharmActions(object):
"""
if self.openstack_upgrade_available(self.release_pkg):
hookenv.status_set('maintenance', 'Running openstack upgrade')
self.do_openstack_pkg_upgrade()
self.do_openstack_upgrade_config_render(interfaces_list)
self.do_openstack_upgrade_db_migration()
new_src = self.config['openstack-origin']
new_os_rel = os_utils.get_os_codename_install_source(new_src)
unitdata.kv().set(os_defaults.OPENSTACK_RELEASE_KEY,
new_os_rel)
target_charm = get_charm_instance(new_os_rel)
target_charm.do_openstack_pkg_upgrade()
target_charm.do_openstack_upgrade_config_render(interfaces_list)
target_charm.do_openstack_upgrade_db_migration()
def do_openstack_pkg_upgrade(self):
"""Upgrade OpenStack packages and snaps

View File

@ -30,7 +30,7 @@ basepython = python3.6
deps = -r{toxinidir}/test-requirements.txt
[testenv:pep8]
basepython = python3.5
basepython = python3
deps = -r{toxinidir}/test-requirements.txt
commands = flake8 {posargs} charms_openstack unit_tests

View File

@ -739,6 +739,7 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest):
self.patch_target('do_openstack_pkg_upgrade')
self.patch_target('do_openstack_upgrade_config_render')
self.patch_target('do_openstack_upgrade_db_migration')
self.patch_object(chm_core, 'get_charm_instance')
# Test no upgrade avaialble
self.openstack_upgrade_available.return_value = False
self.target.upgrade_if_available('int_list')
@ -747,14 +748,17 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest):
self.assertFalse(self.do_openstack_upgrade_config_render.called)
self.assertFalse(self.do_openstack_upgrade_db_migration.called)
# Test upgrade avaialble
target_charm = mock.MagicMock()
self.get_charm_instance.return_value = target_charm
self.openstack_upgrade_available.return_value = True
self.target.upgrade_if_available('int_list')
self.status_set.assert_called_once_with('maintenance',
'Running openstack upgrade')
self.do_openstack_pkg_upgrade.assert_called_once_with()
self.do_openstack_upgrade_config_render.assert_called_once_with(
'int_list')
self.do_openstack_upgrade_db_migration.assert_called_once_with()
target_charm.do_openstack_pkg_upgrade.assert_called_once_with()
(target_charm.do_openstack_upgrade_config_render.
assert_called_once_with('int_list'))
(target_charm.do_openstack_upgrade_db_migration.
assert_called_once_with())
def test_do_openstack_pkg_upgrade_package(self):
self.patch_target('config',
@ -777,7 +781,7 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest):
'--option', 'Dpkg::Options::=--force-confnew', '--option',
'Dpkg::Options::=--force-confdef'])
self.apt_install.assert_called_once_with(
packages=['p1', 'p2', 'p3', 'package-to-filter'],
packages=self.target.all_packages,
options=[
'--option', 'Dpkg::Options::=--force-confnew', '--option',
'Dpkg::Options::=--force-confdef'],
@ -808,7 +812,7 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest):
'--option', 'Dpkg::Options::=--force-confnew', '--option',
'Dpkg::Options::=--force-confdef'])
self.apt_install.assert_called_once_with(
packages=['p1', 'p2', 'p3', 'package-to-filter'],
packages=self.target.all_packages,
options=[
'--option', 'Dpkg::Options::=--force-confnew', '--option',
'Dpkg::Options::=--force-confdef'],
@ -824,7 +828,8 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest):
def test_do_openstack_upgrade_config_render(self):
self.patch_target('render_with_interfaces')
self.target.do_openstack_upgrade_config_render('int_list')
self.render_with_interfaces.assert_called_once_with('int_list')
self.target.render_with_interfaces.assert_called_once_with(
'int_list')
def test_do_openstack_upgrade_db_migration(self):
self.patch_object(chm_core.hookenv, 'is_leader')