@@ -24,12 +24,15 @@ import (
24
24
25
25
"k8s.io/api/core/v1"
26
26
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27
+ "k8s.io/apimachinery/pkg/util/uuid"
27
28
"k8s.io/apimachinery/pkg/util/wait"
28
29
clientset "k8s.io/client-go/kubernetes"
30
+ "k8s.io/kubernetes/pkg/master/ports"
29
31
"k8s.io/kubernetes/test/e2e/framework"
30
32
imageutils "k8s.io/kubernetes/test/utils/image"
31
33
32
34
. "github.com/onsi/ginkgo"
35
+ . "github.com/onsi/gomega"
33
36
)
34
37
35
38
// partially cloned from webserver.go
@@ -160,6 +163,10 @@ func testPreStop(c clientset.Interface, ns string) {
160
163
161
164
var _ = SIGDescribe ("PreStop" , func () {
162
165
f := framework .NewDefaultFramework ("prestop" )
166
+ var podClient * framework.PodClient
167
+ BeforeEach (func () {
168
+ podClient = f .PodClient ()
169
+ })
163
170
164
171
/*
165
172
Release : v1.9
@@ -169,4 +176,70 @@ var _ = SIGDescribe("PreStop", func() {
169
176
framework .ConformanceIt ("should call prestop when killing a pod " , func () {
170
177
testPreStop (f .ClientSet , f .Namespace .Name )
171
178
})
179
+
180
+ It ("graceful pod terminated should wait until preStop hook completes the process" , func () {
181
+ gracefulTerminationPeriodSeconds := int64 (30 )
182
+ By ("creating the pod" )
183
+ name := "pod-prestop-hook-" + string (uuid .NewUUID ())
184
+ pod := getPodWithpreStopLifeCycle (name )
185
+
186
+ By ("submitting the pod to kubernetes" )
187
+ podClient .Create (pod )
188
+
189
+ By ("waiting for pod running" )
190
+ framework .ExpectNoError (f .WaitForPodRunning (pod .Name ))
191
+
192
+ var err error
193
+ pod , err = podClient .Get (pod .Name , metav1.GetOptions {})
194
+ Expect (err ).NotTo (HaveOccurred (), "failed to GET scheduled pod" )
195
+
196
+ By ("deleting the pod gracefully" )
197
+ err = podClient .Delete (pod .Name , metav1 .NewDeleteOptions (gracefulTerminationPeriodSeconds ))
198
+ Expect (err ).NotTo (HaveOccurred (), "failed to delete pod" )
199
+
200
+ //wait up to graceful termination period seconds
201
+ time .Sleep (30 * time .Second )
202
+
203
+ By ("verifying the pod running state after graceful termination" )
204
+ result := & v1.PodList {}
205
+ err = wait .Poll (time .Second * 5 , time .Second * 60 , func () (bool , error ) {
206
+ client , err := framework .NodeProxyRequest (f .ClientSet , pod .Spec .NodeName , "pods" , ports .KubeletPort )
207
+ Expect (err ).NotTo (HaveOccurred (), "failed to get the pods of the node" )
208
+ err = client .Into (result )
209
+ Expect (err ).NotTo (HaveOccurred (), "failed to parse the pods of the node" )
210
+
211
+ for _ , kubeletPod := range result .Items {
212
+ if pod .Name != kubeletPod .Name {
213
+ continue
214
+ } else if kubeletPod .Status .Phase == v1 .PodRunning {
215
+ framework .Logf ("pod is running" )
216
+ return true , err
217
+ }
218
+ }
219
+ return false , err
220
+ })
221
+ })
172
222
})
223
+
224
+ func getPodWithpreStopLifeCycle (name string ) * v1.Pod {
225
+ return & v1.Pod {
226
+ ObjectMeta : metav1.ObjectMeta {
227
+ Name : name ,
228
+ },
229
+ Spec : v1.PodSpec {
230
+ Containers : []v1.Container {
231
+ {
232
+ Name : "nginx" ,
233
+ Image : imageutils .GetE2EImage (imageutils .Nginx ),
234
+ Lifecycle : & v1.Lifecycle {
235
+ PreStop : & v1.Handler {
236
+ Exec : & v1.ExecAction {
237
+ Command : []string {"sh" , "-c" , "while true; do echo preStop; sleep 1; done" },
238
+ },
239
+ },
240
+ },
241
+ },
242
+ },
243
+ },
244
+ }
245
+ }
0 commit comments