#6: Update path creation and implemented possibility save data after removing PV
This commit is contained in:
		
							parent
							
								
									ce96952150
								
							
						
					
					
						commit
						9d6c66ea94
					
				|  | @ -22,14 +22,14 @@ import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"os" | 	"os" | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"strconv" | 	"regexp" | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"k8s.io/kubernetes/pkg/apis/core/v1/helper" | 	"k8s.io/kubernetes/pkg/apis/core/v1/helper" | ||||||
| 
 | 
 | ||||||
| 	"github.com/golang/glog" | 	"github.com/golang/glog" | ||||||
| 	"sigs.k8s.io/sig-storage-lib-external-provisioner/controller" | 	"github.com/kubernetes-sigs/sig-storage-lib-external-provisioner/controller" | ||||||
| 	"k8s.io/api/core/v1" | 	v1 "k8s.io/api/core/v1" | ||||||
| 	storage "k8s.io/api/storage/v1" | 	storage "k8s.io/api/storage/v1" | ||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/util/wait" | 	"k8s.io/apimachinery/pkg/util/wait" | ||||||
|  | @ -47,13 +47,36 @@ type nfsProvisioner struct { | ||||||
| 	path   string | 	path   string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | type pvcMetadata struct { | ||||||
|  | 	data        map[string]string | ||||||
|  | 	labels      map[string]string | ||||||
|  | 	annotations map[string]string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (meta *pvcMetadata) stringParser(str string) string { | ||||||
|  | 	pattern := regexp.MustCompile(`{pvc\.((labels|annotations)\.(.*?)|.*?)}`) | ||||||
|  | 	result := pattern.FindAllStringSubmatch(str, -1) | ||||||
|  | 	for _, r := range result { | ||||||
|  | 		switch r[2] { | ||||||
|  | 		case "labels": | ||||||
|  | 			str = strings.Replace(str, r[0], meta.labels[r[3]], -1) | ||||||
|  | 		case "annotations": | ||||||
|  | 			fmt.Println(r[0], r[3], meta.annotations[r[3]]) | ||||||
|  | 			str = strings.Replace(str, r[0], meta.annotations[r[3]], -1) | ||||||
|  | 		default: | ||||||
|  | 			str = strings.Replace(str, r[0], meta.data[r[1]], -1) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return str | ||||||
|  | } | ||||||
|  | 
 | ||||||
| const ( | const ( | ||||||
| 	mountPath = "/persistentvolumes" | 	mountPath = "/persistentvolumes" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var _ controller.Provisioner = &nfsProvisioner{} | var _ controller.Provisioner = &nfsProvisioner{} | ||||||
| 
 | 
 | ||||||
| func (p *nfsProvisioner) Provision(options controller.ProvisionOptions) (*v1.PersistentVolume, error) { | func (p *nfsProvisioner) Provision(options controller.VolumeOptions) (*v1.PersistentVolume, error) { | ||||||
| 	if options.PVC.Spec.Selector != nil { | 	if options.PVC.Spec.Selector != nil { | ||||||
| 		return nil, fmt.Errorf("claim Selector is not supported") | 		return nil, fmt.Errorf("claim Selector is not supported") | ||||||
| 	} | 	} | ||||||
|  | @ -64,23 +87,39 @@ func (p *nfsProvisioner) Provision(options controller.ProvisionOptions) (*v1.Per | ||||||
| 
 | 
 | ||||||
| 	pvName := strings.Join([]string{pvcNamespace, pvcName, options.PVName}, "-") | 	pvName := strings.Join([]string{pvcNamespace, pvcName, options.PVName}, "-") | ||||||
| 
 | 
 | ||||||
|  | 	metadata := &pvcMetadata{ | ||||||
|  | 		data: map[string]string{ | ||||||
|  | 			"name":      pvcName, | ||||||
|  | 			"namespace": pvcNamespace, | ||||||
|  | 		}, | ||||||
|  | 		labels:      options.PVC.Labels, | ||||||
|  | 		annotations: options.PVC.Annotations, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	fullPath := filepath.Join(mountPath, pvName) | 	fullPath := filepath.Join(mountPath, pvName) | ||||||
|  | 	path := filepath.Join(p.path, pvName) | ||||||
|  | 
 | ||||||
|  | 	pathPattern, exists := options.Parameters["pathPattern"] | ||||||
|  | 	if exists { | ||||||
|  | 		customPath := metadata.stringParser(pathPattern) | ||||||
|  | 		path = filepath.Join(p.path, customPath) | ||||||
|  | 		fullPath = filepath.Join(mountPath, customPath) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	glog.V(4).Infof("creating path %s", fullPath) | 	glog.V(4).Infof("creating path %s", fullPath) | ||||||
| 	if err := os.MkdirAll(fullPath, 0777); err != nil { | 	if err := os.MkdirAll(fullPath, 0777); err != nil { | ||||||
| 		return nil, errors.New("unable to create directory to provision new pv: " + err.Error()) | 		return nil, errors.New("unable to create directory to provision new pv: " + err.Error()) | ||||||
| 	} | 	} | ||||||
| 	os.Chmod(fullPath, 0777) | 	os.Chmod(fullPath, 0777) | ||||||
| 
 | 
 | ||||||
| 	path := filepath.Join(p.path, pvName) |  | ||||||
| 
 |  | ||||||
| 	pv := &v1.PersistentVolume{ | 	pv := &v1.PersistentVolume{ | ||||||
| 		ObjectMeta: metav1.ObjectMeta{ | 		ObjectMeta: metav1.ObjectMeta{ | ||||||
| 			Name: options.PVName, | 			Name: options.PVName, | ||||||
| 		}, | 		}, | ||||||
| 		Spec: v1.PersistentVolumeSpec{ | 		Spec: v1.PersistentVolumeSpec{ | ||||||
| 			PersistentVolumeReclaimPolicy: *options.StorageClass.ReclaimPolicy, | 			PersistentVolumeReclaimPolicy: options.PersistentVolumeReclaimPolicy, | ||||||
| 			AccessModes:                   options.PVC.Spec.AccessModes, | 			AccessModes:                   options.PVC.Spec.AccessModes, | ||||||
| 			//MountOptions:                  options.MountOptions,
 | 			MountOptions:                  options.MountOptions, | ||||||
| 			Capacity: v1.ResourceList{ | 			Capacity: v1.ResourceList{ | ||||||
| 				v1.ResourceName(v1.ResourceStorage): options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)], | 				v1.ResourceName(v1.ResourceStorage): options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)], | ||||||
| 			}, | 			}, | ||||||
|  | @ -98,8 +137,9 @@ func (p *nfsProvisioner) Provision(options controller.ProvisionOptions) (*v1.Per | ||||||
| 
 | 
 | ||||||
| func (p *nfsProvisioner) Delete(volume *v1.PersistentVolume) error { | func (p *nfsProvisioner) Delete(volume *v1.PersistentVolume) error { | ||||||
| 	path := volume.Spec.PersistentVolumeSource.NFS.Path | 	path := volume.Spec.PersistentVolumeSource.NFS.Path | ||||||
| 	pvName := filepath.Base(path) | 	relativePath := strings.Replace(path, p.path, "", 1) | ||||||
| 	oldPath := filepath.Join(mountPath, pvName) | 	oldPath := filepath.Join(mountPath, relativePath) | ||||||
|  | 
 | ||||||
| 	if _, err := os.Stat(oldPath); os.IsNotExist(err) { | 	if _, err := os.Stat(oldPath); os.IsNotExist(err) { | ||||||
| 		glog.Warningf("path %s does not exist, deletion skipped", oldPath) | 		glog.Warningf("path %s does not exist, deletion skipped", oldPath) | ||||||
| 		return nil | 		return nil | ||||||
|  | @ -112,21 +152,20 @@ func (p *nfsProvisioner) Delete(volume *v1.PersistentVolume) error { | ||||||
| 	// Determine if the "archiveOnDelete" parameter exists.
 | 	// Determine if the "archiveOnDelete" parameter exists.
 | ||||||
| 	// If it exists and has a false value, delete the directory.
 | 	// If it exists and has a false value, delete the directory.
 | ||||||
| 	// Otherwise, archive it.
 | 	// Otherwise, archive it.
 | ||||||
| 	archiveOnDelete, exists := storageClass.Parameters["archiveOnDelete"] | 	onDelete := storageClass.Parameters["onDelete"] | ||||||
| 	if exists { | 	switch onDelete { | ||||||
| 		archiveBool, err := strconv.ParseBool(archiveOnDelete) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		if !archiveBool { |  | ||||||
| 			return os.RemoveAll(oldPath) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	archivePath := filepath.Join(mountPath, "archived-"+pvName) | 	case "delete": | ||||||
|  | 		return os.RemoveAll(oldPath) | ||||||
|  | 
 | ||||||
|  | 	case "retain": | ||||||
|  | 		return nil | ||||||
|  | 
 | ||||||
|  | 	default: | ||||||
|  | 		archivePath := filepath.Join(mountPath, "archived-"+volume.Name) | ||||||
| 		glog.V(4).Infof("archiving path %s to %s", oldPath, archivePath) | 		glog.V(4).Infof("archiving path %s to %s", oldPath, archivePath) | ||||||
| 		return os.Rename(oldPath, archivePath) | 		return os.Rename(oldPath, archivePath) | ||||||
| 
 | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // getClassForVolume returns StorageClass
 | // getClassForVolume returns StorageClass
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue