Skip to content

Commit 9ef05a6

Browse files
authored
CO-3733 Support timeout for EvictPod (#191)
1 parent a0dd844 commit 9ef05a6

File tree

3 files changed

+47
-7
lines changed

3 files changed

+47
-7
lines changed

internal/actions/evict_pod_handler.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,17 @@ func (h *EvictPodHandler) Handle(ctx context.Context, action *castai.ClusterActi
4949
"namespace": req.Namespace,
5050
"pod": req.PodName,
5151
})
52-
return h.handle(ctx, log, req)
52+
return h.handle(ctx, log, action, req)
5353
}
5454

55-
func (h *EvictPodHandler) handle(ctx context.Context, log logrus.FieldLogger, req *castai.ActionEvictPod) error {
56-
log.Infof("evicting pod")
55+
func (h *EvictPodHandler) handle(ctx context.Context, log logrus.FieldLogger, action *castai.ClusterAction, req *castai.ActionEvictPod) error {
56+
deadline, deadlineStr := h.computeDeadline(action, req)
57+
if !deadline.IsZero() {
58+
var cancel context.CancelFunc
59+
ctx, cancel = context.WithDeadline(ctx, deadline)
60+
defer cancel()
61+
}
62+
log.WithField("deadline", deadlineStr).Infof("evicting pod")
5763
err := h.evictPod(ctx, log, req.Namespace, req.PodName)
5864
if err != nil {
5965
return fmt.Errorf("evict pod: %w", err)
@@ -160,3 +166,12 @@ func (h *EvictPodHandler) isPodDeleted(ctx context.Context, namespace, name stri
160166
}
161167
return false, p.Status.Phase, nil
162168
}
169+
170+
func (h *EvictPodHandler) computeDeadline(action *castai.ClusterAction, req *castai.ActionEvictPod) (time.Time, string) {
171+
if req.TimeoutSeconds > 0 {
172+
deadline := action.CreatedAt.Add(time.Duration(req.TimeoutSeconds) * time.Second).UTC()
173+
deadlineStr := deadline.Format(time.RFC3339)
174+
return deadline, deadlineStr
175+
}
176+
return time.Time{}, "-"
177+
}

internal/actions/evict_pod_handler_test.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,39 @@ func TestEvictPodHandler(t *testing.T) {
4242
)
4343

4444
action := newEvictPodAction(&castai.ActionEvictPod{
45-
Namespace: pod.Namespace,
46-
PodName: pod.Name,
45+
Namespace: pod.Namespace,
46+
PodName: pod.Name,
47+
TimeoutSeconds: 120,
4748
})
4849
err := h.Handle(ctx, action)
4950
require.NoError(t, err)
5051

5152
requirePodNotExists(t, ctx, clientset, pod.Namespace, pod.Name)
5253
})
5354

55+
t.Run("stops trying after the timeout", func(t *testing.T) {
56+
t.Parallel()
57+
58+
clientset, pod := setupFakeClientWithPodEviction()
59+
60+
reactionErr := &apierrors.StatusError{ErrStatus: metav1.Status{Reason: metav1.StatusReasonTooManyRequests}}
61+
reaction := failingPodEvictionReaction(reactionErr, 1000, nil)
62+
prependPodEvictionReaction(clientset, reaction)
63+
64+
h := NewEvictPodHandler(
65+
log,
66+
clientset,
67+
)
68+
69+
action := newEvictPodAction(&castai.ActionEvictPod{
70+
Namespace: pod.Namespace,
71+
PodName: pod.Name,
72+
TimeoutSeconds: 1,
73+
})
74+
err := h.Handle(ctx, action)
75+
require.ErrorIs(t, err, context.DeadlineExceeded)
76+
})
77+
5478
t.Run("retries on TooManyRequests status", func(t *testing.T) {
5579
t.Parallel()
5680

internal/castai/types.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,9 @@ type ActionDrainNode struct {
160160
}
161161

162162
type ActionEvictPod struct {
163-
Namespace string `json:"namespace"`
164-
PodName string `json:"podName"`
163+
Namespace string `json:"namespace"`
164+
PodName string `json:"podName"`
165+
TimeoutSeconds int `json:"timeoutSeconds"`
165166
}
166167

167168
type ActionPatchNode struct {

0 commit comments

Comments
 (0)