func()

in pkg/csi/controller.go [282:360]


func (r *pvcReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
	log := log.FromContext(ctx)

	pvcName := req.NamespacedName.Name

	var configMap corev1.ConfigMap
	err := r.Get(ctx, types.NamespacedName{Namespace: r.namespace, Name: r.volumeTypeConfigMap}, &configMap)
	if err != nil {
		log.Info("PVC reconcile before mapping available", "pvc", pvcName, "error", err)
		return ctrl.Result{Requeue: true}, nil
	}
	mapping, err := getVolumeTypeMapping(configMap.Data)
	if err != nil {
		return ctrl.Result{}, err
	}

	info, found := mapping[pvcName]
	if !found {
		return ctrl.Result{}, fmt.Errorf("Unknown node or pvc %s", pvcName)
	}

	var pvc corev1.PersistentVolumeClaim
	if err := r.Get(ctx, req.NamespacedName, &pvc); err != nil {
		return ctrl.Result{}, fmt.Errorf("reconciling %s: %w", req.NamespacedName, err)
	}

	var node corev1.Node
	if err := r.Get(ctx, types.NamespacedName{Name: pvcName}, &node); err != nil {
		if apierrors.IsNotFound(err) {
			node.DeletionTimestamp = &metav1.Time{Time: time.Now()}
		} else {
			return ctrl.Result{}, fmt.Errorf("can't get node %s for pvc: %w", pvc.GetName(), err)
		}
	}
	if node.DeletionTimestamp != nil {
		// The node doesn't exist, the PVC should be deleted.
		return ctrl.Result{}, r.deletePVC(ctx, &pvc)
	}

	mustRequeue := false

	// Update the mapping with the PV name, if known.
	if pvc.Status.Phase == corev1.ClaimBound && info.Disk != pvc.Spec.VolumeName {
		if info.Disk != "" && info.Disk != pvc.Spec.VolumeName {
			log.Error(nil, "pv mapping mismatch, will update", "old-disk", info.Disk, "curr-diisk", pvc.Spec.VolumeName)
		}
		info.Disk = pvc.Spec.VolumeName
		mapping[pvcName] = info
		if err := writeVolumeTypeMapping(configMap.Data, mapping); err != nil {
			return ctrl.Result{}, err
		}
		if err := r.Update(ctx, &configMap); err != nil {
			log.Error(err, "mapping update, will requeue")
			mustRequeue = true
		}
	}

	// If the PVC is bound but not attached, attach it.
	if pvc.Status.Phase == corev1.ClaimBound {
		var pv corev1.PersistentVolume
		if err := r.Get(ctx, types.NamespacedName{Name: pvc.Spec.VolumeName}, &pv); err != nil {
			return ctrl.Result{}, fmt.Errorf("Can't get volume for pvc %s: %w", pvc.GetName(), err)
		}
		attached, err := r.attacher.diskIsAttached(ctx, pv.Spec.CSI.VolumeHandle, node.GetName())
		if err != nil {
			return ctrl.Result{}, fmt.Errorf("Could not check attachment for pvc %s, pv %s: %w", pvc.GetName(), pv.GetName(), err)
		}
		if !attached {
			if err := r.attacher.attachDisk(ctx, pv.Spec.CSI.VolumeHandle, node.GetName()); err != nil {
				return ctrl.Result{}, fmt.Errorf("Could not attach pv %s to node %s: %w", pv.GetName(), pvc.GetName(), err)
			}
			log.Info("attach", "pvc", pvc.GetName())
		}
	}

	// Otherwise everything looks good.
	log.Info("reconciled, looks good", "pvc", req.NamespacedName)
	return ctrl.Result{Requeue: mustRequeue}, nil
}