@@ -3,6 +3,8 @@ package e2e
33import (
44 "context"
55 "fmt"
6+ e2epv "k8s.io/kubernetes/test/e2e/framework/pv"
7+ e2evolume "k8s.io/kubernetes/test/e2e/framework/volume"
68 "os"
79 "strconv"
810 "strings"
@@ -416,6 +418,93 @@ var _ = ginkgo.Describe("[efs-csi] EFS CSI", func() {
416418 }
417419 })
418420
421+ createProvisionedDirectory := func (f * framework.Framework , basePath string , pvcName string ) (* v1.PersistentVolumeClaim , * storagev1.StorageClass ) {
422+ immediateBinding := storagev1 .VolumeBindingImmediate
423+ sc := storageframework .GetStorageClass ("efs.csi.aws.com" , map [string ]string {
424+ "provisioningMode" : "efs-dir" ,
425+ "fileSystemId" : FileSystemId ,
426+ "basePath" : basePath ,
427+ }, & immediateBinding , f .Namespace .Name )
428+ sc , err := f .ClientSet .StorageV1 ().StorageClasses ().Create (context .TODO (), sc , metav1.CreateOptions {})
429+ framework .Logf ("Created StorageClass %s" , sc .Name )
430+ framework .ExpectNoError (err , "creating dynamic provisioning storage class" )
431+ pvc := makeEFSPVC (f .Namespace .Name , pvcName , sc .Name )
432+ pvc , err = f .ClientSet .CoreV1 ().PersistentVolumeClaims (f .Namespace .Name ).Create (context .TODO (), pvc , metav1.CreateOptions {})
433+ err = e2epv .WaitForPersistentVolumeClaimPhase (context .TODO (), v1 .ClaimBound , f .ClientSet , f .Namespace .Name , pvc .Name ,
434+ time .Second * 5 , time .Minute )
435+ framework .ExpectNoError (err , "waiting for pv to be provisioned and bound" )
436+ pvc , err = f .ClientSet .CoreV1 ().PersistentVolumeClaims (f .Namespace .Name ).Get (context .TODO (), pvc .Name , metav1.GetOptions {})
437+
438+ framework .Logf ("Created PVC %s, bound to PV %s by dynamic provisioning" , sc .Name , pvc .Name , pvc .Spec .VolumeName )
439+ return pvc , sc
440+ }
441+
442+ ginkgo .It ("should create a directory with the correct permissions when in directory provisioning mode" , func () {
443+ basePath := "dynamic_provisioning"
444+ dynamicPvc , sc := createProvisionedDirectory (f , basePath , "directory-pvc-1" )
445+ defer func () {
446+ err := f .ClientSet .StorageV1 ().StorageClasses ().Delete (context .TODO (), sc .Name , metav1.DeleteOptions {})
447+ framework .ExpectNoError (err , "removing provisioned StorageClass" )
448+ framework .Logf ("Deleted StorageClass %s" , sc .Name )
449+ }()
450+
451+ pvc , pv , err := createEFSPVCPV (f .ClientSet , f .Namespace .Name , "root-dir-pvc-create" , "/" , map [string ]string {})
452+ defer func () {
453+ _ = f .ClientSet .CoreV1 ().PersistentVolumeClaims (f .Namespace .Name ).Delete (context .TODO (), pvc .Name , metav1.DeleteOptions {})
454+ _ = f .ClientSet .CoreV1 ().PersistentVolumes ().Delete (context .TODO (), pv .Name , metav1.DeleteOptions {})
455+ }()
456+ framework .ExpectNoError (err , "creating root mounted pv, pvc to check" )
457+
458+ podSpec := e2epod .MakePod (f .Namespace .Name , nil , []* v1.PersistentVolumeClaim {pvc }, false , "" )
459+ podSpec .Spec .RestartPolicy = v1 .RestartPolicyNever
460+ pod , err := f .ClientSet .CoreV1 ().Pods (f .Namespace .Name ).Create (context .TODO (), podSpec , metav1.CreateOptions {})
461+ framework .ExpectNoError (err , "creating pod" )
462+ err = e2epod .WaitForPodRunningInNamespace (context .TODO (), f .ClientSet , pod )
463+ framework .ExpectNoError (err , "pod started running successfully" )
464+
465+ provisionedPath := fmt .Sprintf ("/mnt/volume1/%s/%s" , basePath , dynamicPvc .Spec .VolumeName )
466+
467+ perms , _ , err := e2evolume .PodExec (f , pod , "stat -c \" %a\" " + provisionedPath )
468+ framework .ExpectNoError (err , "ran stat command in /mnt/volume1 to get folder permissions" )
469+ framework .Logf ("Perms Output: %s" , perms )
470+ framework .ExpectEqual (perms , fmt .Sprintf ("%d" , 777 ), "Checking File Permissions of mounted folder" )
471+
472+ _ = f .ClientSet .CoreV1 ().Pods (f .Namespace .Name ).Delete (context .TODO (), pod .Name , metav1.DeleteOptions {})
473+ })
474+
475+ ginkgo .It ("should delete a directory provisioned in directory provisioning mode" , func () {
476+ basePath := "dynamic_provisioning_delete"
477+ pvc , sc := createProvisionedDirectory (f , basePath , "directory-pvc-2" )
478+ defer func () {
479+ err := f .ClientSet .StorageV1 ().StorageClasses ().Delete (context .TODO (), sc .Name , metav1.DeleteOptions {})
480+ framework .ExpectNoError (err , "removing provisioned StorageClass" )
481+ framework .Logf ("Deleted StorageClass %s" , sc .Name )
482+ }()
483+ volumeName := pvc .Spec .VolumeName
484+
485+ err := f .ClientSet .CoreV1 ().PersistentVolumeClaims (f .Namespace .Name ).Delete (context .TODO (), pvc .Name ,
486+ metav1.DeleteOptions {})
487+ framework .ExpectNoError (err , "deleting pvc" )
488+
489+ pvc , pv , err := createEFSPVCPV (f .ClientSet , f .Namespace .Name , "root-dir-pvc-delete" , "/" , map [string ]string {})
490+ defer func () {
491+ _ = f .ClientSet .CoreV1 ().PersistentVolumeClaims (f .Namespace .Name ).Delete (context .TODO (), pvc .Name , metav1.DeleteOptions {})
492+ _ = f .ClientSet .CoreV1 ().PersistentVolumes ().Delete (context .TODO (), pv .Name , metav1.DeleteOptions {})
493+ }()
494+ framework .ExpectNoError (err , "creating root mounted pv, pvc to check" )
495+
496+ podSpec := e2epod .MakePod (f .Namespace .Name , nil , []* v1.PersistentVolumeClaim {pvc }, false , "" )
497+ podSpec .Spec .RestartPolicy = v1 .RestartPolicyNever
498+ pod , err := f .ClientSet .CoreV1 ().Pods (f .Namespace .Name ).Create (context .TODO (), podSpec , metav1.CreateOptions {})
499+ framework .ExpectNoError (err , "creating pod" )
500+ err = e2epod .WaitForPodRunningInNamespace (context .TODO (), f .ClientSet , pod )
501+ framework .ExpectNoError (err , "pod started running successfully" )
502+
503+ e2evolume .VerifyExecInPodFail (f , pod , "test -d " + "/mnt/volume1/" + basePath + "/" + volumeName , 1 )
504+
505+ _ = f .ClientSet .CoreV1 ().Pods (f .Namespace .Name ).Delete (context .TODO (), pod .Name , metav1.DeleteOptions {})
506+ })
507+
419508 })
420509})
421510
@@ -476,7 +565,7 @@ func createEFSPVCPV(c clientset.Interface, namespace, name, path string, volumeA
476565}
477566
478567func makeEFSPVCPV (namespace , name , path string , volumeAttributes map [string ]string ) (* v1.PersistentVolumeClaim , * v1.PersistentVolume ) {
479- pvc := makeEFSPVC (namespace , name )
568+ pvc := makeEFSPVC (namespace , name , "" )
480569 pv := makeEFSPV (name , path , volumeAttributes )
481570 pvc .Spec .VolumeName = pv .Name
482571 pv .Spec .ClaimRef = & v1.ObjectReference {
@@ -486,8 +575,7 @@ func makeEFSPVCPV(namespace, name, path string, volumeAttributes map[string]stri
486575 return pvc , pv
487576}
488577
489- func makeEFSPVC (namespace , name string ) * v1.PersistentVolumeClaim {
490- storageClassName := ""
578+ func makeEFSPVC (namespace , name string , storageClassName string ) * v1.PersistentVolumeClaim {
491579 return & v1.PersistentVolumeClaim {
492580 ObjectMeta : metav1.ObjectMeta {
493581 Name : name ,
0 commit comments