From e237048bf8dbcfc79df28a700b4ad36d5739d06b Mon Sep 17 00:00:00 2001 From: Sanjay Prabhakar Date: Thu, 3 Apr 2025 19:18:46 +0100 Subject: [PATCH 01/11] [patch] patch pending PVC for tekton postgres --- src/mas/devops/ocp.py | 49 ++++++++++++++++++++++++++++++++++++++++ src/mas/devops/tekton.py | 20 ++++++++++++++-- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/src/mas/devops/ocp.py b/src/mas/devops/ocp.py index 2aa9e0b9..9fa0d25a 100644 --- a/src/mas/devops/ocp.py +++ b/src/mas/devops/ocp.py @@ -157,6 +157,55 @@ def waitForDeployment(dynClient: DynamicClient, namespace: str, deploymentName: sleep(5) return foundReadyDeployment +def waitForPVC(dynClient: DynamicClient, namespace: str, pvcName: str) -> bool: + pvcAPI = dynClient.resources.get(api_version="v1", kind="PersistentVolumeClaim") + maxRetries = 60 + foundReadyPVC = False + retries = 0 + while not foundReadyPVC and retries < maxRetries: + retries += 1 + try: + pvc = pvcAPI.get(name=pvcName, namespace=namespace) + if pvc.status.phase == "Bound": + foundReadyPVC = True + else: + logger.debug("Waiting 5s for PVC {pvcName} to be ready before checking again ...") + sleep(5) + except NotFoundError: + logger.debug("Waiting 5s for PVC {pvcName} to be created before checking again ...") + sleep(5) + return foundReadyPVC + + +def patchPendingPVC(dynClient: DynamicClient, namespace: str, pvcName: str, storageClassName: str) -> bool: + pvcAPI = dynClient.resources.get(api_version="v1", kind="PersistentVolumeClaim") + try: + pvc = pvcAPI.get(name=pvcName, namespace=namespace) + if pvc.status.phase == "Pending" and pvc.spec.storageClassName is None: + pvc.spec.storageClassName = storageClassName + pvcAPI.patch(body=pvc, namespace=namespace) + + maxRetries = 60 + foundReadyPVC = False + retries = 0 + while not foundReadyPVC and retries < maxRetries: + retries += 1 + try: + patchedPVC = pvcAPI.get(name=pvcName, namespace=namespace) + if patchedPVC.status.phase == "Bound": + foundReadyPVC = True + else: + logger.debug("Waiting 5s for PVC {pvcName} to be bound before checking again ...") + sleep(5) + except NotFoundError: + logger.error("The patched PVC {pvcName} does not exist.") + return False + + return foundReadyPVC + + except NotFoundError: + logger.error("PVC {pvcName} does not exist") + return False def getConsoleURL(dynClient: DynamicClient) -> str: routesAPI = dynClient.resources.get(api_version="route.openshift.io/v1", kind="Route") diff --git a/src/mas/devops/tekton.py b/src/mas/devops/tekton.py index 45539d14..6d175500 100644 --- a/src/mas/devops/tekton.py +++ b/src/mas/devops/tekton.py @@ -22,7 +22,7 @@ from jinja2 import Environment, FileSystemLoader -from .ocp import getConsoleURL, waitForCRD, waitForDeployment, crdExists +from .ocp import getConsoleURL, waitForCRD, waitForDeployment, waitForPVC, patchPendingPVC, crdExists logger = logging.getLogger(__name__) @@ -79,11 +79,27 @@ def installOpenShiftPipelines(dynClient: DynamicClient) -> bool: foundReadyWebhook = waitForDeployment(dynClient, namespace="openshift-pipelines", deploymentName="tekton-pipelines-webhook") if foundReadyWebhook: logger.info("OpenShift Pipelines Webhook is installed and ready") - return True else: logger.error("OpenShift Pipelines Webhook is NOT installed and ready") return False + # Wait for the postgredb-tekton-results-postgres-0 PVC to be ready + # this PVC doesn't come up when there's no default storage class is in the cluster, + # this is causing the pvc to be in pending state and causing the tekton-results-postgres statefulSet in pending, + # due to these resources not coming up, the MAS pre-install check in the pipeline times out checking the health of this statefulSet, + # causing failure in pipeline. + # Refer https://github.com/ibm-mas/cli/issues/1511 + logger.debug("Waiting for postgredb-tekton-results-postgres-0 PVC to be ready") + foundReadyPVC = waitForPVC(dynClient, namespace="openshift-pipelines", pvcName="postgredb-tekton-results-postgres-0") + if foundReadyPVC: + logger.info("OpenShift Pipelines postgres is installed and ready") + else: + patchedPVC = patchPVC(dynClient, namespace="openshift-pipelines", pvcName="postgredb-tekton-results-postgres-0") + if patchPVC: + logger.info("OpenShift Pipelines postgres is installed and ready") + else: + logger.error("OpenShift Pipelines postgres PVC is NOT ready") + def updateTektonDefinitions(namespace: str, yamlFile: str) -> None: """ From e9a7af685e390214b17415bff13a6f92b1693675 Mon Sep 17 00:00:00 2001 From: Sanjay Prabhakar Date: Fri, 4 Apr 2025 10:53:30 +0100 Subject: [PATCH 02/11] [patch] fix --- src/mas/devops/ocp.py | 12 ++++++++++-- src/mas/devops/tekton.py | 6 +++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/mas/devops/ocp.py b/src/mas/devops/ocp.py index 9fa0d25a..5cb3c9c6 100644 --- a/src/mas/devops/ocp.py +++ b/src/mas/devops/ocp.py @@ -20,6 +20,8 @@ from kubernetes.stream import stream from kubernetes.stream.ws_client import ERROR_CHANNEL +from .mas import getDefaultStorageClasses + import yaml logger = logging.getLogger(__name__) @@ -177,12 +179,18 @@ def waitForPVC(dynClient: DynamicClient, namespace: str, pvcName: str) -> bool: return foundReadyPVC -def patchPendingPVC(dynClient: DynamicClient, namespace: str, pvcName: str, storageClassName: str) -> bool: +def patchPendingPVC(dynClient: DynamicClient, namespace: str, pvcName: str, storageClassName: str = None) -> bool: pvcAPI = dynClient.resources.get(api_version="v1", kind="PersistentVolumeClaim") try: pvc = pvcAPI.get(name=pvcName, namespace=namespace) if pvc.status.phase == "Pending" and pvc.spec.storageClassName is None: - pvc.spec.storageClassName = storageClassName + if getStorageClasses is not None: + pvc.spec.storageClassName = storageClassName + else: + defaultStorageClasses = getDefaultStorageClasses(dynClient) + if defaultStorageClasses.provider is not None: + pvc.spec.storageClassName = defaultStorageClasses.rwo + pvcAPI.patch(body=pvc, namespace=namespace) maxRetries = 60 diff --git a/src/mas/devops/tekton.py b/src/mas/devops/tekton.py index 6d175500..535d238a 100644 --- a/src/mas/devops/tekton.py +++ b/src/mas/devops/tekton.py @@ -27,7 +27,7 @@ logger = logging.getLogger(__name__) -def installOpenShiftPipelines(dynClient: DynamicClient) -> bool: +def installOpenShiftPipelines(dynClient: DynamicClient, customStorageClassName: str = None) -> bool: """ Install the OpenShift Pipelines Operator and wait for it to be ready to use """ @@ -94,8 +94,8 @@ def installOpenShiftPipelines(dynClient: DynamicClient) -> bool: if foundReadyPVC: logger.info("OpenShift Pipelines postgres is installed and ready") else: - patchedPVC = patchPVC(dynClient, namespace="openshift-pipelines", pvcName="postgredb-tekton-results-postgres-0") - if patchPVC: + patchedPVC = patchPendingPVC(dynClient, namespace="openshift-pipelines", pvcName="postgredb-tekton-results-postgres-0", storageClassName=customStorageClassName) + if patchedPVC: logger.info("OpenShift Pipelines postgres is installed and ready") else: logger.error("OpenShift Pipelines postgres PVC is NOT ready") From 74d0a8472335567f65770f644ec39790f1899138 Mon Sep 17 00:00:00 2001 From: Sanjay Prabhakar Date: Fri, 4 Apr 2025 10:55:35 +0100 Subject: [PATCH 03/11] [patch] fix --- src/mas/devops/ocp.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mas/devops/ocp.py b/src/mas/devops/ocp.py index 5cb3c9c6..d57b726d 100644 --- a/src/mas/devops/ocp.py +++ b/src/mas/devops/ocp.py @@ -190,6 +190,9 @@ def patchPendingPVC(dynClient: DynamicClient, namespace: str, pvcName: str, stor defaultStorageClasses = getDefaultStorageClasses(dynClient) if defaultStorageClasses.provider is not None: pvc.spec.storageClassName = defaultStorageClasses.rwo + else: + logger.error("Unable to set storageClassName in PVC {pvcName}.") + return False pvcAPI.patch(body=pvc, namespace=namespace) From 5e0b4fc13fa45996d0cde3deb67097cd39da3def Mon Sep 17 00:00:00 2001 From: Sanjay Prabhakar Date: Fri, 4 Apr 2025 11:03:27 +0100 Subject: [PATCH 04/11] [patch] add comment --- src/mas/devops/tekton.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mas/devops/tekton.py b/src/mas/devops/tekton.py index 535d238a..3ea103af 100644 --- a/src/mas/devops/tekton.py +++ b/src/mas/devops/tekton.py @@ -26,7 +26,8 @@ logger = logging.getLogger(__name__) - +# customStorageClassName is used when no default Storageclass is available on cluster, +# openshift-pipelines creates PVC which looks for default. customStorageClassName is patched into PVC when default is unavailable. def installOpenShiftPipelines(dynClient: DynamicClient, customStorageClassName: str = None) -> bool: """ Install the OpenShift Pipelines Operator and wait for it to be ready to use From 8bb2e7090e8296db5f786e7ed121f29949b0b941 Mon Sep 17 00:00:00 2001 From: Sanjay Prabhakar Date: Mon, 7 Apr 2025 10:40:36 +0100 Subject: [PATCH 05/11] [patch] fix function --- src/mas/devops/ocp.py | 84 +++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/src/mas/devops/ocp.py b/src/mas/devops/ocp.py index d57b726d..08358102 100644 --- a/src/mas/devops/ocp.py +++ b/src/mas/devops/ocp.py @@ -159,6 +159,47 @@ def waitForDeployment(dynClient: DynamicClient, namespace: str, deploymentName: sleep(5) return foundReadyDeployment +def getConsoleURL(dynClient: DynamicClient) -> str: + routesAPI = dynClient.resources.get(api_version="route.openshift.io/v1", kind="Route") + consoleRoute = routesAPI.get(name="console", namespace="openshift-console") + return f"https://{consoleRoute.spec.host}" + + +def getNodes(dynClient: DynamicClient) -> str: + nodesAPI = dynClient.resources.get(api_version="v1", kind="Node") + nodes = nodesAPI.get().to_dict()['items'] + return nodes + + +def getStorageClass(dynClient: DynamicClient, name: str) -> str: + try: + storageClassAPI = dynClient.resources.get(api_version="storage.k8s.io/v1", kind="StorageClass") + storageclass = storageClassAPI.get(name=name) + return storageclass + except NotFoundError: + return None + + +def getStorageClasses(dynClient: DynamicClient) -> list: + storageClassAPI = dynClient.resources.get(api_version="storage.k8s.io/v1", kind="StorageClass") + storageClasses = storageClassAPI.get().items + return storageClasses + + +def isSNO(dynClient: DynamicClient) -> bool: + return len(getNodes(dynClient)) == 1 + + +def crdExists(dynClient: DynamicClient, crdName: str) -> bool: + crdAPI = dynClient.resources.get(api_version="apiextensions.k8s.io/v1", kind="CustomResourceDefinition") + try: + crdAPI.get(name=crdName) + logger.debug(f"CRD does exist: {crdName}") + return True + except NotFoundError: + logger.debug(f"CRD does not exist: {crdName}") + return False + def waitForPVC(dynClient: DynamicClient, namespace: str, pvcName: str) -> bool: pvcAPI = dynClient.resources.get(api_version="v1", kind="PersistentVolumeClaim") maxRetries = 60 @@ -184,7 +225,7 @@ def patchPendingPVC(dynClient: DynamicClient, namespace: str, pvcName: str, stor try: pvc = pvcAPI.get(name=pvcName, namespace=namespace) if pvc.status.phase == "Pending" and pvc.spec.storageClassName is None: - if getStorageClasses is not None: + if storageClassName is not None and storageClassName(dynClient, name=storageClassName) is not None: pvc.spec.storageClassName = storageClassName else: defaultStorageClasses = getDefaultStorageClasses(dynClient) @@ -218,47 +259,6 @@ def patchPendingPVC(dynClient: DynamicClient, namespace: str, pvcName: str, stor logger.error("PVC {pvcName} does not exist") return False -def getConsoleURL(dynClient: DynamicClient) -> str: - routesAPI = dynClient.resources.get(api_version="route.openshift.io/v1", kind="Route") - consoleRoute = routesAPI.get(name="console", namespace="openshift-console") - return f"https://{consoleRoute.spec.host}" - - -def getNodes(dynClient: DynamicClient) -> str: - nodesAPI = dynClient.resources.get(api_version="v1", kind="Node") - nodes = nodesAPI.get().to_dict()['items'] - return nodes - - -def getStorageClass(dynClient: DynamicClient, name: str) -> str: - try: - storageClassAPI = dynClient.resources.get(api_version="storage.k8s.io/v1", kind="StorageClass") - storageclass = storageClassAPI.get(name=name) - return storageclass - except NotFoundError: - return None - - -def getStorageClasses(dynClient: DynamicClient) -> list: - storageClassAPI = dynClient.resources.get(api_version="storage.k8s.io/v1", kind="StorageClass") - storageClasses = storageClassAPI.get().items - return storageClasses - - -def isSNO(dynClient: DynamicClient) -> bool: - return len(getNodes(dynClient)) == 1 - - -def crdExists(dynClient: DynamicClient, crdName: str) -> bool: - crdAPI = dynClient.resources.get(api_version="apiextensions.k8s.io/v1", kind="CustomResourceDefinition") - try: - crdAPI.get(name=crdName) - logger.debug(f"CRD does exist: {crdName}") - return True - except NotFoundError: - logger.debug(f"CRD does not exist: {crdName}") - return False - # Assisted by WCA@IBM # Latest GenAI contribution: ibm/granite-8b-code-instruct From f838c4e852940e377f67c4bd84ef6d7aa8833712 Mon Sep 17 00:00:00 2001 From: Sanjay Prabhakar Date: Mon, 7 Apr 2025 10:48:25 +0100 Subject: [PATCH 06/11] [patch] moved functions to mas.py --- src/mas/devops/mas.py | 60 +++++++++++++++++++++++++++++++++++++++ src/mas/devops/ocp.py | 61 ---------------------------------------- src/mas/devops/tekton.py | 3 +- 3 files changed, 62 insertions(+), 62 deletions(-) diff --git a/src/mas/devops/mas.py b/src/mas/devops/mas.py index 2bb18640..f405278d 100644 --- a/src/mas/devops/mas.py +++ b/src/mas/devops/mas.py @@ -12,6 +12,7 @@ import re import yaml from os import path +from time import sleep from types import SimpleNamespace from kubernetes.dynamic.resource import ResourceInstance from openshift.dynamic import DynamicClient @@ -194,3 +195,62 @@ def updateIBMEntitlementKey(dynClient: DynamicClient, namespace: str, icrUsernam secret = secretsAPI.apply(body=secret, namespace=namespace) return secret + +def waitForPVC(dynClient: DynamicClient, namespace: str, pvcName: str) -> bool: + pvcAPI = dynClient.resources.get(api_version="v1", kind="PersistentVolumeClaim") + maxRetries = 60 + foundReadyPVC = False + retries = 0 + while not foundReadyPVC and retries < maxRetries: + retries += 1 + try: + pvc = pvcAPI.get(name=pvcName, namespace=namespace) + if pvc.status.phase == "Bound": + foundReadyPVC = True + else: + logger.debug("Waiting 5s for PVC {pvcName} to be ready before checking again ...") + sleep(5) + except NotFoundError: + logger.debug("Waiting 5s for PVC {pvcName} to be created before checking again ...") + sleep(5) + return foundReadyPVC + + +def patchPendingPVC(dynClient: DynamicClient, namespace: str, pvcName: str, storageClassName: str = None) -> bool: + pvcAPI = dynClient.resources.get(api_version="v1", kind="PersistentVolumeClaim") + try: + pvc = pvcAPI.get(name=pvcName, namespace=namespace) + if pvc.status.phase == "Pending" and pvc.spec.storageClassName is None: + if storageClassName is not None and storageClassName(dynClient, name=storageClassName) is not None: + pvc.spec.storageClassName = storageClassName + else: + defaultStorageClasses = getDefaultStorageClasses(dynClient) + if defaultStorageClasses.provider is not None: + pvc.spec.storageClassName = defaultStorageClasses.rwo + else: + logger.error("Unable to set storageClassName in PVC {pvcName}.") + return False + + pvcAPI.patch(body=pvc, namespace=namespace) + + maxRetries = 60 + foundReadyPVC = False + retries = 0 + while not foundReadyPVC and retries < maxRetries: + retries += 1 + try: + patchedPVC = pvcAPI.get(name=pvcName, namespace=namespace) + if patchedPVC.status.phase == "Bound": + foundReadyPVC = True + else: + logger.debug("Waiting 5s for PVC {pvcName} to be bound before checking again ...") + sleep(5) + except NotFoundError: + logger.error("The patched PVC {pvcName} does not exist.") + return False + + return foundReadyPVC + + except NotFoundError: + logger.error("PVC {pvcName} does not exist") + return False diff --git a/src/mas/devops/ocp.py b/src/mas/devops/ocp.py index 08358102..ff7b5c28 100644 --- a/src/mas/devops/ocp.py +++ b/src/mas/devops/ocp.py @@ -20,8 +20,6 @@ from kubernetes.stream import stream from kubernetes.stream.ws_client import ERROR_CHANNEL -from .mas import getDefaultStorageClasses - import yaml logger = logging.getLogger(__name__) @@ -200,65 +198,6 @@ def crdExists(dynClient: DynamicClient, crdName: str) -> bool: logger.debug(f"CRD does not exist: {crdName}") return False -def waitForPVC(dynClient: DynamicClient, namespace: str, pvcName: str) -> bool: - pvcAPI = dynClient.resources.get(api_version="v1", kind="PersistentVolumeClaim") - maxRetries = 60 - foundReadyPVC = False - retries = 0 - while not foundReadyPVC and retries < maxRetries: - retries += 1 - try: - pvc = pvcAPI.get(name=pvcName, namespace=namespace) - if pvc.status.phase == "Bound": - foundReadyPVC = True - else: - logger.debug("Waiting 5s for PVC {pvcName} to be ready before checking again ...") - sleep(5) - except NotFoundError: - logger.debug("Waiting 5s for PVC {pvcName} to be created before checking again ...") - sleep(5) - return foundReadyPVC - - -def patchPendingPVC(dynClient: DynamicClient, namespace: str, pvcName: str, storageClassName: str = None) -> bool: - pvcAPI = dynClient.resources.get(api_version="v1", kind="PersistentVolumeClaim") - try: - pvc = pvcAPI.get(name=pvcName, namespace=namespace) - if pvc.status.phase == "Pending" and pvc.spec.storageClassName is None: - if storageClassName is not None and storageClassName(dynClient, name=storageClassName) is not None: - pvc.spec.storageClassName = storageClassName - else: - defaultStorageClasses = getDefaultStorageClasses(dynClient) - if defaultStorageClasses.provider is not None: - pvc.spec.storageClassName = defaultStorageClasses.rwo - else: - logger.error("Unable to set storageClassName in PVC {pvcName}.") - return False - - pvcAPI.patch(body=pvc, namespace=namespace) - - maxRetries = 60 - foundReadyPVC = False - retries = 0 - while not foundReadyPVC and retries < maxRetries: - retries += 1 - try: - patchedPVC = pvcAPI.get(name=pvcName, namespace=namespace) - if patchedPVC.status.phase == "Bound": - foundReadyPVC = True - else: - logger.debug("Waiting 5s for PVC {pvcName} to be bound before checking again ...") - sleep(5) - except NotFoundError: - logger.error("The patched PVC {pvcName} does not exist.") - return False - - return foundReadyPVC - - except NotFoundError: - logger.error("PVC {pvcName} does not exist") - return False - # Assisted by WCA@IBM # Latest GenAI contribution: ibm/granite-8b-code-instruct diff --git a/src/mas/devops/tekton.py b/src/mas/devops/tekton.py index 3ea103af..215af931 100644 --- a/src/mas/devops/tekton.py +++ b/src/mas/devops/tekton.py @@ -22,7 +22,8 @@ from jinja2 import Environment, FileSystemLoader -from .ocp import getConsoleURL, waitForCRD, waitForDeployment, waitForPVC, patchPendingPVC, crdExists +from .ocp import getConsoleURL, waitForCRD, waitForDeployment, crdExists +from .mas import waitForPVC, patchPendingPVC logger = logging.getLogger(__name__) From 627794c36aeb6107ab5e8cccc9236995b682ac4c Mon Sep 17 00:00:00 2001 From: Sanjay Prabhakar Date: Mon, 7 Apr 2025 10:56:11 +0100 Subject: [PATCH 07/11] [patch] fix whitespace --- src/mas/devops/tekton.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mas/devops/tekton.py b/src/mas/devops/tekton.py index 215af931..799d4420 100644 --- a/src/mas/devops/tekton.py +++ b/src/mas/devops/tekton.py @@ -86,10 +86,10 @@ def installOpenShiftPipelines(dynClient: DynamicClient, customStorageClassName: return False # Wait for the postgredb-tekton-results-postgres-0 PVC to be ready - # this PVC doesn't come up when there's no default storage class is in the cluster, - # this is causing the pvc to be in pending state and causing the tekton-results-postgres statefulSet in pending, + # this PVC doesn't come up when there's no default storage class is in the cluster, + # this is causing the pvc to be in pending state and causing the tekton-results-postgres statefulSet in pending, # due to these resources not coming up, the MAS pre-install check in the pipeline times out checking the health of this statefulSet, - # causing failure in pipeline. + # causing failure in pipeline. # Refer https://github.com/ibm-mas/cli/issues/1511 logger.debug("Waiting for postgredb-tekton-results-postgres-0 PVC to be ready") foundReadyPVC = waitForPVC(dynClient, namespace="openshift-pipelines", pvcName="postgredb-tekton-results-postgres-0") From 1a2e1c66f185aa31f61dfe1217d4bff79b371033 Mon Sep 17 00:00:00 2001 From: Sanjay Prabhakar Date: Mon, 7 Apr 2025 11:02:08 +0100 Subject: [PATCH 08/11] [patch] fix precommit errors --- src/mas/devops/mas.py | 2 ++ src/mas/devops/ocp.py | 1 + src/mas/devops/tekton.py | 1 + 3 files changed, 4 insertions(+) diff --git a/src/mas/devops/mas.py b/src/mas/devops/mas.py index f405278d..b6d97612 100644 --- a/src/mas/devops/mas.py +++ b/src/mas/devops/mas.py @@ -196,6 +196,7 @@ def updateIBMEntitlementKey(dynClient: DynamicClient, namespace: str, icrUsernam secret = secretsAPI.apply(body=secret, namespace=namespace) return secret + def waitForPVC(dynClient: DynamicClient, namespace: str, pvcName: str) -> bool: pvcAPI = dynClient.resources.get(api_version="v1", kind="PersistentVolumeClaim") maxRetries = 60 @@ -213,6 +214,7 @@ def waitForPVC(dynClient: DynamicClient, namespace: str, pvcName: str) -> bool: except NotFoundError: logger.debug("Waiting 5s for PVC {pvcName} to be created before checking again ...") sleep(5) + return foundReadyPVC diff --git a/src/mas/devops/ocp.py b/src/mas/devops/ocp.py index ff7b5c28..2aa9e0b9 100644 --- a/src/mas/devops/ocp.py +++ b/src/mas/devops/ocp.py @@ -157,6 +157,7 @@ def waitForDeployment(dynClient: DynamicClient, namespace: str, deploymentName: sleep(5) return foundReadyDeployment + def getConsoleURL(dynClient: DynamicClient) -> str: routesAPI = dynClient.resources.get(api_version="route.openshift.io/v1", kind="Route") consoleRoute = routesAPI.get(name="console", namespace="openshift-console") diff --git a/src/mas/devops/tekton.py b/src/mas/devops/tekton.py index 799d4420..4f561aec 100644 --- a/src/mas/devops/tekton.py +++ b/src/mas/devops/tekton.py @@ -27,6 +27,7 @@ logger = logging.getLogger(__name__) + # customStorageClassName is used when no default Storageclass is available on cluster, # openshift-pipelines creates PVC which looks for default. customStorageClassName is patched into PVC when default is unavailable. def installOpenShiftPipelines(dynClient: DynamicClient, customStorageClassName: str = None) -> bool: From 2879ef45b29eb3d33bd15bdd645467272dcbf83a Mon Sep 17 00:00:00 2001 From: Sanjay Prabhakar Date: Mon, 7 Apr 2025 11:05:45 +0100 Subject: [PATCH 09/11] [patch] fix whitespace --- src/mas/devops/mas.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mas/devops/mas.py b/src/mas/devops/mas.py index b6d97612..bca104ab 100644 --- a/src/mas/devops/mas.py +++ b/src/mas/devops/mas.py @@ -250,7 +250,7 @@ def patchPendingPVC(dynClient: DynamicClient, namespace: str, pvcName: str, stor except NotFoundError: logger.error("The patched PVC {pvcName} does not exist.") return False - + return foundReadyPVC except NotFoundError: From 907c62976260d941528d725cc6d52cc54ac7a2bc Mon Sep 17 00:00:00 2001 From: Sanjay Prabhakar Date: Mon, 7 Apr 2025 11:14:20 +0100 Subject: [PATCH 10/11] [patch] return value for installOpenShiftPipelines --- src/mas/devops/tekton.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mas/devops/tekton.py b/src/mas/devops/tekton.py index 4f561aec..e97811b0 100644 --- a/src/mas/devops/tekton.py +++ b/src/mas/devops/tekton.py @@ -96,12 +96,15 @@ def installOpenShiftPipelines(dynClient: DynamicClient, customStorageClassName: foundReadyPVC = waitForPVC(dynClient, namespace="openshift-pipelines", pvcName="postgredb-tekton-results-postgres-0") if foundReadyPVC: logger.info("OpenShift Pipelines postgres is installed and ready") + return True else: patchedPVC = patchPendingPVC(dynClient, namespace="openshift-pipelines", pvcName="postgredb-tekton-results-postgres-0", storageClassName=customStorageClassName) if patchedPVC: logger.info("OpenShift Pipelines postgres is installed and ready") + return True else: logger.error("OpenShift Pipelines postgres PVC is NOT ready") + return False def updateTektonDefinitions(namespace: str, yamlFile: str) -> None: From 9381a55d4fd552a0bfbcdad32c7936bbe7308e5c Mon Sep 17 00:00:00 2001 From: Anil Prajapati Date: Wed, 23 Apr 2025 12:37:34 +0530 Subject: [PATCH 11/11] [patch] fix logger message formating --- src/mas/devops/mas.py | 16 ++++++++-------- src/mas/devops/ocp.py | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/mas/devops/mas.py b/src/mas/devops/mas.py index bca104ab..1d1e184f 100644 --- a/src/mas/devops/mas.py +++ b/src/mas/devops/mas.py @@ -146,8 +146,8 @@ def verifyMasInstance(dynClient: DynamicClient, instanceId: str) -> bool: except ResourceNotFoundError: # The MAS Suite CRD has not even been installed in the cluster return False - except UnauthorizedError: - logger.error("Error: Unable to verify MAS instance due to failed authorization: {e}") + except UnauthorizedError as e: + logger.error(f"Error: Unable to verify MAS instance due to failed authorization: {e}") return False @@ -209,10 +209,10 @@ def waitForPVC(dynClient: DynamicClient, namespace: str, pvcName: str) -> bool: if pvc.status.phase == "Bound": foundReadyPVC = True else: - logger.debug("Waiting 5s for PVC {pvcName} to be ready before checking again ...") + logger.debug(f"Waiting 5s for PVC {pvcName} to be ready before checking again ...") sleep(5) except NotFoundError: - logger.debug("Waiting 5s for PVC {pvcName} to be created before checking again ...") + logger.debug(f"Waiting 5s for PVC {pvcName} to be created before checking again ...") sleep(5) return foundReadyPVC @@ -230,7 +230,7 @@ def patchPendingPVC(dynClient: DynamicClient, namespace: str, pvcName: str, stor if defaultStorageClasses.provider is not None: pvc.spec.storageClassName = defaultStorageClasses.rwo else: - logger.error("Unable to set storageClassName in PVC {pvcName}.") + logger.error(f"Unable to set storageClassName in PVC {pvcName}.") return False pvcAPI.patch(body=pvc, namespace=namespace) @@ -245,14 +245,14 @@ def patchPendingPVC(dynClient: DynamicClient, namespace: str, pvcName: str, stor if patchedPVC.status.phase == "Bound": foundReadyPVC = True else: - logger.debug("Waiting 5s for PVC {pvcName} to be bound before checking again ...") + logger.debug(f"Waiting 5s for PVC {pvcName} to be bound before checking again ...") sleep(5) except NotFoundError: - logger.error("The patched PVC {pvcName} does not exist.") + logger.error(f"The patched PVC {pvcName} does not exist.") return False return foundReadyPVC except NotFoundError: - logger.error("PVC {pvcName} does not exist") + logger.error(f"PVC {pvcName} does not exist") return False diff --git a/src/mas/devops/ocp.py b/src/mas/devops/ocp.py index 2aa9e0b9..e4c54113 100644 --- a/src/mas/devops/ocp.py +++ b/src/mas/devops/ocp.py @@ -150,10 +150,10 @@ def waitForDeployment(dynClient: DynamicClient, namespace: str, deploymentName: # NoneType and int comparison TypeError foundReadyDeployment = True else: - logger.debug("Waiting 5s for deployment {deploymentName} to be ready before checking again ...") + logger.debug(f"Waiting 5s for deployment {deploymentName} to be ready before checking again ...") sleep(5) except NotFoundError: - logger.debug("Waiting 5s for deployment {deploymentName} to be created before checking again ...") + logger.debug(f"Waiting 5s for deployment {deploymentName} to be created before checking again ...") sleep(5) return foundReadyDeployment