func (r *KalmPVReconciler) reconcileDeleteOfPVWithSpecialCleanLabel(kalmPVList corev1.PersistentVolumeList) error {
	r.Log.Info("reconcileDeleteOfPVWithSpecialCleanLabel")
	for i := range kalmPVList.Items {
		pv := kalmPVList.Items[i]
		pvcNsAndName, exist := pv.Labels[KalmLabelCleanIfPVCGone]
		if !exist {
			continue
		}
		claimRef := pv.Spec.ClaimRef
		if claimRef == nil {
			continue
		}
		ns := claimRef.Namespace
		name := claimRef.Name
		expectedPVCNsAndName := fmt.Sprintf("%s-%s", ns, name)
		if pvcNsAndName != expectedPVCNsAndName {
			r.Log.Info("pv clean label not match expected, skip deletion",
				KalmLabelCleanIfPVCGone, pvcNsAndName, "expected", expectedPVCNsAndName)
			continue
		}
		var pvc corev1.PersistentVolumeClaim
		err := r.Get(r.ctx, client.ObjectKey{Namespace: ns, Name: name}, &pvc)
		if err != nil {
			if !errors.IsNotFound(err) {
				return err
			}
			if err := r.Delete(r.ctx, &pv); err != nil {
				return err
			}
			r.Log.Info("deleted pv with clean mark:"+pv.Name, KalmLabelCleanIfPVCGone, pvcNsAndName)
		}
	}
	return nil
}
list all kalm-managed pv
if 1. labeled with: clean-if-pvc-deleted
2. pvc is gone
then delete this pv
package controllers
import (
	"context"
	"fmt"
	"github.com/kalmhq/kalm/controller/api/v1alpha1"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/types"
	ctrl "sigs.k8s.io/controller-runtime"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/handler"
	"sigs.k8s.io/controller-runtime/pkg/reconcile"
)
type KalmPVReconciler struct {
	*BaseReconciler
	ctx context.Context
}
const (
	KalmLabelCleanIfPVCGone = "clean-if-claimed-pvc-gone"
	KalmLabelPVLocker       = "kalm-pv-locker"
	ControllerKalmPV        = "controller-kalm-pv"
)
func NewKalmPVReconciler(mgr ctrl.Manager) *KalmPVReconciler {
	return &KalmPVReconciler{
		BaseReconciler: NewBaseReconciler(mgr, "KalmPV"),
		ctx:            context.Background(),
	}
}
func (r *KalmPVReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
	r.Log.Info("reconciling kalmPV", "req", req)
	if req.Namespace == NSForPVCChanged {
		return ctrl.Result{}, r.reconcileForPVCChange()
	} else {
		return ctrl.Result{}, r.reconcilePV(req.Name)
	}
}
type PVCMapper struct {
	*BaseReconciler
}
func (r *KalmPVReconciler) reconcileForPVCChange() error {
	var pvList corev1.PersistentVolumeList
	matchingLabels := client.MatchingLabels{KalmLabelManaged: "true"}
	if err := r.List(r.ctx, &pvList, matchingLabels); err != nil {
		return err
	}
	err := r.reconcileDeleteOfPVWithSpecialCleanLabel(pvList)
	if err != nil {
		return err
	}
	err = r.reconcileOrphanPVs(pvList)
	return err
}