Merge "Introduce multi-version auto downgrade for apps"
This commit is contained in:
commit
37beadd020
|
@ -381,6 +381,13 @@ def validate_metadata_file(path, metadata_file, upgrade_from_release=None):
|
||||||
for version in from_versions:
|
for version in from_versions:
|
||||||
validate_string(version)
|
validate_string(version)
|
||||||
|
|
||||||
|
# Downgrades section validation
|
||||||
|
downgrades = validate_dict_field(doc, constants.APP_METADATA_DOWNGRADES)
|
||||||
|
if downgrades:
|
||||||
|
validate_boolstr_field(
|
||||||
|
downgrades,
|
||||||
|
constants.APP_METADATA_AUTO_DOWNGRADE)
|
||||||
|
|
||||||
# Kubernetes version section validation
|
# Kubernetes version section validation
|
||||||
k8s_version = validate_k8s_version(doc)
|
k8s_version = validate_k8s_version(doc)
|
||||||
if k8s_version:
|
if k8s_version:
|
||||||
|
|
|
@ -1988,6 +1988,9 @@ APP_METADATA_UPGRADES = 'upgrades'
|
||||||
APP_METADATA_UPDATE_FAILURE_SKIP_RECOVERY = 'update_failure_no_rollback'
|
APP_METADATA_UPDATE_FAILURE_SKIP_RECOVERY = 'update_failure_no_rollback'
|
||||||
APP_METADATA_AUTO_UPDATE = 'auto_update'
|
APP_METADATA_AUTO_UPDATE = 'auto_update'
|
||||||
APP_METADATA_AUTO_UPDATE_DEFAULT_VALUE = True
|
APP_METADATA_AUTO_UPDATE_DEFAULT_VALUE = True
|
||||||
|
APP_METADATA_DOWNGRADES = 'downgrades'
|
||||||
|
APP_METADATA_AUTO_DOWNGRADE = 'auto_downgrade'
|
||||||
|
APP_METADATA_AUTO_DOWNGRADE_DEFAULT_VALUE = True
|
||||||
APP_METADATA_FAILED_VERSIONS = 'failed_versions'
|
APP_METADATA_FAILED_VERSIONS = 'failed_versions'
|
||||||
APP_METADATA_FROM_VERSIONS = 'from_versions'
|
APP_METADATA_FROM_VERSIONS = 'from_versions'
|
||||||
APP_METADATA_SUPPORTED_K8S_VERSION = 'supported_k8s_version'
|
APP_METADATA_SUPPORTED_K8S_VERSION = 'supported_k8s_version'
|
||||||
|
|
|
@ -53,6 +53,7 @@ import xml.etree.ElementTree as ElementTree
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
from distutils.util import strtobool
|
||||||
from distutils.version import LooseVersion
|
from distutils.version import LooseVersion
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from urllib3.exceptions import MaxRetryError
|
from urllib3.exceptions import MaxRetryError
|
||||||
|
@ -7805,6 +7806,11 @@ class ConductorManager(service.PeriodicService):
|
||||||
True,
|
True,
|
||||||
k8s_upgrade_timing)
|
k8s_upgrade_timing)
|
||||||
|
|
||||||
|
auto_downgrade = strtobool(app.app_metadata.get(constants.APP_METADATA_DOWNGRADES, {})
|
||||||
|
.get(constants.APP_METADATA_AUTO_DOWNGRADE,
|
||||||
|
str(constants.APP_METADATA_AUTO_DOWNGRADE_DEFAULT_VALUE)))
|
||||||
|
latest_downgrade_bundle = None
|
||||||
|
available_versions = set()
|
||||||
latest_version_bundle = None
|
latest_version_bundle = None
|
||||||
|
|
||||||
if k8s_version is None:
|
if k8s_version is None:
|
||||||
|
@ -7813,15 +7819,8 @@ class ConductorManager(service.PeriodicService):
|
||||||
k8s_version = k8s_version.strip().lstrip('v')
|
k8s_version = k8s_version.strip().lstrip('v')
|
||||||
|
|
||||||
for bundle_metadata in bundle_metadata_list:
|
for bundle_metadata in bundle_metadata_list:
|
||||||
if LooseVersion(bundle_metadata.version) <= LooseVersion(app.app_version):
|
available_versions.add(bundle_metadata.version)
|
||||||
LOG.debug("Bundle {} version {} lower than installed app version ({})"
|
if LooseVersion(k8s_version) < LooseVersion(bundle_metadata.k8s_minimum_version):
|
||||||
.format(bundle_metadata.file_path,
|
|
||||||
bundle_metadata.version,
|
|
||||||
app.app_version))
|
|
||||||
elif not bundle_metadata.auto_update:
|
|
||||||
LOG.debug("Application auto update disabled for bundle {}"
|
|
||||||
.format(bundle_metadata.file_path))
|
|
||||||
elif LooseVersion(k8s_version) < LooseVersion(bundle_metadata.k8s_minimum_version):
|
|
||||||
LOG.debug("Kubernetes version {} is lower than {} which is "
|
LOG.debug("Kubernetes version {} is lower than {} which is "
|
||||||
"the minimum required for bundle {}"
|
"the minimum required for bundle {}"
|
||||||
.format(k8s_version,
|
.format(k8s_version,
|
||||||
|
@ -7834,6 +7833,21 @@ class ConductorManager(service.PeriodicService):
|
||||||
.format(k8s_version,
|
.format(k8s_version,
|
||||||
bundle_metadata.k8s_maximum_version,
|
bundle_metadata.k8s_maximum_version,
|
||||||
bundle_metadata.file_path))
|
bundle_metadata.file_path))
|
||||||
|
elif LooseVersion(bundle_metadata.version) == LooseVersion(app.app_version):
|
||||||
|
LOG.debug("Bundle {} version and installed app version are the same ({})"
|
||||||
|
.format(bundle_metadata.file_path,
|
||||||
|
app.app_version))
|
||||||
|
elif LooseVersion(bundle_metadata.version) < LooseVersion(app.app_version):
|
||||||
|
LOG.debug("Bundle {} version {} is lower than installed app version ({})"
|
||||||
|
.format(bundle_metadata.file_path,
|
||||||
|
bundle_metadata.version,
|
||||||
|
app.app_version))
|
||||||
|
if (latest_downgrade_bundle is None or LooseVersion(bundle_metadata.version) >
|
||||||
|
LooseVersion(latest_downgrade_bundle.version)):
|
||||||
|
latest_downgrade_bundle = bundle_metadata
|
||||||
|
elif not bundle_metadata.auto_update:
|
||||||
|
LOG.debug("Application auto update disabled for bundle {}"
|
||||||
|
.format(bundle_metadata.file_path))
|
||||||
elif ((latest_version_bundle is None) or
|
elif ((latest_version_bundle is None) or
|
||||||
(LooseVersion(bundle_metadata.version) >
|
(LooseVersion(bundle_metadata.version) >
|
||||||
LooseVersion(latest_version_bundle.version))):
|
LooseVersion(latest_version_bundle.version))):
|
||||||
|
@ -7841,6 +7855,15 @@ class ConductorManager(service.PeriodicService):
|
||||||
# of the current one is higher than the one previously set.
|
# of the current one is higher than the one previously set.
|
||||||
latest_version_bundle = bundle_metadata
|
latest_version_bundle = bundle_metadata
|
||||||
|
|
||||||
|
# Downgrade if the installed app version is not available anymore and an older compatible
|
||||||
|
# bundle is available instead.
|
||||||
|
if (auto_downgrade and
|
||||||
|
app.app_version not in available_versions and
|
||||||
|
latest_downgrade_bundle is not None):
|
||||||
|
LOG.info("Application {} will be downgraded from version {} to {}"
|
||||||
|
.format(app.name, app.app_version, latest_downgrade_bundle.version))
|
||||||
|
return latest_downgrade_bundle
|
||||||
|
|
||||||
return latest_version_bundle
|
return latest_version_bundle
|
||||||
|
|
||||||
def _auto_update_app(self,
|
def _auto_update_app(self,
|
||||||
|
|
Loading…
Reference in New Issue