some refactoring and updates from review

This commit is contained in:
Chris MacNaughton
2020-03-19 12:16:18 +01:00
committed by Chris MacNaughton
parent 0a94b97cf4
commit d4ee838d4b
3 changed files with 104 additions and 37 deletions

View File

@@ -233,12 +233,8 @@ class ParallelSeriesUpgradeTest(unittest.TestCase):
"""Run series upgrade."""
# Set Feature Flag
os.environ["JUJU_DEV_FEATURE_FLAGS"] = "upgrade-series"
upgrade_groups = upgrade_utils.get_upgrade_groups()
upgrade_groups = upgrade_utils.get_series_upgrade_groups()
applications = model.get_status().applications
upgrade_groups['support'] = [
app for app in upgrade_utils.UPGRADE_EXCLUDE_LIST
if app in applications.keys()]
upgrade_groups['deferred'] = []
completed_machines = []
for group_name, group in upgrade_groups.items():
logging.warn("About to upgrade {} ({})".format(group_name, group))
@@ -249,16 +245,6 @@ class ParallelSeriesUpgradeTest(unittest.TestCase):
pause_non_leader_subordinate = True
pause_non_leader_primary = True
post_upgrade_functions = []
name = upgrade_utils.extract_charm_name_from_url(
app_details['charm'])
if name not in group and application not in group:
if group_name != "deferred" and \
name not in upgrade_groups['deferred']:
upgrade_groups['deferred'].append(name)
continue
if group_name != "deferred" and \
name in upgrade_groups['deferred']:
upgrade_groups['deferred'].remove(name)
# Skip subordinates
if app_details["subordinate-to"]:
continue

View File

@@ -14,6 +14,8 @@
"""Collection of functions for testing series upgrade."""
import collections
import copy
import concurrent
import logging
import os
@@ -40,6 +42,34 @@ def run_post_upgrade_functions(post_upgrade_functions):
cl_utils.get_class(func)()
def get_charm_settings():
default = {
'origin': 'openstack-origin',
'pause_non_leader_subordinate': True,
'pause_non_leader_primary': True,
'upgrade_function': async_series_upgrade_application,
'post_upgrade_functions': []}
_app_settings = collections.defaultdict(lambda: default)
exceptions = {
'rabbitmq-server': {
'origin': 'source',
'pause_non_leader_subordinate': False},
'percona-cluster': {'origin': 'source'},
'nova-compute' : {
'pause_non_leader_primary': False,
'pause_non_leader_subordinate': False},
'mongodb': {
'upgrade_function': async_series_upgrade_non_leaders_first,
'origin': None,
}}
for key, value in exceptions.items():
_app_settings[key] = copy.deepcopy(default)
_app_settings[key].update(value)
return _app_settings
def series_upgrade_non_leaders_first(application, from_series="trusty",
to_series="xenial",
completed_machines=[],
@@ -283,7 +313,8 @@ async def async_series_upgrade_application(application,
origin='openstack-origin',
completed_machines=None,
files=None, workaround_script=None,
post_upgrade_functions=None):
post_upgrade_functions=None,
post_application_upgrade_functions=None):
"""Series upgrade application.
Wrap all the functionality to handle series upgrade for a given
@@ -312,6 +343,13 @@ async def async_series_upgrade_application(application,
:type files: list
:param workaround_script: Workaround script to run during series upgrade
:type workaround_script: str
:param post_upgrade_functions: A list of functions to call after upgrading
each unit of an application
:type post_upgrade_functions: List[fn]
:param post_application_upgrade_functions: A list of functions to call
once after updating all units
of an application
:type post_application_upgrade_functions: List[fn]
:returns: None
:rtype: None
"""
@@ -391,6 +429,7 @@ async def async_series_upgrade_application(application,
logging.info("Set origin on {}".format(application))
await os_utils.async_set_origin(application, origin)
await wait_for_unit_idle(unit)
run_post_upgrade_functions(post_application_upgrade_functions)
# TODO: Move these functions into zaza.model

View File

@@ -34,41 +34,54 @@ SERVICE_GROUPS = collections.OrderedDict([
UPGRADE_EXCLUDE_LIST = ['rabbitmq-server', 'percona-cluster']
def get_upgrade_candidates(model_name=None):
def get_upgrade_candidates(model_name=None, filters=None):
"""Extract list of apps from model that can be upgraded.
:param model_name: Name of model to query.
:type model_name: str
:param filters: List of filter functions to apply
:type filters: List[fn]
:returns: List of application that can have their payload upgraded.
:rtype: []
"""
if filters is None:
filters = []
status = zaza.model.get_status(model_name=model_name)
candidates = {}
for app, app_config in status.applications.items():
# Filter out subordinates
if app_config.get("subordinate-to"):
logging.warning(
"Excluding {} from upgrade, it is a subordinate".format(app))
continue
for f in filters:
if f(app, model_name=model_name):
continue
candidates[app] = app_config
return candidates
# Filter out charms on the naughty list
charm_name = extract_charm_name_from_url(app_config['charm'])
if app in UPGRADE_EXCLUDE_LIST or charm_name in UPGRADE_EXCLUDE_LIST:
logging.warning(
"Excluding {} from upgrade, on the exclude list".format(app))
continue
# Filter out charms that have no source option
def _filter_subordinates(app, model_name=None):
if app_config.get("subordinate-to"):
logging.warning(
"Excluding {} from upgrade, it is a subordinate".format(app))
return True
return False
def _filter_openstack_upgrade_list(app, model_name=None):
charm_name = extract_charm_name_from_url(app_config['charm'])
if app in UPGRADE_EXCLUDE_LIST or charm_name in UPGRADE_EXCLUDE_LIST:
logging.warning(
"Excluding {} from upgrade, on the exclude list".format(app))
return True
return False
def _filter_non_openstack_services(app, model_name=None):
charm_options = zaza.model.get_application_config(
app, model_name=model_name).keys()
src_options = ['openstack-origin', 'source']
if not [x for x in src_options if x in charm_options]:
logging.warning(
"Excluding {} from upgrade, no src option".format(app))
continue
candidates[app] = app_config
return candidates
return True
return False
def get_upgrade_groups(model_name=None):
@@ -82,26 +95,55 @@ def get_upgrade_groups(model_name=None):
:returns: Dict of group lists keyed on group name.
:rtype: collections.OrderedDict
"""
apps_in_model = get_upgrade_candidates(model_name=model_name)
apps_in_model = get_upgrade_candidates(
model_name=model_name,
filters=[
_filter_subordinates,
_filter_openstack_upgrade_list,
_filter_non_openstack_services,
])
return _build_service_groups(apps_in_model)
def get_series_upgrade_groups(model_name=None):
"""Place apps in the model into their upgrade groups.
Place apps in the model into their upgrade groups. If an app is deployed
but is not in SERVICE_GROUPS then it is placed in a sweep_up group.
:param model_name: Name of model to query.
:type model_name: str
:returns: Dict of group lists keyed on group name.
:rtype: collections.OrderedDict
"""
apps_in_model = get_upgrade_candidates(
model_name=model_name,
filters=[
_filter_subordinates,
])
return _build_service_groups(apps_in_model)
def _build_service_groups(applications):
groups = collections.OrderedDict()
for phase_name, charms in SERVICE_GROUPS.items():
group = []
for app, app_config in apps_in_model.items():
for app, app_config in applications.items():
charm_name = extract_charm_name_from_url(app_config['charm'])
if charm_name in charms:
group.append(app)
groups[phase_name] = group
sweep_up = []
for app in apps_in_model:
for app in applications:
if not (app in [a for group in groups.values() for a in group]):
sweep_up.append(app)
groups['sweep_up'] = sweep_up
return groups
def extract_charm_name_from_url(charm_url):
"""Extract the charm name from the charm url.