@@ -579,55 +579,32 @@ def preparePipelinesNamespace(
579579
580580 # Create config PVC if requested
581581 if createConfigPVC :
582- # If config-pvc already exists with a different storageClass, delete it first.
583- # Kubernetes does not allow changing storageClassName on an existing PVC (immutable
584- # field), so patching would fail with a conflict error. Deleting and recreating
585- # is safe here because config-pvc only holds transient pipeline workspace data —
586- # it is not a source of truth for any persistent application state.
582+ # If config-pvc already exists, remove its pvc-protection finalizer and delete it
583+ # so it can be recreated with the correct storageClass. storageClassName is immutable
584+ # in Kubernetes — patching it causes a 422 error.
587585 try :
588586 existingConfigPVC = pvcAPI .get (name = "config-pvc" , namespace = namespace )
589587 existingStorageClass = existingConfigPVC .spec .storageClassName
590588 existingPhase = existingConfigPVC .status .phase
591- if existingPhase == "Bound" :
592- # config-pvc already exists and is healthy — storageClassName is immutable
593- # in Kubernetes so we must not try to patch it with a new storageClass
594- # (which would cause a 422 Unprocessable Entity error). The pipeline only
595- # needs the PVC to exist and be mountable — it does not care which
596- # storageClass backs it.
597- logger .info (
598- f"config-pvc already exists and is Bound with storageClassName='{ existingStorageClass } ', "
599- f"reusing existing PVC as-is (skipping recreate)."
600- )
601- return
602- else :
603- # PVC exists but is not Bound (e.g. Lost or Pending because the backing
604- # storageClass was removed). Delete it so it can be recreated below.
605- # We must remove the pvc-protection finalizer first — otherwise Kubernetes
606- # will block deletion indefinitely while any pod (e.g. mas-cli deployment)
607- # still has the PVC mounted.
608- logger .info (
609- f"config-pvc exists but is in '{ existingPhase } ' state "
610- f"(storageClassName='{ existingStorageClass } '). "
611- f"Removing finalizer and deleting so it can be recreated with storageClassName='{ storageClass } '."
612- )
613- pvcAPI .patch (
614- name = "config-pvc" ,
615- namespace = namespace ,
616- body = {"metadata" : {"finalizers" : []}},
617- content_type = "application/merge-patch+json" ,
618- )
619- pvcAPI .delete (name = "config-pvc" , namespace = namespace )
620- logger .info ("Waiting for config-pvc deletion to complete..." )
621- while True :
622- try :
623- pvcAPI .get (name = "config-pvc" , namespace = namespace )
624- logger .debug ("config-pvc still terminating, waiting 5s..." )
625- sleep (5 )
626- except NotFoundError :
627- logger .info ("config-pvc deletion confirmed." )
628- break
589+ logger .info (f"config-pvc already exists (storageClassName='{ existingStorageClass } ', phase='{ existingPhase } '). Removing finalizer and deleting to recreate with storageClassName='{ storageClass } '." )
590+ pvcAPI .patch (
591+ name = "config-pvc" ,
592+ namespace = namespace ,
593+ body = {"metadata" : {"finalizers" : []}},
594+ content_type = "application/merge-patch+json" ,
595+ )
596+ pvcAPI .delete (name = "config-pvc" , namespace = namespace )
597+ logger .info ("Waiting for config-pvc deletion to complete..." )
598+ while True :
599+ try :
600+ pvcAPI .get (name = "config-pvc" , namespace = namespace )
601+ logger .debug ("config-pvc still terminating, waiting 5s..." )
602+ sleep (5 )
603+ except NotFoundError :
604+ logger .info ("config-pvc deletion confirmed." )
605+ break
629606 except NotFoundError :
630- pass # PVC does not exist yet — will be created below
607+ pass # PVC does not exist yet, will be created below
631608
632609 logger .info ("Creating config PVC" )
633610 template = env .get_template ("pipelines-pvc.yml.j2" )
0 commit comments