From 7113c1c99b2632f413e5df938c074cae90d50644 Mon Sep 17 00:00:00 2001 From: Igor Soares Date: Thu, 16 May 2024 18:20:23 -0300 Subject: [PATCH] Prevent app incompatibility gap during k8s upgrade Introduce an additional check to block Kubernetes upgrades on the kube-upgrade-start step if applied apps marked to be post updated are incompatible with the target k8s version. This will prevent incompatibility gaps in the upgrade process, i.e. avoiding that the post-update stage is reached while running an incompatible app. Application developers can leverage the auto update feature and the pre-update step in case incompatible apps need to be updated before deploying a new Kubernetes version. Test Plan: PASS: build-pkgs -a && build-image. PASS: Deploy platform with Kubernetes 1.24. Apply a metrics-server version containing supported_k8s_version:minimum: 1.24 and supported_k8s_version:maximum: 1.27. Add a new metrics-server bundle containing supported_k8s_version:minimum: 1.28 and supported_k8s_version:maximum: 1.29. Start Kubernetes upgrade to 1.28. Confirm that the upgrade was blocked. PASS: Deploy platform with Kubernetes 1.24. Apply a metrics-server version containing supported_k8s_version:minimum: 1.24 and supported_k8s_version:maximum: 1.28. Add a new metrics-server bundle containing supported_k8s_version:minimum: 1.28 and supported_k8s_version:maximum: 1.29. Start Kubernetes upgrade to 1.28. Confirm that metrics-server is updated during post-update step. Closes-Bug: 2066042 Change-Id: Ie5d7e872ae49f833bf1cf1a4eb80a7f50dad8920 Signed-off-by: Igor Soares --- .../sysinv/api/controllers/v1/kube_upgrade.py | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/kube_upgrade.py b/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/kube_upgrade.py index b47a7bd15f..a4a948b68e 100755 --- a/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/kube_upgrade.py +++ b/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/kube_upgrade.py @@ -194,13 +194,27 @@ class KubeUpgradeController(rest.RestController): LOG.debug("Unable to find a version of application {} to be pre updated." .format(app.name)) - # Applications with timing=post should be compatible with the target k8s version. - # Compatibility with current or intermediate versions is not required: - post_update_compatible = \ - pecan.request.dbapi.kube_app_bundle_is_k8s_compatible( - name=app.name, - k8s_timing=constants.APP_METADATA_TIMING_POST, - target_k8s_version=to_version) + # Check if the target version is within the range of the applied app + post_update_compatible = False + applied_app_target_compatible = False + applied_app_kube_min_version, applied_app_kube_max_version = \ + cutils.get_app_supported_kube_version(app.name, app.app_version) + if applied_app_kube_min_version is not None: + applied_app_kube_min_version = str(applied_app_kube_min_version).lstrip('v') + if applied_app_kube_max_version is not None: + applied_app_kube_max_version = str(applied_app_kube_max_version).lstrip('v') + if kubernetes.is_kube_version_supported( + to_version, applied_app_kube_min_version, applied_app_kube_max_version): + applied_app_target_compatible = True + + # Applications with timing=post should be compatible with the target k8s version. + # Compatibility with current or intermediate versions is not required: + post_update_compatible = \ + pecan.request.dbapi.kube_app_bundle_is_k8s_compatible( + name=app.name, + k8s_timing=constants.APP_METADATA_TIMING_POST, + target_k8s_version=to_version) + if not post_update_compatible: LOG.debug("Unable to find a version of application {} to be post updated." .format(app.name)) @@ -208,10 +222,7 @@ class KubeUpgradeController(rest.RestController): if not pre_update_compatible and not post_update_compatible: # If the app cannot be pre or post updated, check if we can proceed with # the current applied version. - applied_app_kube_min_version, applied_app_kube_max_version = \ - cutils.get_app_supported_kube_version(app.name, app.app_version) - if kubernetes.is_kube_version_supported( - to_version, applied_app_kube_min_version, applied_app_kube_max_version): + if applied_app_target_compatible: LOG.info("No updates found for application {} during Kubernetes upgrade " "to {} but current applied version {} is supported.".format( app.name,