some refactoring and updates from review
This commit is contained in:
committed by
Chris MacNaughton
parent
0a94b97cf4
commit
d4ee838d4b
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user