@@ -43,52 +43,16 @@ func Destroy(ctx context.Context, clusterName, instanceName string, keepPVC bool
4343 return err
4444 }
4545
46+ // PVCs are detached or deleted before the pod so the operator's reconcile loop
47+ // can't see dangling PVCs and recreate the pod. This matches the deletion order
48+ // in ensureInstanceIsDeleted.
4649 if keepPVC {
47- if err := ensurePodIsDeleted (ctx , instanceName , clusterName ); err != nil {
50+ if err := detachInstancePVCs (ctx , pvcs , clusterName , instanceName ); err != nil {
4851 return err
4952 }
50-
51- // we remove the ownership from the pvcs if present
52- for i := range pvcs {
53- if _ , isOwned := controller .IsOwnedByCluster (& pvcs [i ]); ! isOwned {
54- continue
55- }
56-
57- pvcs [i ].OwnerReferences = removeOwnerReference (pvcs [i ].OwnerReferences , clusterName )
58- pvcs [i ].Annotations [utils .PVCStatusAnnotationName ] = persistentvolumeclaim .StatusDetached
59- pvcs [i ].Labels [utils .InstanceNameLabelName ] = instanceName
60- err = plugin .Client .Update (ctx , & pvcs [i ])
61- if err != nil {
62- return fmt .Errorf ("error updating metadata for persistent volume claim %s: %v" ,
63- clusterName , err )
64- }
65- }
66- fmt .Printf ("Instance %s of cluster %s has been destroyed and the PVC was kept\n " ,
67- instanceName ,
68- clusterName ,
69- )
70- return nil
71- }
72-
73- // Delete PVCs before the pod to prevent a race where the operator sees
74- // dangling PVCs and recreates the pod before we can delete them.
75- // This matches the deletion order in ensureInstanceIsDeleted.
76- for i := range pvcs {
77- if pvcs [i ].Labels == nil {
78- pvcs [i ].Labels = map [string ]string {}
79- }
80-
81- _ , isOwned := controller .IsOwnedByCluster (& pvcs [i ])
82- // if it is requested for deletion and it is owned by the cluster, we delete it. If it is not owned by the cluster
83- // but it does have the instance label and the detached annotation then we can still delete it
84- // We will only skip the iteration and not delete the pvc if it is not owned by the cluster, and it does not have
85- // the annotation or label
86- if isOwned ||
87- (pvcs [i ].Annotations [utils .PVCStatusAnnotationName ] == persistentvolumeclaim .StatusDetached &&
88- pvcs [i ].Labels [utils .InstanceNameLabelName ] == instanceName ) {
89- if err = plugin .Client .Delete (ctx , & pvcs [i ]); err != nil {
90- return fmt .Errorf ("error deleting pvc %s: %v" , pvcs [i ].Name , err )
91- }
53+ } else {
54+ if err := deleteInstancePVCs (ctx , pvcs , instanceName ); err != nil {
55+ return err
9256 }
9357 }
9458
@@ -117,8 +81,62 @@ func Destroy(ctx context.Context, clusterName, instanceName string, keepPVC bool
11781 }
11882 }
11983
120- fmt .Printf ("Instance %s of cluster %s is destroyed\n " , instanceName , clusterName )
84+ if keepPVC {
85+ fmt .Printf ("Instance %s of cluster %s has been destroyed and the PVC was kept\n " ,
86+ instanceName ,
87+ clusterName ,
88+ )
89+ } else {
90+ fmt .Printf ("Instance %s of cluster %s is destroyed\n " , instanceName , clusterName )
91+ }
92+
93+ return nil
94+ }
95+
96+ // detachInstancePVCs removes the ownership from the pvcs if present
97+ func detachInstancePVCs (
98+ ctx context.Context ,
99+ pvcs []corev1.PersistentVolumeClaim ,
100+ clusterName , instanceName string ,
101+ ) error {
102+ for i := range pvcs {
103+ if _ , isOwned := controller .IsOwnedByCluster (& pvcs [i ]); ! isOwned {
104+ continue
105+ }
106+
107+ pvcs [i ].OwnerReferences = removeOwnerReference (pvcs [i ].OwnerReferences , clusterName )
108+ pvcs [i ].Annotations [utils .PVCStatusAnnotationName ] = persistentvolumeclaim .StatusDetached
109+ pvcs [i ].Labels [utils .InstanceNameLabelName ] = instanceName
110+ if err := plugin .Client .Update (ctx , & pvcs [i ]); err != nil {
111+ return fmt .Errorf ("error updating metadata for persistent volume claim %s: %v" ,
112+ clusterName , err )
113+ }
114+ }
115+ return nil
116+ }
117+
118+ // deleteInstancePVCs deletes the pvcs owned by the cluster, or unowned pvcs that
119+ // still carry the instance label and the detached annotation from a previous
120+ // keep-pvc run
121+ func deleteInstancePVCs (ctx context.Context , pvcs []corev1.PersistentVolumeClaim , instanceName string ) error {
122+ for i := range pvcs {
123+ if pvcs [i ].Labels == nil {
124+ pvcs [i ].Labels = map [string ]string {}
125+ }
121126
127+ _ , isOwned := controller .IsOwnedByCluster (& pvcs [i ])
128+ // if it is requested for deletion and it is owned by the cluster, we delete it. If it is not owned by the cluster
129+ // but it does have the instance label and the detached annotation then we can still delete it
130+ // We will only skip the iteration and not delete the pvc if it is not owned by the cluster, and it does not have
131+ // the annotation or label
132+ if isOwned ||
133+ (pvcs [i ].Annotations [utils .PVCStatusAnnotationName ] == persistentvolumeclaim .StatusDetached &&
134+ pvcs [i ].Labels [utils .InstanceNameLabelName ] == instanceName ) {
135+ if err := plugin .Client .Delete (ctx , & pvcs [i ]); err != nil {
136+ return fmt .Errorf ("error deleting pvc %s: %v" , pvcs [i ].Name , err )
137+ }
138+ }
139+ }
122140 return nil
123141}
124142
0 commit comments