adding more callbacks in kubedrain helper

Kubernetes-commit: 0323fe42e23aee176ff14f3385bc15e81216c7bb
This commit is contained in:
adil ghaffar 2023-04-20 16:16:11 +03:00 committed by Kubernetes Publisher
parent 71b74708cf
commit e112354038
3 changed files with 91 additions and 7 deletions

View File

@ -31,6 +31,7 @@ import (
"k8s.io/cli-runtime/pkg/genericiooptions"
"k8s.io/cli-runtime/pkg/printers"
"k8s.io/cli-runtime/pkg/resource"
"k8s.io/klog/v2"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/drain"
"k8s.io/kubectl/pkg/scheme"
@ -156,24 +157,53 @@ func NewDrainCmdOptions(f cmdutil.Factory, ioStreams genericiooptions.IOStreams)
ChunkSize: cmdutil.DefaultChunkSize,
},
}
o.drainer.OnPodDeletedOrEvicted = o.onPodDeletedOrEvicted
o.drainer.OnPodDeletionOrEvictionFinished = o.onPodDeletionOrEvictionFinished
o.drainer.OnPodDeletionOrEvictionStarted = o.onPodDeletionOrEvictionStarted
return o
}
// onPodDeletedOrEvicted is called by drain.Helper, when the pod has been deleted or evicted
func (o *DrainCmdOptions) onPodDeletedOrEvicted(pod *corev1.Pod, usingEviction bool) {
// onPodDeletionOrEvictionFinished is called by drain.Helper, when eviction/deletetion of the pod is finished
func (o *DrainCmdOptions) onPodDeletionOrEvictionFinished(pod *corev1.Pod, usingEviction bool, err error) {
var verbStr string
if usingEviction {
verbStr = "evicted"
if err != nil {
verbStr = "eviction failed"
} else {
verbStr = "evicted"
}
} else {
verbStr = "deleted"
if err != nil {
verbStr = "deletion failed"
} else {
verbStr = "deleted"
}
}
printObj, err := o.ToPrinter(verbStr)
if err != nil {
fmt.Fprintf(o.ErrOut, "error building printer: %v\n", err)
fmt.Fprintf(o.Out, "pod %s/%s %s\n", pod.Namespace, pod.Name, verbStr)
} else {
printObj(pod, o.Out)
_ = printObj(pod, o.Out)
}
}
// onPodDeletionOrEvictionStarted is called by drain.Helper, when eviction/deletion of the pod is started
func (o *DrainCmdOptions) onPodDeletionOrEvictionStarted(pod *corev1.Pod, usingEviction bool) {
if !klog.V(2).Enabled() {
return
}
var verbStr string
if usingEviction {
verbStr = "eviction started"
} else {
verbStr = "deletion started"
}
printObj, err := o.ToPrinter(verbStr)
if err != nil {
fmt.Fprintf(o.ErrOut, "error building printer: %v\n", err)
fmt.Fprintf(o.Out, "pod %s/%s %s\n", pod.Namespace, pod.Name, verbStr)
} else {
_ = printObj(pod, o.Out)
}
}

View File

@ -85,7 +85,14 @@ type Helper struct {
DryRunStrategy cmdutil.DryRunStrategy
// OnPodDeletedOrEvicted is called when a pod is evicted/deleted; for printing progress output
// Deprecated: use OnPodDeletionOrEvictionFinished instead
OnPodDeletedOrEvicted func(pod *corev1.Pod, usingEviction bool)
// OnPodDeletionOrEvictionFinished is called when a pod is eviction/deletetion is failed; for printing progress output
OnPodDeletionOrEvictionFinished func(pod *corev1.Pod, usingEviction bool, err error)
// OnPodDeletionOrEvictionStarted is called when a pod eviction/deletion is started; for printing progress output
OnPodDeletionOrEvictionStarted func(pod *corev1.Pod, usingEviction bool)
}
type waitForDeleteParams struct {
@ -96,6 +103,7 @@ type waitForDeleteParams struct {
usingEviction bool
getPodFn func(string, string) (*corev1.Pod, error)
onDoneFn func(pod *corev1.Pod, usingEviction bool)
onFinishFn func(pod *corev1.Pod, usingEviction bool, err error)
globalTimeout time.Duration
skipWaitForDeleteTimeoutSeconds int
out io.Writer
@ -276,6 +284,9 @@ func (d *Helper) evictPods(pods []corev1.Pod, evictionGroupVersion schema.GroupV
case cmdutil.DryRunServer:
fmt.Fprintf(d.Out, "evicting pod %s/%s (server dry run)\n", pod.Namespace, pod.Name)
default:
if d.OnPodDeletionOrEvictionStarted != nil {
d.OnPodDeletionOrEvictionStarted(&pod, true)
}
fmt.Fprintf(d.Out, "evicting pod %s/%s\n", pod.Namespace, pod.Name)
}
select {
@ -334,6 +345,7 @@ func (d *Helper) evictPods(pods []corev1.Pod, evictionGroupVersion schema.GroupV
usingEviction: true,
getPodFn: getPodFn,
onDoneFn: d.OnPodDeletedOrEvicted,
onFinishFn: d.OnPodDeletionOrEvictionFinished,
globalTimeout: globalTimeout,
skipWaitForDeleteTimeoutSeconds: d.SkipWaitForDeleteTimeoutSeconds,
out: d.Out,
@ -377,6 +389,9 @@ func (d *Helper) deletePods(pods []corev1.Pod, getPodFn func(namespace, name str
if err != nil && !apierrors.IsNotFound(err) {
return err
}
if d.OnPodDeletionOrEvictionStarted != nil {
d.OnPodDeletionOrEvictionStarted(&pod, false)
}
}
ctx := d.getContext()
params := waitForDeleteParams{
@ -387,6 +402,7 @@ func (d *Helper) deletePods(pods []corev1.Pod, getPodFn func(namespace, name str
usingEviction: false,
getPodFn: getPodFn,
onDoneFn: d.OnPodDeletedOrEvicted,
onFinishFn: d.OnPodDeletionOrEvictionFinished,
globalTimeout: globalTimeout,
skipWaitForDeleteTimeoutSeconds: d.SkipWaitForDeleteTimeoutSeconds,
out: d.Out,
@ -402,11 +418,16 @@ func waitForDelete(params waitForDeleteParams) ([]corev1.Pod, error) {
for i, pod := range pods {
p, err := params.getPodFn(pod.Namespace, pod.Name)
if apierrors.IsNotFound(err) || (p != nil && p.ObjectMeta.UID != pod.ObjectMeta.UID) {
if params.onDoneFn != nil {
if params.onFinishFn != nil {
params.onFinishFn(&pod, params.usingEviction, nil)
} else if params.onDoneFn != nil {
params.onDoneFn(&pod, params.usingEviction)
}
continue
} else if err != nil {
if params.onFinishFn != nil {
params.onFinishFn(&pod, params.usingEviction, err)
}
return false, err
} else {
if shouldSkipPod(*p, params.skipWaitForDeleteTimeoutSeconds) {

View File

@ -331,6 +331,39 @@ func TestDeleteOrEvict(t *testing.T) {
h := &Helper{
Out: os.Stdout,
GracePeriodSeconds: 10,
OnPodDeletionOrEvictionStarted: func(pod *corev1.Pod, usingEviction bool) {
if tc.evictionSupported && !tc.disableEviction {
if !usingEviction {
t.Errorf("%s: OnPodDeletionOrEvictionStarted callback failed while evicting; actual\n\t%v\nexpected\n\t%v", tc.description, usingEviction, !usingEviction)
}
} else if tc.evictionSupported && tc.disableEviction {
if usingEviction {
t.Errorf("%s: OnPodDeletionOrEvictionStarted callback failed while deleting; actual\n\t%v\nexpected\n\t%v", tc.description, !usingEviction, usingEviction)
}
}
},
OnPodDeletedOrEvicted: func(pod *corev1.Pod, usingEviction bool) {
if tc.evictionSupported && !tc.disableEviction {
if !usingEviction {
t.Errorf("%s: OnPodDeletedOrEvicted callback failed while evicting; actual\n\t%v\nexpected\n\t%v", tc.description, usingEviction, !usingEviction)
}
} else if tc.evictionSupported && tc.disableEviction {
if usingEviction {
t.Errorf("%s: OnPodDeletedOrEvicted callback failed while deleting; actual\n\t%v\nexpected\n\t%v", tc.description, !usingEviction, usingEviction)
}
}
},
OnPodDeletionOrEvictionFinished: func(pod *corev1.Pod, usingEviction bool, err error) {
if tc.evictionSupported && !tc.disableEviction {
if !usingEviction {
t.Errorf("%s: OnPodDeletionOrEvictionFinished callback failed while evicting; actual\n\t%v\nexpected\n\t%v", tc.description, usingEviction, !usingEviction)
}
} else if tc.evictionSupported && tc.disableEviction {
if usingEviction {
t.Errorf("%s: OnPodDeletionOrEvictionFinished callback failed while deleting; actual\n\t%v\nexpected\n\t%v", tc.description, !usingEviction, usingEviction)
}
}
},
}
// Create 4 pods, and try to remove the first 2