diff --git a/unit_tests/utilities/test_zaza_utilities_upgrade_utils.py b/unit_tests/utilities/test_zaza_utilities_upgrade_utils.py index f42ba5a..986ba38 100644 --- a/unit_tests/utilities/test_zaza_utilities_upgrade_utils.py +++ b/unit_tests/utilities/test_zaza_utilities_upgrade_utils.py @@ -116,6 +116,21 @@ class TestUpgradeUtils(ut_utils.BaseTestCase): self.assertEqual( actual, expected) + # test that, at focal, there are no database services. + expected = [ + ('Database Services', []), + ('Stateful Services', []), + ('Core Identity', []), + ('Control Plane', ['cinder']), + ('Data Plane', ['nova-compute']), + ('sweep_up', ['ntp'])] + actual = openstack_upgrade.get_series_upgrade_groups( + target_series='focal') + pprint.pprint(expected) + pprint.pprint(actual) + self.assertEqual( + actual, + expected) def test_extract_charm_name_from_url(self): self.assertEqual( diff --git a/zaza/openstack/charm_tests/rabbitmq_server/tests.py b/zaza/openstack/charm_tests/rabbitmq_server/tests.py index fed72df..6ee156e 100644 --- a/zaza/openstack/charm_tests/rabbitmq_server/tests.py +++ b/zaza/openstack/charm_tests/rabbitmq_server/tests.py @@ -26,8 +26,8 @@ import zaza.model import zaza.openstack.charm_tests.test_utils as test_utils import zaza.openstack.utilities.generic as generic_utils -from charmhelpers.core.host import CompareHostReleases from zaza.openstack.utilities.generic import get_series +from zaza.openstack.utilities.os_versions import CompareHostReleases from . import utils as rmq_utils from .utils import RmqNoMessageException diff --git a/zaza/openstack/charm_tests/series_upgrade/parallel_tests.py b/zaza/openstack/charm_tests/series_upgrade/parallel_tests.py index e524fa2..4dd2432 100644 --- a/zaza/openstack/charm_tests/series_upgrade/parallel_tests.py +++ b/zaza/openstack/charm_tests/series_upgrade/parallel_tests.py @@ -73,7 +73,8 @@ class ParallelSeriesUpgradeTest(unittest.TestCase): # Set Feature Flag os.environ["JUJU_DEV_FEATURE_FLAGS"] = "upgrade-series" upgrade_groups = upgrade_utils.get_series_upgrade_groups( - extra_filters=[_filter_etcd, _filter_easyrsa]) + extra_filters=[_filter_etcd, _filter_easyrsa], + target_series=self.to_series) from_series = self.from_series to_series = self.to_series completed_machines = [] diff --git a/zaza/openstack/charm_tests/series_upgrade/tests.py b/zaza/openstack/charm_tests/series_upgrade/tests.py index 122af11..3bb37ed 100644 --- a/zaza/openstack/charm_tests/series_upgrade/tests.py +++ b/zaza/openstack/charm_tests/series_upgrade/tests.py @@ -193,7 +193,8 @@ class ParallelSeriesUpgradeTest(unittest.TestCase): os.environ["JUJU_DEV_FEATURE_FLAGS"] = "upgrade-series" upgrade_groups = upgrade_utils.get_series_upgrade_groups( extra_filters=[upgrade_utils._filter_etcd, - upgrade_utils._filter_easyrsa]) + upgrade_utils._filter_easyrsa], + target_series=self.to_series) applications = model.get_status().applications completed_machines = [] for group_name, group in upgrade_groups: diff --git a/zaza/openstack/utilities/os_versions.py b/zaza/openstack/utilities/os_versions.py index e67a97f..d69f9cf 100644 --- a/zaza/openstack/utilities/os_versions.py +++ b/zaza/openstack/utilities/os_versions.py @@ -278,3 +278,105 @@ PACKAGE_CODENAMES = { ('4', 'victoria'), ]), } + + +UBUNTU_RELEASES = ( + 'lucid', + 'maverick', + 'natty', + 'oneiric', + 'precise', + 'quantal', + 'raring', + 'saucy', + 'trusty', + 'utopic', + 'vivid', + 'wily', + 'xenial', + 'yakkety', + 'zesty', + 'artful', + 'bionic', + 'cosmic', + 'disco', + 'eoan', + 'focal', + 'groovy', + 'hirsute', + 'impish', +) + + +class BasicStringComparator(object): + """Provides a class that will compare strings from an iterator type object. + + Used to provide > and < comparisons on strings that may not necessarily be + alphanumerically ordered. e.g. OpenStack or Ubuntu releases AFTER the + z-wrap. + """ + + _list = None + + def __init__(self, item): + """Do init.""" + if self._list is None: + raise Exception("Must define the _list in the class definition!") + try: + self.index = self._list.index(item) + except Exception: + raise KeyError("Item '{}' is not in list '{}'" + .format(item, self._list)) + + def __eq__(self, other): + """Do equals.""" + assert isinstance(other, str) or isinstance(other, self.__class__) + return self.index == self._list.index(other) + + def __ne__(self, other): + """Do not equals.""" + return not self.__eq__(other) + + def __lt__(self, other): + """Do less than.""" + assert isinstance(other, str) or isinstance(other, self.__class__) + return self.index < self._list.index(other) + + def __ge__(self, other): + """Do greater than or equal.""" + return not self.__lt__(other) + + def __gt__(self, other): + """Do greater than.""" + assert isinstance(other, str) or isinstance(other, self.__class__) + return self.index > self._list.index(other) + + def __le__(self, other): + """Do less than or equals.""" + return not self.__gt__(other) + + def __str__(self): + """Give back the item at the index. + + This is so it can be used in comparisons like: + + s_mitaka = CompareOpenStack('mitaka') + s_newton = CompareOpenstack('newton') + + assert s_newton > s_mitaka + + :returns: + """ + return self._list[self.index] + + +class CompareHostReleases(BasicStringComparator): + """Provide comparisons of Ubuntu releases. + + Use in the form of + + if CompareHostReleases(release) > 'trusty': + # do something with mitaka + """ + + _list = UBUNTU_RELEASES diff --git a/zaza/openstack/utilities/upgrade_utils.py b/zaza/openstack/utilities/upgrade_utils.py index ecc0b8b..6ce7254 100644 --- a/zaza/openstack/utilities/upgrade_utils.py +++ b/zaza/openstack/utilities/upgrade_utils.py @@ -24,6 +24,7 @@ from zaza.openstack.utilities.os_versions import ( OPENSTACK_CODENAMES, UBUNTU_OPENSTACK_RELEASE, OPENSTACK_RELEASES_PAIRS, + CompareHostReleases, ) """ @@ -96,6 +97,25 @@ def _filter_openstack_upgrade_list(app, app_config, model_name=None): return False +def _make_filter_percona_cluster_at(target_series): + def _filter_percona_cluster(app, app_config, model_name=None): + charm_name = extract_charm_name_from_url(app_config['charm']) + if charm_name == "percona-cluster": + logging.warning( + "Excluding percona-cluster from upgrade, " + "as no candidate in %s", target_series) + return True + return False + + def _noop_filter(*args, **kwargs): + return False + + if target_series and CompareHostReleases(target_series) >= "focal": + return _filter_percona_cluster + + return _noop_filter + + def _filter_non_openstack_services(app, app_config, model_name=None): charm_options = zaza.model.get_application_config( app, model_name=model_name).keys() @@ -168,7 +188,8 @@ def get_upgrade_groups(model_name=None, extra_filters=None): return _build_service_groups(apps_in_model) -def get_series_upgrade_groups(model_name=None, extra_filters=None): +def get_series_upgrade_groups(model_name=None, extra_filters=None, + target_series=None): """Place apps in the model into their upgrade groups. Place apps in the model into their upgrade groups. If an app is deployed @@ -176,10 +197,17 @@ def get_series_upgrade_groups(model_name=None, extra_filters=None): :param model_name: Name of model to query. :type model_name: str + :param extra_filters: filters to apply to the upgrade groups + :type extra_filters: Callable + :param target_series: The series that will be series upgraded to. + :type target_series: Optional[str] :returns: List of tuples(group name, applications) :rtype: List[Tuple[str, Dict[str, ANY]]] """ - filters = [_filter_subordinates] + filters = [ + _filter_subordinates, + _make_filter_percona_cluster_at(target_series), + ] filters = _apply_extra_filters(filters, extra_filters) apps_in_model = get_upgrade_candidates( model_name=model_name,