linstor: support for WaitingForFirstConsumer
@@ -17,6 +17,7 @@ import (
"github.com/portworx/sched-ops/k8s/storage"
"github.com/sirupsen/logrus"
v1 "k8s.io/api/core/v1"
+ storagev1 "k8s.io/api/storage/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/runtime"
@@ -252,10 +253,12 @@ func (l *linstor) GetNodes() ([]*storkvolume.NodeInfo, error) {
}
func (l *linstor) GetPodVolumes(podSpec *v1.PodSpec, namespace string, includePendingWFFC bool) ([]*storkvolume.Info, []*storkvolume.Info, error) {
- var empty []*storkvolume.Info
+ // includePendingWFFC - Includes pending volumes in the second return value if they are using WaitForFirstConsumer binding mode
var volumes []*storkvolume.Info
+ var pendingWFFCVolumes []*storkvolume.Info
for _, volume := range podSpec.Volumes {
volumeName := ""
+ isPendingWFFC := false
if volume.PersistentVolumeClaim != nil {
pvc, err := core.Instance().GetPersistentVolumeClaim(
volume.PersistentVolumeClaim.ClaimName,
@@ -269,10 +272,15 @@ func (l *linstor) GetPodVolumes(podSpec *v1.PodSpec, namespace string, includePe
}
if pvc.Status.Phase == v1.ClaimPending {
+ // Only include pending volume if requested and storage class has WFFC
+ if includePendingWFFC && isWaitingForFirstConsumer(pvc) {
+ isPendingWFFC = true
+ } else {
return nil, nil, &storkvolume.ErrPVCPending{
Name: volume.PersistentVolumeClaim.ClaimName,
}
}
+ }
volumeName = pvc.Spec.VolumeName
}
@@ -284,10 +292,29 @@ func (l *linstor) GetPodVolumes(podSpec *v1.PodSpec, namespace string, includePe
VolumeName: volumeName,
}
}
+ if isPendingWFFC {
+ pendingWFFCVolumes = append(pendingWFFCVolumes, volumeInfo)
+ } else {
volumes = append(volumes, volumeInfo)
}
}
- return volumes, empty, nil
+ }
+ return volumes, pendingWFFCVolumes, nil
+}
+
+func isWaitingForFirstConsumer(pvc *v1.PersistentVolumeClaim) bool {
+ var sc *storagev1.StorageClass
+ var err error
+ storageClassName := k8shelper.GetPersistentVolumeClaimClass(pvc)
+ if storageClassName != "" {
+ sc, err = storage.Instance().GetStorageClass(storageClassName)
+ if err != nil {
+ logrus.Warnf("Did not get the storageclass %s for pvc %s/%s, err: %v", storageClassName, pvc.Namespace, pvc.Name, err)
+ return false
+ }
+ return *sc.VolumeBindingMode == storagev1.VolumeBindingWaitForFirstConsumer
+ }
+ return false
}
func (l *linstor) GetVolumeClaimTemplates(templates []v1.PersistentVolumeClaim) ([]v1.PersistentVolumeClaim, error) {
