@@ -254,6 +254,7 @@ func (d *Helper) evictPods(pods []corev1.Pod, policyGroupVersion string, getPodF
254
254
defer cancel ()
255
255
for _ , pod := range pods {
256
256
go func (pod corev1.Pod , returnCh chan error ) {
257
+ refreshPod := false
257
258
for {
258
259
switch d .DryRunStrategy {
259
260
case cmdutil .DryRunServer :
@@ -268,17 +269,40 @@ func (d *Helper) evictPods(pods []corev1.Pod, policyGroupVersion string, getPodF
268
269
return
269
270
default :
270
271
}
271
- err := d .EvictPod (pod , policyGroupVersion )
272
+
273
+ // Create a temporary pod so we don't mutate the pod in the loop.
274
+ activePod := pod
275
+ if refreshPod {
276
+ freshPod , err := getPodFn (pod .Namespace , pod .Name )
277
+ // We ignore errors and let eviction sort it out with
278
+ // the original pod.
279
+ if err == nil {
280
+ activePod = * freshPod
281
+ }
282
+ refreshPod = false
283
+ }
284
+
285
+ err := d .EvictPod (activePod , policyGroupVersion )
272
286
if err == nil {
273
287
break
274
288
} else if apierrors .IsNotFound (err ) {
275
289
returnCh <- nil
276
290
return
277
291
} else if apierrors .IsTooManyRequests (err ) {
278
- fmt .Fprintf (d .ErrOut , "error when evicting pods/%q -n %q (will retry after 5s): %v\n " , pod .Name , pod .Namespace , err )
292
+ fmt .Fprintf (d .ErrOut , "error when evicting pods/%q -n %q (will retry after 5s): %v\n " , activePod .Name , activePod .Namespace , err )
293
+ time .Sleep (5 * time .Second )
294
+ } else if ! activePod .ObjectMeta .DeletionTimestamp .IsZero () && apierrors .IsForbidden (err ) && apierrors .HasStatusCause (err , corev1 .NamespaceTerminatingCause ) {
295
+ // an eviction request in a deleting namespace will throw a forbidden error,
296
+ // if the pod is already marked deleted, we can ignore this error, an eviction
297
+ // request will never succeed, but we will waitForDelete for this pod.
298
+ break
299
+ } else if apierrors .IsForbidden (err ) && apierrors .HasStatusCause (err , corev1 .NamespaceTerminatingCause ) {
300
+ // an eviction request in a deleting namespace will throw a forbidden error,
301
+ // if the pod is not marked deleted, we retry until it is.
302
+ fmt .Fprintf (d .ErrOut , "error when evicting pod %q (will retry after 5s): %v\n " , activePod .Name , err )
279
303
time .Sleep (5 * time .Second )
280
304
} else {
281
- returnCh <- fmt .Errorf ("error when evicting pods/%q -n %q: %v" , pod .Name , pod .Namespace , err )
305
+ returnCh <- fmt .Errorf ("error when evicting pods/%q -n %q: %v" , activePod .Name , activePod .Namespace , err )
282
306
return
283
307
}
284
308
}
0 commit comments