From b1b160f48bab21af56b617a911218877cde13550 Mon Sep 17 00:00:00 2001 From: Igor Soares Date: Tue, 19 Mar 2024 17:29:11 -0300 Subject: [PATCH] Fix charts upload when there are existing ones This fixes a bug that prevents StarlingX application charts from being uploaded to the helm repository when one or more of them have been uploaded before. The charts upload logic was changed to check if all charts provided by the given application are valid prior to uploading. If a chart is invalid then no charts for that application will be uploaded, since the upload process cannot proceed in that scenario. Test Plan: PASS: build-pkgs -a && build-image PASS: AIO-SX fresh install PASS: Build a platform-integ-apps version containing one existing chart and two nonexistent charts in the local Helm repository. Update platform-integ-apps to the built version. Confirm that the existing chart was not re-uploaded and that the nonexistent ones were correctly uploaded to the Helm repository. PASS: Apply/remove/delete platform-integ-apps Closes-Bug: 2053074 Depends-on: https://review.opendev.org/c/starlingx/integ/+/912305 Change-Id: I155d457f58be1986cc6f25178929aedfbe1d0693 Signed-off-by: Igor Soares --- .../sysinv/sysinv/conductor/kube_app.py | 39 +++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/sysinv/sysinv/sysinv/sysinv/conductor/kube_app.py b/sysinv/sysinv/sysinv/sysinv/conductor/kube_app.py index bc492e0284..9f0e8db1a4 100644 --- a/sysinv/sysinv/sysinv/sysinv/conductor/kube_app.py +++ b/sysinv/sysinv/sysinv/sysinv/conductor/kube_app.py @@ -1,6 +1,6 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 # -# Copyright (c) 2018-2023 Wind River Systems, Inc. +# Copyright (c) 2018-2024 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -948,8 +948,32 @@ class AppOperator(object): os.chown(constants.APP_INSTALL_ROOT_PATH, orig_uid, grp.getgrnam(constants.SYSINV_SYSADMIN_GRPNAME).gr_gid) with open(os.devnull, "w") as fnull: + + # Check if all charts are good to be uploaded + charts_to_upload = set() for chart in charts: - subprocess.check_call(['helm-upload', helm_repo, chart], # pylint: disable=not-callable + try: + subprocess.check_call(['helm-upload', # pylint: disable=not-callable + 'check-only', + helm_repo, chart], + env=env, stdout=fnull, stderr=fnull) + charts_to_upload.add(chart) + LOG.debug("Helm chart %s ready to be uploaded" % os.path.basename(chart)) + except subprocess.CalledProcessError as e: + if e.returncode == CHART_UPLOAD_FILE_EXISTS_ERROR_CODE: + # If the exact same chart already exists then just log a + # warning and proceed with the upload process. + LOG.warning("Chart %s already exists in the %s repository. " + "Skipping upload." % (os.path.basename(chart), helm_repo)) + continue + else: + raise + + # All charts checked. They can be uploaded now. + for chart in charts_to_upload: + subprocess.check_call(['helm-upload', # pylint: disable=not-callable + 'upload-only', + helm_repo, chart], env=env, stdout=fnull, stderr=fnull) LOG.info("Helm chart %s uploaded" % os.path.basename(chart)) @@ -960,12 +984,6 @@ class AppOperator(object): if e.returncode == CHART_UPLOAD_COPY_ERROR_CODE: reason = "Error while copying chart file %s to %s repository" \ % (chart, helm_repo) - elif e.returncode == CHART_UPLOAD_FILE_EXISTS_ERROR_CODE: - # If the exact same chart already exists then just log a - # warning and proceed with the upload process. - LOG.warning("Chart %s already exists in the %s repository. " - "Skipping upload." % - (os.path.basename(chart), helm_repo)) elif e.returncode == CHART_UPLOAD_VERSION_EXISTS_ERROR_CODE: reason = "The incoming chart %s matches the same version of " \ "an existing chart in the %s repository that " \ @@ -974,9 +992,8 @@ class AppOperator(object): else: reason = str(e) - if e.returncode != CHART_UPLOAD_FILE_EXISTS_ERROR_CODE: - raise exception.KubeAppUploadFailure( - name=app.name, version=app.version, reason=reason) + raise exception.KubeAppUploadFailure( + name=app.name, version=app.version, reason=reason) except Exception as e: raise exception.KubeAppUploadFailure( name=app.name, version=app.version, reason=str(e))