🌳
pt0/deployF/k8sF/pvcF/waitForPvCleanupAI.mts
5type PvStatus = { status?: { phase?: string }, spec?: { persistentVolumeReclaimPolicy?: string } }
7// Wait for a PV to be cleaned up after its PVC was deleted.
8// For reclaimPolicy=Delete: waits until PV AND Longhorn Volume no longer exist
9// For reclaimPolicy=Retain: waits until PV is Available or Released
10//
11// Use this after delpvcs when you need to immediately re-create a PVC with the same name.
12// Prevents race conditions where new PVC gets stale data from not-yet-cleaned storage.
13export const waitForPvCleanup = async ({pvName, cluster_name}: {pvName: string, cluster_name: string}) => {
14 if (!pvName) return // PVC wasn't bound to a PV
16 const pvResource = {apiVersion: 'v1', kind: 'PersistentVolume', metadata: {name: pvName}}
17 const lhVolResource = {apiVersion: 'longhorn.io/v1beta2', kind: 'Volume', metadata: {name: pvName, namespace: 'longhorn-system'}}
18 const startTime = Date.now()
20 while (true) {
21 const pv = await read2Resource({resource: pvResource, cluster_name}) as PvStatus | null
22 const phase = pv?.status?.phase
23 const reclaimPolicy = pv?.spec?.persistentVolumeReclaimPolicy
25 // For Retain policy: done when PV is Available or Released
26 if (reclaimPolicy === 'Retain') {
27 if (phase === 'Available' || phase === 'Released') return
28 }
30 // For Delete policy: wait until both PV and Longhorn Volume are gone
31 if (!pv) {
32 // PV is gone, now check Longhorn Volume (may still be cleaning up replicas)
33 const lhVol = await read2Resource({resource: lhVolResource, cluster_name})
34 if (!lhVol) return // Both PV and Longhorn Volume are gone
35 }
37 throwTimedOut(startTime, `waiting for PV ${pvName} cleanup (phase=${phase})`)
38 await sleep(2000)
39 }
42// Get the PV name bound to a PVC (if any)
43export const getPvNameForPvc = async ({pvcName, cluster_name}: {pvcName: string, cluster_name: string}): Promise<string | null> => {
44 const resource = {apiVersion: 'v1', kind: 'PersistentVolumeClaim', metadata: {name: pvcName, namespace: 'default'}}
45 const pvc = await read2Resource({resource, cluster_name}) as {spec?: {volumeName?: string}} | null
46 return pvc?.spec?.volumeName || null