From 60285578cf90ee7baaf591bfaf7908634caca1f7 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Thu, 6 Jan 2022 07:27:45 +0000 Subject: [PATCH] feat: add inline volume support fix yaml refine tests fix example fix test --- .github/workflows/static.yaml | 2 +- charts/README.md | 1 + charts/latest/csi-driver-nfs-v3.1.0.tgz | Bin 3578 -> 3602 bytes .../templates/csi-nfs-driverinfo.yaml | 3 + charts/latest/csi-driver-nfs/values.yaml | 1 + deploy/csi-nfs-driverinfo.yaml | 1 + deploy/example/nginx-pod-inline-volume.yaml | 25 +++++++++ hack/verify-examples.sh | 2 +- test/e2e/dynamic_provisioning_test.go | 26 +++++++++ test/e2e/e2e_suite_test.go | 6 +- .../dynamically_provisioned_inline_volume.go | 53 ++++++++++++++++++ test/e2e/testsuites/specs.go | 9 +++ test/e2e/testsuites/testsuites.go | 24 ++++++++ 13 files changed, 149 insertions(+), 4 deletions(-) create mode 100644 deploy/example/nginx-pod-inline-volume.yaml create mode 100644 test/e2e/testsuites/dynamically_provisioned_inline_volume.go diff --git a/.github/workflows/static.yaml b/.github/workflows/static.yaml index 1d887fb2..9efaaa44 100644 --- a/.github/workflows/static.yaml +++ b/.github/workflows/static.yaml @@ -12,7 +12,7 @@ jobs: - name: Run linter uses: golangci/golangci-lint-action@v2 with: - version: v1.29 + version: v1.31 args: -E=gofmt,deadcode,unused,varcheck,ineffassign,golint,misspell --timeout=30m0s verify-helm: name: Verify Helm diff --git a/charts/README.md b/charts/README.md index 216b82f9..3edef385 100644 --- a/charts/README.md +++ b/charts/README.md @@ -40,6 +40,7 @@ The following table lists the configurable parameters of the latest NFS CSI Driv | `driver.name` | alternative driver name | `nfs.csi.k8s.io` | | `driver.mountPermissions` | mounted folder permissions name | `0777` | `feature.enableFSGroupPolicy` | enable `fsGroupPolicy` on a k8s 1.20+ cluster | `false` | +| `feature.enableInlineVolume` | enable inline volume | `true` | | `image.nfs.repository` | csi-driver-nfs image | `mcr.microsoft.com/k8s/csi/nfs-csi` | | `image.nfs.tag` | csi-driver-nfs image tag | `latest` | | `image.nfs.pullPolicy` | csi-driver-nfs image pull policy | `IfNotPresent` | diff --git a/charts/latest/csi-driver-nfs-v3.1.0.tgz b/charts/latest/csi-driver-nfs-v3.1.0.tgz index f2247d2321a50b2452ad573b430bfa2daba3384b..30095df0908287e47e153a009e9ac2bca949413a 100644 GIT binary patch delta 3575 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 delta 3551 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 /mnt/nfs/outfile; sleep 1; done + volumeMounts: + - name: persistent-storage + mountPath: "/mnt/nfs" + volumes: + - name: persistent-storage + csi: + driver: nfs.csi.k8s.io + volumeAttributes: + server: nfs-server.default.svc.cluster.local # required + share: / # required diff --git a/hack/verify-examples.sh b/hack/verify-examples.sh index aac53e58..3ff485a0 100755 --- a/hack/verify-examples.sh +++ b/hack/verify-examples.sh @@ -20,7 +20,7 @@ rollout_and_wait() { trap "echo \"Failed to apply config \\\"$1\\\"\" >&2" err APPNAME=$(kubectl apply -f $1 | grep -E "^(:?daemonset|deployment|statefulset|pod)" | awk '{printf $1}') - if [[ -n $(expr "${APPNAME}" : "\(daemonset\|deployment\|statefulset\)" || true) ]]; then + if [[ -n $(expr "${APPNAME}" : "\(daemonset\|deployment\|statefulset\|pod\)" || true) ]]; then kubectl rollout status $APPNAME --watch --timeout=5m else kubectl wait "${APPNAME}" --for condition=ready --timeout=5m diff --git a/test/e2e/dynamic_provisioning_test.go b/test/e2e/dynamic_provisioning_test.go index 700ccebd..3dd157e7 100644 --- a/test/e2e/dynamic_provisioning_test.go +++ b/test/e2e/dynamic_provisioning_test.go @@ -257,6 +257,32 @@ var _ = ginkgo.Describe("Dynamic Provisioning", func() { } test.Run(cs, ns) }) + + ginkgo.It("should create a CSI inline volume [nfs.csi.k8s.io]", func() { + pods := []testsuites.PodDetails{ + { + Cmd: convertToPowershellCommandIfNecessary("echo 'hello world' > /mnt/test-1/data && grep 'hello world' /mnt/test-1/data"), + Volumes: []testsuites.VolumeDetails{ + { + ClaimSize: "10Gi", + VolumeMount: testsuites.VolumeMountDetails{ + NameGenerate: "test-volume-", + MountPathGenerate: "/mnt/test-", + }, + }, + }, + }, + } + + test := testsuites.DynamicallyProvisionedInlineVolumeTest{ + CSIDriver: testDriver, + Pods: pods, + Server: nfsServerAddress, + Share: nfsShare, + ReadOnly: false, + } + test.Run(cs, ns) + }) }) func restClient(group string, version string) (restclientset.Interface, error) { diff --git a/test/e2e/e2e_suite_test.go b/test/e2e/e2e_suite_test.go index be5e9c28..2660eb84 100644 --- a/test/e2e/e2e_suite_test.go +++ b/test/e2e/e2e_suite_test.go @@ -37,6 +37,8 @@ import ( const ( kubeconfigEnvVar = "KUBECONFIG" testWindowsEnvVar = "TEST_WINDOWS" + nfsServerAddress = "nfs-server.default.svc.cluster.local" + nfsShare = "/" ) var ( @@ -44,8 +46,8 @@ var ( nfsDriver *nfs.Driver isWindowsCluster = os.Getenv(testWindowsEnvVar) != "" defaultStorageClassParameters = map[string]string{ - "server": "nfs-server.default.svc.cluster.local", - "share": "/", + "server": nfsServerAddress, + "share": nfsShare, "csi.storage.k8s.io/provisioner-secret-name": "mount-options", "csi.storage.k8s.io/provisioner-secret-namespace": "default", } diff --git a/test/e2e/testsuites/dynamically_provisioned_inline_volume.go b/test/e2e/testsuites/dynamically_provisioned_inline_volume.go new file mode 100644 index 00000000..eadacd13 --- /dev/null +++ b/test/e2e/testsuites/dynamically_provisioned_inline_volume.go @@ -0,0 +1,53 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testsuites + +import ( + "github.com/kubernetes-csi/csi-driver-nfs/test/e2e/driver" + "github.com/onsi/ginkgo" + v1 "k8s.io/api/core/v1" + clientset "k8s.io/client-go/kubernetes" +) + +// DynamicallyProvisionedInlineVolumeTest will provision required server, share +// Waiting for the PV provisioner to create an inline volume +// Testing if the Pod(s) Cmd is run with a 0 exit code +type DynamicallyProvisionedInlineVolumeTest struct { + CSIDriver driver.DynamicPVTestDriver + Pods []PodDetails + Server string + Share string + ReadOnly bool +} + +func (t *DynamicallyProvisionedInlineVolumeTest) Run(client clientset.Interface, namespace *v1.Namespace) { + for _, pod := range t.Pods { + var tpod *TestPod + var cleanup []func() + tpod, cleanup = pod.SetupWithCSIInlineVolumes(client, namespace, t.CSIDriver, t.Server, t.Share, t.ReadOnly) + // defer must be called here for resources not get removed before using them + for i := range cleanup { + defer cleanup[i]() + } + + ginkgo.By("deploying the pod") + tpod.Create() + defer tpod.Cleanup() + ginkgo.By("checking that the pods command exits with no error") + tpod.WaitForSuccess() + } +} diff --git a/test/e2e/testsuites/specs.go b/test/e2e/testsuites/specs.go index 3c52a639..025fed5f 100644 --- a/test/e2e/testsuites/specs.go +++ b/test/e2e/testsuites/specs.go @@ -123,6 +123,15 @@ func (pod *PodDetails) SetupWithDynamicVolumes(client clientset.Interface, names return tpod, cleanupFuncs } +func (pod *PodDetails) SetupWithCSIInlineVolumes(client clientset.Interface, namespace *v1.Namespace, csiDriver driver.DynamicPVTestDriver, server, share string, readOnly bool) (*TestPod, []func()) { + tpod := NewTestPod(client, namespace, pod.Cmd) + cleanupFuncs := make([]func(), 0) + for n, v := range pod.Volumes { + tpod.SetupCSIInlineVolume(fmt.Sprintf("%s%d", v.VolumeMount.NameGenerate, n+1), fmt.Sprintf("%s%d", v.VolumeMount.MountPathGenerate, n+1), server, share, readOnly) + } + return tpod, cleanupFuncs +} + func (pod *PodDetails) SetupDeployment(client clientset.Interface, namespace *v1.Namespace, csiDriver driver.DynamicPVTestDriver, storageClassParameters map[string]string) (*TestDeployment, []func()) { cleanupFuncs := make([]func(), 0) volume := pod.Volumes[0] diff --git a/test/e2e/testsuites/testsuites.go b/test/e2e/testsuites/testsuites.go index c9812274..a7d8f730 100644 --- a/test/e2e/testsuites/testsuites.go +++ b/test/e2e/testsuites/testsuites.go @@ -595,3 +595,27 @@ func (t *TestPod) SetupVolumeMountWithSubpath(pvc *v1.PersistentVolumeClaim, nam t.pod.Spec.Volumes = append(t.pod.Spec.Volumes, volume) } + +func (t *TestPod) SetupCSIInlineVolume(name, mountPath, server, share string, readOnly bool) { + volumeMount := v1.VolumeMount{ + Name: name, + MountPath: mountPath, + ReadOnly: readOnly, + } + t.pod.Spec.Containers[0].VolumeMounts = append(t.pod.Spec.Containers[0].VolumeMounts, volumeMount) + + volume := v1.Volume{ + Name: name, + VolumeSource: v1.VolumeSource{ + CSI: &v1.CSIVolumeSource{ + Driver: nfs.DefaultDriverName, + VolumeAttributes: map[string]string{ + "server": server, + "share": share, + }, + ReadOnly: &readOnly, + }, + }, + } + t.pod.Spec.Volumes = append(t.pod.Spec.Volumes, volume) +}