1
2
3
4
19
20 package storage
21
22 import (
23 "context"
24
25 "github.com/onsi/ginkgo/v2"
26
27 v1 "k8s.io/api/core/v1"
28 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29 "k8s.io/apimachinery/pkg/labels"
30 "k8s.io/apimachinery/pkg/types"
31 utilerrors "k8s.io/apimachinery/pkg/util/errors"
32 clientset "k8s.io/client-go/kubernetes"
33 "k8s.io/kubernetes/test/e2e/feature"
34 "k8s.io/kubernetes/test/e2e/framework"
35 e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
36 "k8s.io/kubernetes/test/e2e/framework/providers/gce"
37 e2epv "k8s.io/kubernetes/test/e2e/framework/pv"
38 e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper"
39 "k8s.io/kubernetes/test/e2e/storage/utils"
40 admissionapi "k8s.io/pod-security-admission/api"
41 )
42
43
44 func verifyGCEDiskAttached(diskName string, nodeName types.NodeName) bool {
45 gceCloud, err := gce.GetGCECloud()
46 framework.ExpectNoError(err)
47 isAttached, err := gceCloud.DiskIsAttached(diskName, nodeName)
48 framework.ExpectNoError(err)
49 return isAttached
50 }
51
52
53 func initializeGCETestSpec(ctx context.Context, c clientset.Interface, t *framework.TimeoutContext, ns string, pvConfig e2epv.PersistentVolumeConfig, pvcConfig e2epv.PersistentVolumeClaimConfig, isPrebound bool) (*v1.Pod, *v1.PersistentVolume, *v1.PersistentVolumeClaim) {
54 ginkgo.By("Creating the PV and PVC")
55 pv, pvc, err := e2epv.CreatePVPVC(ctx, c, t, pvConfig, pvcConfig, ns, isPrebound)
56 framework.ExpectNoError(err)
57 framework.ExpectNoError(e2epv.WaitOnPVandPVC(ctx, c, t, ns, pv, pvc))
58
59 ginkgo.By("Creating the Client Pod")
60 clientPod, err := e2epod.CreateClientPod(ctx, c, ns, pvc)
61 framework.ExpectNoError(err)
62 return clientPod, pv, pvc
63 }
64
65
66 var _ = utils.SIGDescribe("PersistentVolumes GCEPD", feature.StorageProvider, func() {
67 var (
68 c clientset.Interface
69 diskName string
70 ns string
71 err error
72 pv *v1.PersistentVolume
73 pvc *v1.PersistentVolumeClaim
74 clientPod *v1.Pod
75 pvConfig e2epv.PersistentVolumeConfig
76 pvcConfig e2epv.PersistentVolumeClaimConfig
77 volLabel labels.Set
78 selector *metav1.LabelSelector
79 node types.NodeName
80 )
81
82 f := framework.NewDefaultFramework("pv")
83 f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged
84 ginkgo.BeforeEach(func(ctx context.Context) {
85 c = f.ClientSet
86 ns = f.Namespace.Name
87
88
89 volLabel = labels.Set{e2epv.VolumeSelectorKey: ns}
90 selector = metav1.SetAsLabelSelector(volLabel)
91
92 e2eskipper.SkipUnlessProviderIs("gce", "gke")
93 ginkgo.By("Initializing Test Spec")
94 diskName, err = e2epv.CreatePDWithRetry(ctx)
95 framework.ExpectNoError(err)
96
97 pvConfig = e2epv.PersistentVolumeConfig{
98 NamePrefix: "gce-",
99 Labels: volLabel,
100 PVSource: v1.PersistentVolumeSource{
101 GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{
102 PDName: diskName,
103 FSType: e2epv.GetDefaultFSType(),
104 ReadOnly: false,
105 },
106 },
107 Prebind: nil,
108 }
109 emptyStorageClass := ""
110 pvcConfig = e2epv.PersistentVolumeClaimConfig{
111 Selector: selector,
112 StorageClassName: &emptyStorageClass,
113 }
114 clientPod, pv, pvc = initializeGCETestSpec(ctx, c, f.Timeouts, ns, pvConfig, pvcConfig, false)
115 node = types.NodeName(clientPod.Spec.NodeName)
116 })
117
118 ginkgo.AfterEach(func(ctx context.Context) {
119 framework.Logf("AfterEach: Cleaning up test resources")
120 if c != nil {
121 framework.ExpectNoError(e2epod.DeletePodWithWait(ctx, c, clientPod))
122 if errs := e2epv.PVPVCCleanup(ctx, c, ns, pv, pvc); len(errs) > 0 {
123 framework.Failf("AfterEach: Failed to delete PVC and/or PV. Errors: %v", utilerrors.NewAggregate(errs))
124 }
125 clientPod, pv, pvc, node = nil, nil, nil, ""
126 if diskName != "" {
127 framework.ExpectNoError(e2epv.DeletePDWithRetry(ctx, diskName))
128 }
129 }
130 })
131
132
133
134 ginkgo.It("should test that deleting a PVC before the pod does not cause pod deletion to fail on PD detach", func(ctx context.Context) {
135
136 ginkgo.By("Deleting the Claim")
137 framework.ExpectNoError(e2epv.DeletePersistentVolumeClaim(ctx, c, pvc.Name, ns), "Unable to delete PVC ", pvc.Name)
138 if !verifyGCEDiskAttached(diskName, node) {
139 framework.Failf("Disk %s is not attached to node %s", diskName, node)
140 }
141
142 ginkgo.By("Deleting the Pod")
143 framework.ExpectNoError(e2epod.DeletePodWithWait(ctx, c, clientPod), "Failed to delete pod ", clientPod.Name)
144
145 ginkgo.By("Verifying Persistent Disk detach")
146 framework.ExpectNoError(waitForPDDetach(diskName, node), "PD ", diskName, " did not detach")
147 })
148
149
150
151 ginkgo.It("should test that deleting the PV before the pod does not cause pod deletion to fail on PD detach", func(ctx context.Context) {
152
153 ginkgo.By("Deleting the Persistent Volume")
154 framework.ExpectNoError(e2epv.DeletePersistentVolume(ctx, c, pv.Name), "Failed to delete PV ", pv.Name)
155 if !verifyGCEDiskAttached(diskName, node) {
156 framework.Failf("Disk %s is not attached to node %s", diskName, node)
157 }
158
159 ginkgo.By("Deleting the client pod")
160 framework.ExpectNoError(e2epod.DeletePodWithWait(ctx, c, clientPod), "Failed to delete pod ", clientPod.Name)
161
162 ginkgo.By("Verifying Persistent Disk detaches")
163 framework.ExpectNoError(waitForPDDetach(diskName, node), "PD ", diskName, " did not detach")
164 })
165
166
167 ginkgo.It("should test that deleting the Namespace of a PVC and Pod causes the successful detach of Persistent Disk", func(ctx context.Context) {
168
169 ginkgo.By("Deleting the Namespace")
170 err := c.CoreV1().Namespaces().Delete(ctx, ns, metav1.DeleteOptions{})
171 framework.ExpectNoError(err)
172
173
174 e2epod.DeletePodOrFail(ctx, c, clientPod.Namespace, clientPod.Name)
175 framework.ExpectNoError(e2epv.DeletePersistentVolumeClaim(ctx, c, pvc.Name, ns), "Unable to delete PVC ", pvc.Name)
176
177 ginkgo.By("Verifying Persistent Disk detaches")
178 framework.ExpectNoError(waitForPDDetach(diskName, node), "PD ", diskName, " did not detach")
179 })
180 })
181
View as plain text