Skip to content

Commit be6ca6f

Browse files
authored
Merge pull request #530 from navilg/feature/on-delete-archive
feat: archive on delete support
2 parents db71902 + 5fbe712 commit be6ca6f

File tree

8 files changed

+102
-21
lines changed

8 files changed

+102
-21
lines changed

charts/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ The following table lists the configurable parameters of the latest NFS CSI Driv
6868
| `controller.runOnMaster` | run controller on master node(deprecated on k8s 1.25+) |`false` |
6969
| `controller.runOnControlPlane` | run controller on control plane node |`false` |
7070
| `controller.dnsPolicy` | dnsPolicy of controller driver, available values: `Default`, `ClusterFirstWithHostNet`, `ClusterFirst` | `ClusterFirstWithHostNet` |
71-
| `controller.defaultOnDeletePolicy` | default policy for deleting subdirectory when deleting a volume, available values: `delete`, `retain` | `delete` |
71+
| `controller.defaultOnDeletePolicy` | default policy for deleting subdirectory when deleting a volume, available values: `delete`, `retain`, `archive` | `delete` |
7272
| `controller.logLevel` | controller driver log level |`5` |
7373
| `controller.workingMountDir` | working directory for provisioner to mount nfs shares temporarily | `/tmp` |
7474
| `controller.affinity` | controller pod affinity | `{}` |

docs/driver-parameters.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ server | NFS Server address | domain name `nfs-server.default.svc.cluster.local`
1010
share | NFS share path | `/` | Yes |
1111
subDir | sub directory under nfs share | | No | if sub directory does not exist, this driver would create a new one
1212
mountPermissions | mounted folder permissions. The default is `0`, if set as non-zero, driver will perform `chmod` after mount | | No |
13-
onDelete | when volume is deleted, keep the directory if it's `retain` | `delete`(default), `retain` | No | `delete`
13+
onDelete | when volume is deleted, keep the directory if it's `retain` | `delete`(default), `retain`, `archive` | No | `delete`
1414

1515
- VolumeID(`volumeHandle`) is the identifier of the volume handled by the driver, format of VolumeID:
1616
```

pkg/nfs/controllerserver.go

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -240,15 +240,27 @@ func (cs *ControllerServer) DeleteVolume(ctx context.Context, req *csi.DeleteVol
240240
}
241241
}()
242242

243-
// delete subdirectory under base-dir
244243
internalVolumePath := getInternalVolumePath(cs.Driver.workingMountDir, nfsVol)
245244

246-
klog.V(2).Infof("Removing subdirectory at %v", internalVolumePath)
247-
if err = os.RemoveAll(internalVolumePath); err != nil {
248-
return nil, status.Errorf(codes.Internal, "failed to delete subdirectory: %v", err.Error())
245+
if strings.EqualFold(nfsVol.onDelete, archive) {
246+
archivedNfsVol := *nfsVol
247+
archivedNfsVol.subDir = "archived-" + nfsVol.subDir
248+
archivedInternalVolumePath := getArchivedInternalVolumePath(cs.Driver.workingMountDir, nfsVol, &archivedNfsVol)
249+
250+
// archive subdirectory under base-dir
251+
klog.V(2).Infof("archiving subdirectory %s --> %s", internalVolumePath, archivedInternalVolumePath)
252+
if err = os.Rename(internalVolumePath, archivedInternalVolumePath); err != nil {
253+
return nil, status.Errorf(codes.Internal, "archive subdirectory(%s, %s) failed with %v", internalVolumePath, archivedInternalVolumePath, err.Error())
254+
}
255+
} else {
256+
// delete subdirectory under base-dir
257+
klog.V(2).Infof("removing subdirectory at %v", internalVolumePath)
258+
if err = os.RemoveAll(internalVolumePath); err != nil {
259+
return nil, status.Errorf(codes.Internal, "delete subdirectory(%s) failed with %v", internalVolumePath, err.Error())
260+
}
249261
}
250262
} else {
251-
klog.V(2).Infof("DeleteVolume: volume(%s) is set to retain, not deleting subdirectory", volumeID)
263+
klog.V(2).Infof("DeleteVolume: volume(%s) is set to retain, not deleting/archiving subdirectory", volumeID)
252264
}
253265

254266
return &csi.DeleteVolumeResponse{}, nil
@@ -674,16 +686,21 @@ func getInternalVolumePath(workingMountDir string, vol *nfsVolume) string {
674686
return filepath.Join(getInternalMountPath(workingMountDir, vol), vol.subDir)
675687
}
676688

689+
func getArchivedInternalVolumePath(workingMountDir string, vol *nfsVolume, archVol *nfsVolume) string {
690+
return filepath.Join(getInternalMountPath(workingMountDir, vol), archVol.subDir)
691+
}
692+
677693
// Given a nfsVolume, return a CSI volume id
678694
func getVolumeIDFromNfsVol(vol *nfsVolume) string {
679695
idElements := make([]string, totalIDElements)
680696
idElements[idServer] = strings.Trim(vol.server, "/")
681697
idElements[idBaseDir] = strings.Trim(vol.baseDir, "/")
682698
idElements[idSubDir] = strings.Trim(vol.subDir, "/")
683699
idElements[idUUID] = vol.uuid
684-
if strings.EqualFold(vol.onDelete, retain) {
700+
if strings.EqualFold(vol.onDelete, retain) || strings.EqualFold(vol.onDelete, archive) {
685701
idElements[idOnDelete] = vol.onDelete
686702
}
703+
687704
return strings.Join(idElements, separator)
688705
}
689706

pkg/nfs/controllerserver_test.go

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,19 @@ import (
3838
)
3939

4040
const (
41-
testServer = "test-server"
42-
testBaseDir = "test-base-dir"
43-
testBaseDirNested = "test/base/dir"
44-
testCSIVolume = "volume-name"
45-
testVolumeID = "test-server/test-base-dir/volume-name"
46-
newTestVolumeID = "test-server#test-base-dir#volume-name##"
47-
newTestVolumeWithVolumeID = "test-server#test-base-dir#volume-name#volume-name#"
48-
testVolumeIDNested = "test-server/test/base/dir/volume-name"
49-
newTestVolumeIDNested = "test-server#test/base/dir#volume-name#"
50-
newTestVolumeIDUUID = "test-server#test-base-dir#volume-name#uuid"
51-
newTestVolumeOnDeleteRetain = "test-server#test-base-dir#volume-name#uuid#retain"
52-
newTestVolumeOnDeleteDelete = "test-server#test-base-dir#volume-name#uuid#delete"
41+
testServer = "test-server"
42+
testBaseDir = "test-base-dir"
43+
testBaseDirNested = "test/base/dir"
44+
testCSIVolume = "volume-name"
45+
testVolumeID = "test-server/test-base-dir/volume-name"
46+
newTestVolumeID = "test-server#test-base-dir#volume-name##"
47+
newTestVolumeWithVolumeID = "test-server#test-base-dir#volume-name#volume-name#"
48+
testVolumeIDNested = "test-server/test/base/dir/volume-name"
49+
newTestVolumeIDNested = "test-server#test/base/dir#volume-name#"
50+
newTestVolumeIDUUID = "test-server#test-base-dir#volume-name#uuid"
51+
newTestVolumeOnDeleteRetain = "test-server#test-base-dir#volume-name#uuid#retain"
52+
newTestVolumeOnDeleteDelete = "test-server#test-base-dir#volume-name#uuid#delete"
53+
newTestVolumeOnDeleteArchive = "test-server#test-base-dir#volume-name##archive"
5354
)
5455

5556
func initTestController(t *testing.T) *ControllerServer {
@@ -287,6 +288,14 @@ func TestDeleteVolume(t *testing.T) {
287288
expectedErr: nil,
288289
expectedDeleteSubDir: false,
289290
},
291+
{
292+
desc: "Valid request with onDelete:archive",
293+
testOnWindows: false,
294+
req: &csi.DeleteVolumeRequest{VolumeId: newTestVolumeOnDeleteArchive},
295+
resp: &csi.DeleteVolumeResponse{},
296+
expectedErr: nil,
297+
expectedDeleteSubDir: true,
298+
},
290299
}
291300

292301
for _, test := range cases {
@@ -493,6 +502,19 @@ func TestNfsVolFromId(t *testing.T) {
493502
},
494503
expectErr: false,
495504
},
505+
{
506+
name: "valid request nested ondelete archive",
507+
volumeID: newTestVolumeOnDeleteArchive,
508+
resp: &nfsVolume{
509+
id: newTestVolumeOnDeleteArchive,
510+
server: testServer,
511+
baseDir: testBaseDir,
512+
subDir: testCSIVolume,
513+
uuid: "",
514+
onDelete: "archive",
515+
},
516+
expectErr: false,
517+
},
496518
}
497519

498520
for _, test := range cases {

pkg/nfs/utils.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ const (
3636
separator = "#"
3737
delete = "delete"
3838
retain = "retain"
39+
archive = "archive"
3940
)
4041

41-
var supportedOnDeleteValues = []string{"", delete, retain}
42+
var supportedOnDeleteValues = []string{"", delete, retain, archive}
4243

4344
func validateOnDeleteValue(onDelete string) error {
4445
for _, v := range supportedOnDeleteValues {

pkg/nfs/utils_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,16 @@ func TestValidateOnDeleteValue(t *testing.T) {
333333
onDelete: "Delete",
334334
expected: nil,
335335
},
336+
{
337+
desc: "Archive value",
338+
onDelete: "Archive",
339+
expected: nil,
340+
},
341+
{
342+
desc: "archive value",
343+
onDelete: "archive",
344+
expected: nil,
345+
},
336346
{
337347
desc: "invalid value",
338348
onDelete: "invalid",

test/e2e/dynamic_provisioning_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,4 +350,27 @@ var _ = ginkgo.Describe("Dynamic Provisioning", func() {
350350
}
351351
test.Run(cs, ns)
352352
})
353+
354+
ginkgo.It("should create a volume on demand with archive subdir on delete [nfs.csi.k8s.io]", func() {
355+
pods := []testsuites.PodDetails{
356+
{
357+
Cmd: "echo 'hello world' > /mnt/test-1/data && grep 'hello world' /mnt/test-1/data",
358+
Volumes: []testsuites.VolumeDetails{
359+
{
360+
ClaimSize: "10Gi",
361+
VolumeMount: testsuites.VolumeMountDetails{
362+
NameGenerate: "test-volume-",
363+
MountPathGenerate: "/mnt/test-",
364+
},
365+
},
366+
},
367+
},
368+
}
369+
test := testsuites.DynamicallyProvisionedCmdVolumeTest{
370+
CSIDriver: testDriver,
371+
Pods: pods,
372+
StorageClassParameters: archiveStorageClassParameters,
373+
}
374+
test.Run(cs, ns)
375+
})
353376
})

test/e2e/e2e_suite_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@ var (
7575
"mountPermissions": "0755",
7676
"onDelete": "retain",
7777
}
78+
archiveStorageClassParameters = map[string]string{
79+
"server": nfsServerAddress,
80+
"share": nfsShare,
81+
"csi.storage.k8s.io/provisioner-secret-name": "mount-options",
82+
"csi.storage.k8s.io/provisioner-secret-namespace": "default",
83+
"mountPermissions": "0755",
84+
"onDelete": "archive",
85+
}
7886
controllerServer *nfs.ControllerServer
7987
)
8088

0 commit comments

Comments
 (0)