func (r *glusterfsVolumeProvisioner) Provision() (*v1.PersistentVolume, error) { var err error if r.options.PVC.Spec.Selector != nil { glog.V(4).Infof("glusterfs: not able to parse your claim Selector") return nil, fmt.Errorf("glusterfs: not able to parse your claim Selector") } glog.V(4).Infof("glusterfs: Provison VolumeOptions %v", r.options) scName := storageutil.GetClaimStorageClass(r.options.PVC) cfg, err := parseClassParameters(r.options.Parameters, r.plugin.host.GetKubeClient()) if err != nil { return nil, err } r.provisioningConfig = *cfg glog.V(4).Infof("glusterfs: creating volume with configuration %+v", r.provisioningConfig) gidTable, err := r.plugin.getGidTable(scName, cfg.gidMin, cfg.gidMax) if err != nil { return nil, fmt.Errorf("glusterfs: failed to get gidTable: %v", err) } gid, _, err := gidTable.AllocateNext() if err != nil { glog.Errorf("glusterfs: failed to reserve gid from table: %v", err) return nil, fmt.Errorf("glusterfs: failed to reserve gid from table: %v", err) } glog.V(2).Infof("glusterfs: got gid [%d] for PVC %s", gid, r.options.PVC.Name) glusterfs, sizeGB, err := r.CreateVolume(gid) if err != nil { if release_err := gidTable.Release(gid); release_err != nil { glog.Errorf("glusterfs: error when releasing gid in storageclass: %s", scName) } glog.Errorf("glusterfs: create volume err: %v.", err) return nil, fmt.Errorf("glusterfs: create volume err: %v.", err) } pv := new(v1.PersistentVolume) pv.Spec.PersistentVolumeSource.Glusterfs = glusterfs pv.Spec.PersistentVolumeReclaimPolicy = r.options.PersistentVolumeReclaimPolicy pv.Spec.AccessModes = r.options.PVC.Spec.AccessModes if len(pv.Spec.AccessModes) == 0 { pv.Spec.AccessModes = r.plugin.GetAccessModes() } gidStr := strconv.FormatInt(int64(gid), 10) pv.Annotations = map[string]string{volumehelper.VolumeGidAnnotationKey: gidStr} pv.Spec.Capacity = v1.ResourceList{ v1.ResourceName(v1.ResourceStorage): resource.MustParse(fmt.Sprintf("%dGi", sizeGB)), } return pv, nil }
func addVolumeAnnotation(volume *v1.PersistentVolume, annName, annValue string) *v1.PersistentVolume { if volume.Annotations == nil { volume.Annotations = make(map[string]string) } volume.Annotations[annName] = annValue return volume }
// newVolume returns a new volume with given attributes func newVolume(name, capacity, boundToClaimUID, boundToClaimName string, phase v1.PersistentVolumePhase, reclaimPolicy v1.PersistentVolumeReclaimPolicy, annotations ...string) *v1.PersistentVolume { volume := v1.PersistentVolume{ ObjectMeta: v1.ObjectMeta{ Name: name, ResourceVersion: "1", }, Spec: v1.PersistentVolumeSpec{ Capacity: v1.ResourceList{ v1.ResourceName(v1.ResourceStorage): resource.MustParse(capacity), }, PersistentVolumeSource: v1.PersistentVolumeSource{ GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{}, }, AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce, v1.ReadOnlyMany}, PersistentVolumeReclaimPolicy: reclaimPolicy, }, Status: v1.PersistentVolumeStatus{ Phase: phase, }, } if boundToClaimName != "" { volume.Spec.ClaimRef = &v1.ObjectReference{ Kind: "PersistentVolumeClaim", APIVersion: "v1", UID: types.UID(boundToClaimUID), Namespace: testNamespace, Name: boundToClaimName, } } if len(annotations) > 0 { volume.Annotations = make(map[string]string) for _, a := range annotations { switch a { case annDynamicallyProvisioned: volume.Annotations[a] = mockPluginName case storageutil.StorageClassAnnotation: volume.Annotations[a] = "gold" default: volume.Annotations[a] = "yes" } } } return &volume }