Skip to content

Commit 02978cb

Browse files
[patch] auto check binding mode and wait based on the type
1 parent 500e6d7 commit 02978cb

2 files changed

Lines changed: 52 additions & 14 deletions

File tree

src/mas/devops/ocp.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,30 @@ def getStorageClasses(dynClient: DynamicClient) -> list:
228228
return storageClasses
229229

230230

231+
def getStorageClassVolumeBindingMode(dynClient: DynamicClient, storageClassName: str) -> str:
232+
"""
233+
Get the volumeBindingMode for a storage class.
234+
235+
Args:
236+
dynClient: OpenShift dynamic client
237+
storageClassName: Name of the storage class
238+
239+
Returns:
240+
str: "Immediate" or "WaitForFirstConsumer" (defaults to "Immediate" if not found)
241+
"""
242+
try:
243+
storageClass = getStorageClass(dynClient, storageClassName)
244+
if storageClass and hasattr(storageClass, 'volumeBindingMode'):
245+
return storageClass.volumeBindingMode
246+
# Default to Immediate if not specified (Kubernetes default)
247+
logger.debug(f"Storage class {storageClassName} does not have volumeBindingMode set, defaulting to 'Immediate'")
248+
return "Immediate"
249+
except Exception as e:
250+
logger.warning(f"Unable to determine volumeBindingMode for storage class {storageClassName}: {e}")
251+
# Default to Immediate to maintain backward compatibility
252+
return "Immediate"
253+
254+
231255
def isSNO(dynClient: DynamicClient) -> bool:
232256
return len(getNodes(dynClient)) == 1
233257

src/mas/devops/tekton.py

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ def updateTektonDefinitions(namespace: str, yamlFile: str) -> None:
124124
logger.debug(line)
125125

126126

127-
def preparePipelinesNamespace(dynClient: DynamicClient, instanceId: str = None, storageClass: str = None, accessMode: str = None, waitForBind: bool = True, configureRBAC: bool = True):
127+
def preparePipelinesNamespace(dynClient: DynamicClient, instanceId: str = None, storageClass: str = None, accessMode: str = None, configureRBAC: bool = True):
128128
templateDir = path.join(path.abspath(path.dirname(__file__)), "templates")
129129
env = Environment(
130130
loader=FileSystemLoader(searchpath=templateDir)
@@ -157,20 +157,27 @@ def preparePipelinesNamespace(dynClient: DynamicClient, instanceId: str = None,
157157
pvcAPI = dynClient.resources.get(api_version="v1", kind="PersistentVolumeClaim")
158158
pvcAPI.apply(body=pvc, namespace=namespace)
159159

160-
if instanceId is not None and waitForBind:
161-
logger.debug("Waiting for PVC to be bound")
162-
pvcIsBound = False
163-
while not pvcIsBound:
164-
configPVC = pvcAPI.get(name="config-pvc", namespace=namespace)
165-
if configPVC.status.phase == "Bound":
166-
pvcIsBound = True
167-
else:
168-
logger.debug("Waiting 15s before checking status of PVC again")
169-
logger.debug(configPVC)
170-
sleep(15)
160+
# Automatically determine if we should wait for PVC binding based on storage class
161+
from .ocp import getStorageClassVolumeBindingMode
162+
volumeBindingMode = getStorageClassVolumeBindingMode(dynClient, storageClass)
163+
waitForBind = (volumeBindingMode == "Immediate")
164+
165+
if waitForBind:
166+
logger.info(f"Storage class {storageClass} uses volumeBindingMode={volumeBindingMode}, waiting for PVC to bind")
167+
pvcIsBound = False
168+
while not pvcIsBound:
169+
configPVC = pvcAPI.get(name="config-pvc", namespace=namespace)
170+
if configPVC.status.phase == "Bound":
171+
pvcIsBound = True
172+
else:
173+
logger.debug("Waiting 15s before checking status of PVC again")
174+
logger.debug(configPVC)
175+
sleep(15)
176+
else:
177+
logger.info(f"Storage class {storageClass} uses volumeBindingMode={volumeBindingMode}, skipping PVC bind wait")
171178

172179

173-
def prepareAiServicePipelinesNamespace(dynClient: DynamicClient, instanceId: str = None, storageClass: str = None, accessMode: str = None, waitForBind: bool = True, configureRBAC: bool = True):
180+
def prepareAiServicePipelinesNamespace(dynClient: DynamicClient, instanceId: str = None, storageClass: str = None, accessMode: str = None, configureRBAC: bool = True):
174181
templateDir = path.join(path.abspath(path.dirname(__file__)), "templates")
175182
env = Environment(
176183
loader=FileSystemLoader(searchpath=templateDir)
@@ -197,8 +204,13 @@ def prepareAiServicePipelinesNamespace(dynClient: DynamicClient, instanceId: str
197204
pvcAPI = dynClient.resources.get(api_version="v1", kind="PersistentVolumeClaim")
198205
pvcAPI.apply(body=pvc, namespace=namespace)
199206

207+
# Automatically determine if we should wait for PVC binding based on storage class
208+
from .ocp import getStorageClassVolumeBindingMode
209+
volumeBindingMode = getStorageClassVolumeBindingMode(dynClient, storageClass)
210+
waitForBind = (volumeBindingMode == "Immediate")
211+
200212
if waitForBind:
201-
logger.debug("Waiting for PVC to be bound")
213+
logger.info(f"Storage class {storageClass} uses volumeBindingMode={volumeBindingMode}, waiting for PVC to bind")
202214
pvcIsBound = False
203215
while not pvcIsBound:
204216
configPVC = pvcAPI.get(name="config-pvc", namespace=namespace)
@@ -208,6 +220,8 @@ def prepareAiServicePipelinesNamespace(dynClient: DynamicClient, instanceId: str
208220
logger.debug("Waiting 15s before checking status of PVC again")
209221
logger.debug(configPVC)
210222
sleep(15)
223+
else:
224+
logger.info(f"Storage class {storageClass} uses volumeBindingMode={volumeBindingMode}, skipping PVC bind wait")
211225

212226

213227
def prepareInstallSecrets(dynClient: DynamicClient, namespace: str, slsLicenseFile: str = None, additionalConfigs: dict = None, certs: str = None, podTemplates: str = None) -> None:

0 commit comments

Comments
 (0)