Skip to content

Commit cc641c1

Browse files
author
Jeel Oza
committed
[patch] force-delete config-pvc by clearing PV claimRef and finalizers in a retry loop
1 parent c42959e commit cc641c1

1 file changed

Lines changed: 53 additions & 37 deletions

File tree

‎src/mas/devops/tekton.py‎

Lines changed: 53 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -587,56 +587,72 @@ def preparePipelinesNamespace(
587587
f"config-pvc already exists (storageClassName='{existingStorageClass}', phase='{existingPhase}'). "
588588
f"Deleting to recreate with storageClassName='{storageClass}'."
589589
)
590-
591-
# Unbind the PVC by clearing the claimRef on its backing PV, then remove the finalizer.
592-
# PVCProtectionController keeps re-adding pvc-protection on Bound PVCs so we must
593-
# move it to Lost state first before the finalizer patch and delete will stick.
594590
pvName = existingConfigPVC.spec.volumeName
595591
pvAPI = dynClient.resources.get(api_version="v1", kind="PersistentVolume")
596-
if pvName:
597-
logger.info(f"Unbinding config-pvc from PV '{pvName}' to allow clean deletion.")
598-
# Clear all claimRef fields — setting name/namespace/uid to empty strings forces
599-
# Lost state even when the PVC already has a deletionTimestamp (Terminating).
600-
pvAPI.patch(
601-
name=pvName,
602-
body={"spec": {"claimRef": {"name": "", "namespace": "", "uid": "", "resourceVersion": ""}}},
603-
content_type="application/merge-patch+json",
604-
)
605-
# Wait for the PVC to leave Bound state
606-
for _ in range(30):
607-
current = pvcAPI.get(name="config-pvc", namespace=namespace)
608-
if current.status.phase != "Bound":
609-
logger.info(f"config-pvc is now '{current.status.phase}'.")
610-
break
611-
logger.debug("config-pvc still Bound, waiting 2s...")
612-
sleep(2)
613-
614-
# Remove the finalizer directly — safe now that the PVC is no longer Bound
615-
pvcAPI.patch(
616-
name="config-pvc",
617-
namespace=namespace,
618-
body={"metadata": {"finalizers": []}},
619-
content_type="application/merge-patch+json",
620-
)
621-
pvcAPI.delete(name="config-pvc", namespace=namespace)
622-
logger.info("Waiting for config-pvc deletion to complete...")
623-
while True:
592+
593+
# Force-delete the config-pvc regardless of its current state (Bound, Lost, Terminating).
594+
# Each iteration applies every known unblocking step, then checks if the PVC is gone.
595+
for attempt in range(30):
596+
logger.debug(f"config-pvc force-delete attempt {attempt + 1}/30")
597+
598+
# Step 1: clear claimRef on the backing PV so the PVC moves from Bound → Lost.
599+
# Using empty strings (not null) — null is ignored when PVC has a deletionTimestamp.
600+
if pvName:
601+
try:
602+
pvAPI.patch(
603+
name=pvName,
604+
body={"spec": {"claimRef": {"name": "", "namespace": "", "uid": "", "resourceVersion": ""}}},
605+
content_type="application/merge-patch+json",
606+
)
607+
except NotFoundError:
608+
pvName = None # PV already gone, skip PV steps
609+
610+
# Step 2: clear PV finalizers in case the PV itself is stuck Terminating
611+
if pvName:
612+
try:
613+
pvAPI.patch(
614+
name=pvName,
615+
body={"metadata": {"finalizers": []}},
616+
content_type="application/merge-patch+json",
617+
)
618+
except NotFoundError:
619+
pvName = None
620+
621+
# Step 3: clear PVC finalizer and issue delete
622+
try:
623+
pvcAPI.patch(
624+
name="config-pvc",
625+
namespace=namespace,
626+
body={"metadata": {"finalizers": []}},
627+
content_type="application/merge-patch+json",
628+
)
629+
pvcAPI.delete(name="config-pvc", namespace=namespace)
630+
except NotFoundError:
631+
logger.info("config-pvc is gone.")
632+
break
633+
634+
sleep(3)
635+
636+
# Check if gone
624637
try:
625638
pvcAPI.get(name="config-pvc", namespace=namespace)
626-
logger.debug("config-pvc still terminating, waiting 5s...")
627-
sleep(5)
639+
logger.debug("config-pvc still present, retrying...")
628640
except NotFoundError:
629641
logger.info("config-pvc deletion confirmed.")
630642
break
631643

632-
# Delete the now-orphaned PV so it does not accumulate across upgrades.
633-
# The new config-pvc will get a fresh PV provisioned automatically.
644+
# Clean up the orphaned PV if still around
634645
if pvName:
635646
try:
647+
pvAPI.patch(
648+
name=pvName,
649+
body={"metadata": {"finalizers": []}},
650+
content_type="application/merge-patch+json",
651+
)
636652
pvAPI.delete(name=pvName)
637653
logger.info(f"Deleted orphaned PV '{pvName}'.")
638654
except NotFoundError:
639-
pass # already gone (e.g. reclaimPolicy: Delete handled it)
655+
pass # already gone
640656

641657
except NotFoundError:
642658
pass # PVC does not exist yet, will be created fresh below

0 commit comments

Comments
 (0)