2222
2323from jinja2 import Environment , FileSystemLoader
2424
25- from .ocp import getConsoleURL , waitForCRD , waitForDeployment , crdExists , waitForPVC
25+ from .ocp import getConsoleURL , waitForCRD , waitForDeployment , crdExists , waitForPVC , getStorageClasses
2626
2727logger = logging .getLogger (__name__ )
2828
@@ -111,7 +111,7 @@ def installOpenShiftPipelines(dynClient: DynamicClient, customStorageClassName:
111111 return False
112112
113113
114- def addMissingStorageClassToTektonPVC (dynClient : DynamicClient , namespace : str , pvcName : str , storageClassName : str ) -> bool :
114+ def addMissingStorageClassToTektonPVC (dynClient : DynamicClient , namespace : str , pvcName : str , storageClassName : str = None ) -> bool :
115115 """
116116 OpenShift Pipelines has a problem when there is no default storage class defined in a cluster, this function
117117 patches the PVC used to store pipeline results to add a specific storage class into the PVC spec and waits for the
@@ -123,18 +123,49 @@ def addMissingStorageClassToTektonPVC(dynClient: DynamicClient, namespace: str,
123123 :type namespace: str
124124 :param pvcName: Name of the PVC that we want to fix
125125 :type pvcName: str
126- :param storageClassName: Name of the storage class that we want to update the PVC to reference
126+ :param storageClassName: Name of the storage class that we want to update the PVC to reference (optional, will auto-select if not provided)
127127 :type storageClassName: str
128- :return: Description
128+ :return: True if PVC is successfully patched and bound, False otherwise
129129 :rtype: bool
130130 """
131131 pvcAPI = dynClient .resources .get (api_version = "v1" , kind = "PersistentVolumeClaim" )
132+ storageClassAPI = dynClient .resources .get (api_version = "storage.k8s.io/v1" , kind = "StorageClass" )
133+
132134 try :
133135 pvc = pvcAPI .get (name = pvcName , namespace = namespace )
136+
137+ # Check if PVC is pending and has no storage class
134138 if pvc .status .phase == "Pending" and pvc .spec .storageClassName is None :
135- pvc .spec .storageClassName = storageClassName
139+ # Determine which storage class to use
140+ targetStorageClass = None
141+
142+ if storageClassName is not None :
143+ # Verify the provided storage class exists
144+ try :
145+ storageClassAPI .get (name = storageClassName )
146+ targetStorageClass = storageClassName
147+ logger .info (f"Using provided storage class '{ storageClassName } ' for PVC { pvcName } " )
148+ except NotFoundError :
149+ logger .warning (f"Provided storage class '{ storageClassName } ' not found, will try to detect available storage class" )
150+
151+ # If no valid custom storage class, try to detect one
152+ if targetStorageClass is None :
153+ logger .warning ("No storage class provided or provided storage class not found, attempting to use first available storage class" )
154+ storageClasses = getStorageClasses (dynClient )
155+ if len (storageClasses ) > 0 :
156+ # Use the first available storage class
157+ targetStorageClass = storageClasses [0 ].metadata .name
158+ logger .info (f"Using first available storage class '{ targetStorageClass } ' for PVC { pvcName } " )
159+ else :
160+ logger .error (f"Unable to set storageClassName in PVC { pvcName } . No storage classes available in the cluster." )
161+ return False
162+
163+ # Patch the PVC with the storage class
164+ pvc .spec .storageClassName = targetStorageClass
165+ logger .info (f"Patching PVC { pvcName } with storageClassName: { targetStorageClass } " )
136166 pvcAPI .patch (body = pvc , namespace = namespace )
137167
168+ # Wait for the PVC to be bound
138169 maxRetries = 60
139170 foundReadyPVC = False
140171 retries = 0
@@ -144,6 +175,7 @@ def addMissingStorageClassToTektonPVC(dynClient: DynamicClient, namespace: str,
144175 patchedPVC = pvcAPI .get (name = pvcName , namespace = namespace )
145176 if patchedPVC .status .phase == "Bound" :
146177 foundReadyPVC = True
178+ logger .info (f"PVC { pvcName } is now bound" )
147179 else :
148180 logger .debug (f"Waiting 5s for PVC { pvcName } to be bound before checking again ..." )
149181 sleep (5 )
@@ -152,6 +184,9 @@ def addMissingStorageClassToTektonPVC(dynClient: DynamicClient, namespace: str,
152184 return False
153185
154186 return foundReadyPVC
187+ else :
188+ logger .warning (f"PVC { pvcName } is not in Pending state or already has a storageClassName" )
189+ return pvc .status .phase == "Bound"
155190
156191 except NotFoundError :
157192 logger .error (f"PVC { pvcName } does not exist" )
@@ -529,4 +564,4 @@ def launchAiServiceUpgradePipeline(dynClient: DynamicClient,
529564 pipelineRunsAPI .apply (body = pipelineRun , namespace = namespace )
530565
531566 pipelineURL = f"{ getConsoleURL (dynClient )} /k8s/ns/aiservice-{ aiserviceInstanceId } -pipelines/tekton.dev~v1beta1~PipelineRun/{ aiserviceInstanceId } -upgrade-{ timestamp } "
532- return pipelineURL
567+ return pipelineURL
0 commit comments