fix: kubectl drain --disable-eviction --dry-run=server hanging indefinitely

This commit is contained in:
kita456 2026-03-08 12:05:32 +09:00
parent dfbe79674a
commit bc5302ec93
2 changed files with 70 additions and 0 deletions

View file

@ -394,6 +394,11 @@ func (d *Helper) deletePods(pods []corev1.Pod, getPodFn func(namespace, name str
d.OnPodDeletionOrEvictionStarted(&pod, false)
}
}
if d.DryRunStrategy == cmdutil.DryRunServer {
return nil
}
ctx := d.getContext()
params := waitForDeleteParams{
ctx: ctx,

View file

@ -17,6 +17,7 @@ limitations under the License.
package drain
import (
"bytes"
"context"
"errors"
"fmt"
@ -38,6 +39,7 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes/fake"
ktest "k8s.io/client-go/testing"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
)
func TestDeletePods(t *testing.T) {
@ -461,6 +463,69 @@ func TestDeleteOrEvict(t *testing.T) {
}
}
func TestDeleteOrEvictWithDryRunServer(t *testing.T) {
testCases := []struct {
description string
disableEviction bool
}{
{
description: "Eviction enabled with server dry-run",
disableEviction: false,
},
{
description: "Eviction disabled with server dry-run",
disableEviction: true,
},
}
for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) {
var buf bytes.Buffer
h := &Helper{
Out: &buf,
GracePeriodSeconds: 10,
DisableEviction: tc.disableEviction,
DryRunStrategy: cmdutil.DryRunServer,
}
var allPods []runtime.Object
var podsToDelete []corev1.Pod
for i := 1; i <= 4; i++ {
pod := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("mypod-%d", i),
Namespace: "default",
},
}
allPods = append(allPods, &pod)
if i <= 2 {
podsToDelete = append(podsToDelete, pod)
}
}
k := fake.NewSimpleClientset(allPods...)
// fake clientset will actually delete objects from the in-memory store.
// This reactor intercepts delete requests with DryRun set and returns success without
// removing the object, simulating real API server dry-run behavior.
k.PrependReactor("delete", "pods", func(actions ktest.Action) (bool, runtime.Object, error) {
deleteAction := actions.(ktest.DeleteAction)
if len(deleteAction.GetDeleteOptions().DryRun) > 0 {
return true, nil, nil
}
return false, nil, nil
})
addEvictionSupport(t, k, "v1")
h.Client = k
if err := h.DeleteOrEvictPods(podsToDelete); err != nil {
t.Fatalf("error from DeleteOrEvictPods: %v", err)
}
})
}
}
func mockFilterSkip(_ corev1.Pod) PodDeleteStatus {
return MakePodDeleteStatusSkip()
}