Skip to content

Commit 6bc821a

Browse files
committed
Add directory provisioning mode
Implement `DirectoryProvisioner` struct and its `Provision/Delete` methods. Add `delete-provisioned-dir` command-line option to control DeleteVolume behavior in efs-dir mode.
1 parent e952280 commit 6bc821a

File tree

8 files changed

+321
-10
lines changed

8 files changed

+321
-10
lines changed

cmd/main.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ func main() {
4141
volMetricsFsRateLimit = flag.Int("vol-metrics-fs-rate-limit", 5, "Volume metrics routines rate limiter per file system")
4242
deleteAccessPointRootDir = flag.Bool("delete-access-point-root-dir", false,
4343
"Opt in to delete access point root directory by DeleteVolume. By default, DeleteVolume will delete the access point behind Persistent Volume and deleting access point will not delete the access point root directory or its contents.")
44+
deleteProvisionedDir = flag.Bool("delete-provisioned-dir", false,
45+
"Opt in to delete any provisioned directories and their contents. By default, DeleteVolume will not delete the directory behind Persistent Volume. Note: If root squash is enabled on your EFS it's possible this option will not work.")
4446
adaptiveRetryMode = flag.Bool("adaptive-retry-mode", true, "Opt out to use standard sdk retry configuration. By default, adaptive retry mode will be used to more heavily client side rate limit EFS API requests.")
4547
tags = flag.String("tags", "", "Space separated key:value pairs which will be added as tags for EFS resources. For example, 'environment:prod region:us-east-1'")
4648
)
@@ -61,7 +63,7 @@ func main() {
6163
if err != nil {
6264
klog.Fatalln(err)
6365
}
64-
drv := driver.NewDriver(*endpoint, etcAmazonEfs, *efsUtilsStaticFilesPath, *tags, *volMetricsOptIn, *volMetricsRefreshPeriod, *volMetricsFsRateLimit, *deleteAccessPointRootDir, *adaptiveRetryMode)
66+
drv := driver.NewDriver(*endpoint, etcAmazonEfs, *efsUtilsStaticFilesPath, *tags, *volMetricsOptIn, *volMetricsRefreshPeriod, *volMetricsFsRateLimit, *deleteAccessPointRootDir, *adaptiveRetryMode, *deleteProvisionedDir)
6567
if err := drv.Run(); err != nil {
6668
klog.Fatalln(err)
6769
}

pkg/driver/controller.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const (
4040
DefaultTagKey = "efs.csi.aws.com/cluster"
4141
DefaultTagValue = "true"
4242
DirectoryPerms = "directoryPerms"
43+
DirectoryMode = "efs-dir"
4344
EnsureUniqueDirectory = "ensureUniqueDirectory"
4445
FsId = "fileSystemId"
4546
Gid = "gid"
@@ -120,19 +121,25 @@ func (d *Driver) DeleteVolume(ctx context.Context, req *csi.DeleteVolumeRequest)
120121
return nil, status.Error(codes.InvalidArgument, "Volume ID not provided")
121122
}
122123

123-
_, _, accessPointId, err := parseVolumeId(volId)
124+
_, subpath, accessPointId, err := parseVolumeId(volId)
124125
if err != nil {
125126
//Returning success for an invalid volume ID. See here - https://github.com/kubernetes-csi/csi-test/blame/5deb83d58fea909b2895731d43e32400380aae3c/pkg/sanity/controller.go#L733
126127
klog.V(5).Infof("DeleteVolume: Failed to parse volumeID: %v, err: %v, returning success", volId, err)
127128
return &csi.DeleteVolumeResponse{}, nil
128129
}
129130

130-
if accessPointId == "" {
131-
klog.V(5).Infof("DeleteVolume: No Access Point for volume %v, returning success", volId)
131+
var provisioningMode string
132+
if accessPointId != "" {
133+
provisioningMode = AccessPointMode
134+
} else if subpath != "" {
135+
provisioningMode = DirectoryMode
136+
} else {
137+
klog.V(5).Infof("DeleteVolume: No Access Point or subpath for volume %v, returning success", volId)
132138
return &csi.DeleteVolumeResponse{}, nil
133139
}
134140

135-
err = d.provisioners[AccessPointMode].Delete(ctx, req)
141+
klog.V(5).Infof("DeleteVolume: provisioningMode %v", provisioningMode)
142+
err = d.provisioners[provisioningMode].Delete(ctx, req)
136143
if err != nil {
137144
return nil, status.Errorf(codes.Internal, "Failed to Delete volume %v: %v", volId, err)
138145
}

pkg/driver/controller_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2932,6 +2932,6 @@ func buildDriver(endpoint string, cloud cloud.Cloud, tags string, mounter Mounte
29322932
endpoint: endpoint,
29332933
cloud: cloud,
29342934
mounter: mounter,
2935-
provisioners: getProvisioners(cloud, mounter, parseTagsFromStr(tags), deleteAccessPointRootDir, false),
2935+
provisioners: getProvisioners(cloud, mounter, parseTagsFromStr(tags), deleteAccessPointRootDir, false, &FakeOsClient{}, false),
29362936
}
29372937
}

pkg/driver/driver.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ type Driver struct {
5252
provisioners map[string]Provisioner
5353
}
5454

55-
func NewDriver(endpoint, efsUtilsCfgPath, efsUtilsStaticFilesPath, tags string, volMetricsOptIn bool, volMetricsRefreshPeriod float64, volMetricsFsRateLimit int, deleteAccessPointRootDir bool, adaptiveRetryMode bool) *Driver {
55+
func NewDriver(endpoint, efsUtilsCfgPath, efsUtilsStaticFilesPath, tags string, volMetricsOptIn bool, volMetricsRefreshPeriod float64, volMetricsFsRateLimit int, deleteAccessPointRootDir bool, adaptiveRetryMode bool, deleteProvisionedDir bool) *Driver {
5656
cloud, err := cloud.NewCloud(adaptiveRetryMode)
5757
if err != nil {
5858
klog.Fatalln(err)
@@ -62,7 +62,7 @@ func NewDriver(endpoint, efsUtilsCfgPath, efsUtilsStaticFilesPath, tags string,
6262
watchdog := newExecWatchdog(efsUtilsCfgPath, efsUtilsStaticFilesPath, "amazon-efs-mount-watchdog")
6363
mounter := newNodeMounter()
6464
parsedTags := parseTagsFromStr(strings.TrimSpace(tags))
65-
provisioners := getProvisioners(cloud, mounter, parsedTags, deleteAccessPointRootDir, adaptiveRetryMode)
65+
provisioners := getProvisioners(cloud, mounter, parsedTags, deleteAccessPointRootDir, adaptiveRetryMode, &RealOsClient{}, deleteProvisionedDir)
6666
return &Driver{
6767
endpoint: endpoint,
6868
nodeID: cloud.GetMetadata().GetInstanceID(),

pkg/driver/os_client.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package driver
2+
3+
import "os"
4+
5+
type OsClient interface {
6+
MkDirAllWithPerms(path string, perms os.FileMode, uid, gid int) error
7+
MkDirAllWithPermsNoOwnership(path string, perms os.FileMode) error
8+
GetPerms(path string) (os.FileMode, error)
9+
Remove(path string) error
10+
RemoveAll(path string) error
11+
}
12+
13+
// Real OsClient
14+
15+
type RealOsClient struct{}
16+
17+
func NewOsClient() *RealOsClient {
18+
return &RealOsClient{}
19+
}
20+
21+
func (o *RealOsClient) MkDirAllWithPerms(path string, perms os.FileMode, uid, gid int) error {
22+
err := os.MkdirAll(path, perms)
23+
if err != nil {
24+
return err
25+
}
26+
// Extra CHMOD guarantees we get the permissions we desire, inspite of the umask
27+
err = os.Chmod(path, perms)
28+
if err != nil {
29+
return err
30+
}
31+
err = os.Chown(path, uid, gid)
32+
if err != nil {
33+
return err
34+
}
35+
return nil
36+
}
37+
38+
func (o *RealOsClient) MkDirAllWithPermsNoOwnership(path string, perms os.FileMode) error {
39+
err := os.MkdirAll(path, perms)
40+
if err != nil {
41+
return err
42+
}
43+
// Extra CHMOD guarantees we get the permissions we desire, inspite of the umask
44+
err = os.Chmod(path, perms)
45+
if err != nil {
46+
return err
47+
}
48+
return nil
49+
}
50+
51+
func (o *RealOsClient) Remove(path string) error {
52+
return os.Remove(path)
53+
}
54+
55+
func (o *RealOsClient) RemoveAll(path string) error {
56+
return os.RemoveAll(path)
57+
}
58+
59+
func (o *RealOsClient) GetPerms(path string) (os.FileMode, error) {
60+
fInfo, err := os.Stat(path)
61+
if err != nil {
62+
return 0, err
63+
}
64+
return fInfo.Mode(), nil
65+
}
66+
67+
// Fake OsClient
68+
69+
type FakeOsClient struct{}
70+
71+
func (o *FakeOsClient) MkDirAllWithPerms(_ string, _ os.FileMode, _, _ int) error {
72+
return nil
73+
}
74+
75+
func (o *FakeOsClient) MkDirAllWithPermsNoOwnership(_ string, _ os.FileMode) error {
76+
return nil
77+
}
78+
79+
func (o *FakeOsClient) Remove(_ string) error {
80+
return nil
81+
}
82+
83+
func (o *FakeOsClient) RemoveAll(_ string) error {
84+
return nil
85+
}
86+
87+
func (o *FakeOsClient) GetPerms(_ string) (os.FileMode, error) {
88+
return 0, nil
89+
}

pkg/driver/provisioner.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type BaseProvisioner struct {
2121
adaptiveRetryMode bool
2222
}
2323

24-
func getProvisioners(cloud cloud.Cloud, mounter Mounter, tags map[string]string, deleteAccessPointRootDir bool, adaptiveRetryMode bool) map[string]Provisioner {
24+
func getProvisioners(cloud cloud.Cloud, mounter Mounter, tags map[string]string, deleteAccessPointRootDir bool, adaptiveRetryMode bool, osClient OsClient, deleteProvisionedDir bool) map[string]Provisioner {
2525
return map[string]Provisioner{
2626
AccessPointMode: AccessPointProvisioner{
2727
BaseProvisioner: BaseProvisioner{
@@ -33,6 +33,14 @@ func getProvisioners(cloud cloud.Cloud, mounter Mounter, tags map[string]string,
3333
gidAllocator: NewGidAllocator(),
3434
deleteAccessPointRootDir: deleteAccessPointRootDir,
3535
},
36+
DirectoryMode: DirectoryProvisioner{
37+
BaseProvisioner: BaseProvisioner{
38+
cloud: cloud,
39+
mounter: mounter,
40+
},
41+
osClient: osClient,
42+
deleteProvisionedDir: deleteProvisionedDir,
43+
},
3644
}
3745
}
3846

0 commit comments

Comments
 (0)