Skip to content

Commit 506d9cc

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 39fd0d7 commit 506d9cc

File tree

8 files changed

+323
-12
lines changed

8 files changed

+323
-12
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
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'")
4547
)
4648
klog.InitFlags(nil)
@@ -60,7 +62,7 @@ func main() {
6062
if err != nil {
6163
klog.Fatalln(err)
6264
}
63-
drv := driver.NewDriver(*endpoint, etcAmazonEfs, *efsUtilsStaticFilesPath, *tags, *volMetricsOptIn, *volMetricsRefreshPeriod, *volMetricsFsRateLimit, *deleteAccessPointRootDir)
65+
drv := driver.NewDriver(*endpoint, etcAmazonEfs, *efsUtilsStaticFilesPath, *tags, *volMetricsOptIn, *volMetricsRefreshPeriod, *volMetricsFsRateLimit, *deleteAccessPointRootDir, *deleteProvisionedDir)
6466
if err := drv.Run(); err != nil {
6567
klog.Fatalln(err)
6668
}

pkg/driver/controller.go

Lines changed: 13 additions & 6 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,20 +121,26 @@ 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

131+
var provisioningMode string
130132
if accessPointId != "" {
131-
err := d.provisioners[AccessPointMode].Delete(ctx, req)
132-
if err != nil {
133-
return nil, status.Errorf(codes.Internal, "Failed to Delete volume %v: %v", volId, err)
134-
}
133+
provisioningMode = AccessPointMode
134+
} else if subpath != "" {
135+
provisioningMode = DirectoryMode
135136
} else {
136-
return nil, status.Errorf(codes.NotFound, "Failed to find access point for volume: %v", volId)
137+
return nil, status.Errorf(codes.NotFound, "Failed to find identifying information for volume: %v", volId)
138+
}
139+
140+
klog.V(5).Infof("DeleteVolume: provisioningMode %v", provisioningMode)
141+
err = d.provisioners[provisioningMode].Delete(ctx, req)
142+
if err != nil {
143+
return nil, status.Errorf(codes.Internal, "Failed to Delete volume %v: %v", volId, err)
137144
}
138145

139146
return &csi.DeleteVolumeResponse{}, nil

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),
2935+
provisioners: getProvisioners(cloud, mounter, parseTagsFromStr(tags), deleteAccessPointRootDir, &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) *Driver {
55+
func NewDriver(endpoint, efsUtilsCfgPath, efsUtilsStaticFilesPath, tags string, volMetricsOptIn bool, volMetricsRefreshPeriod float64, volMetricsFsRateLimit int, deleteAccessPointRootDir bool, deleteProvisionedDir bool) *Driver {
5656
cloud, err := cloud.NewCloud()
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)
65+
provisioners := getProvisioners(cloud, mounter, parsedTags, deleteAccessPointRootDir, &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
@@ -20,7 +20,7 @@ type BaseProvisioner struct {
2020
mounter Mounter
2121
}
2222

23-
func getProvisioners(cloud cloud.Cloud, mounter Mounter, tags map[string]string, deleteAccessPointRootDir bool) map[string]Provisioner {
23+
func getProvisioners(cloud cloud.Cloud, mounter Mounter, tags map[string]string, deleteAccessPointRootDir bool, osClient OsClient, deleteProvisionedDir bool) map[string]Provisioner {
2424
return map[string]Provisioner{
2525
AccessPointMode: AccessPointProvisioner{
2626
BaseProvisioner: BaseProvisioner{
@@ -31,6 +31,14 @@ func getProvisioners(cloud cloud.Cloud, mounter Mounter, tags map[string]string,
3131
gidAllocator: NewGidAllocator(),
3232
deleteAccessPointRootDir: deleteAccessPointRootDir,
3333
},
34+
DirectoryMode: DirectoryProvisioner{
35+
BaseProvisioner: BaseProvisioner{
36+
cloud: cloud,
37+
mounter: mounter,
38+
},
39+
osClient: osClient,
40+
deleteProvisionedDir: deleteProvisionedDir,
41+
},
3442
}
3543
}
3644

0 commit comments

Comments
 (0)