Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 89def23

Browse files
juanvallejodeads2k
authored andcommittedJan 5, 2018
UPSTREAM: 56864: pick pod-selector changes from kubernetes#56864
:100644 100644 910654f6f6... 37f3ef1175... M pkg/kubectl/cmd/drain.go
1 parent d699e92 commit 89def23

File tree

1 file changed

+30
-51
lines changed

1 file changed

+30
-51
lines changed
 

‎pkg/kubectl/cmd/drain.go

+30-51
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
"k8s.io/apimachinery/pkg/api/meta"
3434
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3535
"k8s.io/apimachinery/pkg/fields"
36+
"k8s.io/apimachinery/pkg/labels"
3637
"k8s.io/apimachinery/pkg/runtime"
3738
"k8s.io/apimachinery/pkg/types"
3839
"k8s.io/apimachinery/pkg/util/json"
@@ -61,6 +62,7 @@ type DrainOptions struct {
6162
backOff clockwork.Clock
6263
DeleteLocalData bool
6364
Selector string
65+
PodSelector string
6466
mapper meta.RESTMapper
6567
nodeInfos []*resource.Info
6668
Out io.Writer
@@ -197,6 +199,8 @@ func NewCmdDrain(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
197199
cmd.Flags().IntVar(&options.GracePeriodSeconds, "grace-period", -1, "Period of time in seconds given to each pod to terminate gracefully. If negative, the default value specified in the pod will be used.")
198200
cmd.Flags().DurationVar(&options.Timeout, "timeout", 0, "The length of time to wait before giving up, zero means infinite")
199201
cmd.Flags().StringVarP(&options.Selector, "selector", "l", options.Selector, "Selector (label query) to filter on")
202+
cmd.Flags().StringVarP(&options.PodSelector, "pod-selector", "", options.PodSelector, "Label selector to filter pods on the node")
203+
200204
cmdutil.AddDryRunFlag(cmd)
201205
return cmd
202206
}
@@ -223,6 +227,12 @@ func (o *DrainOptions) SetupDrain(cmd *cobra.Command, args []string) error {
223227
return err
224228
}
225229

230+
if len(o.PodSelector) > 0 {
231+
if _, err := labels.Parse(o.PodSelector); err != nil {
232+
return errors.New("--pod-selector=<pod_selector> must be a valid label selector")
233+
}
234+
}
235+
226236
o.restClient, err = o.Factory.RESTClient()
227237
if err != nil {
228238
return err
@@ -328,38 +338,8 @@ func (o *DrainOptions) deleteOrEvictPodsSimple(nodeInfo *resource.Info) error {
328338
return err
329339
}
330340

331-
func (o *DrainOptions) getController(namespace string, controllerRef *metav1.OwnerReference) (interface{}, error) {
332-
switch controllerRef.Kind {
333-
case "ReplicationController":
334-
return o.client.Core().ReplicationControllers(namespace).Get(controllerRef.Name, metav1.GetOptions{})
335-
case "DaemonSet":
336-
return o.client.Extensions().DaemonSets(namespace).Get(controllerRef.Name, metav1.GetOptions{})
337-
case "Job":
338-
return o.client.Batch().Jobs(namespace).Get(controllerRef.Name, metav1.GetOptions{})
339-
case "ReplicaSet":
340-
return o.client.Extensions().ReplicaSets(namespace).Get(controllerRef.Name, metav1.GetOptions{})
341-
case "StatefulSet":
342-
return o.client.AppsV1beta1().StatefulSets(namespace).Get(controllerRef.Name, metav1.GetOptions{})
343-
}
344-
return nil, fmt.Errorf("Unknown controller kind %q", controllerRef.Kind)
345-
}
346-
347-
func (o *DrainOptions) getPodController(pod corev1.Pod) (*metav1.OwnerReference, error) {
348-
controllerRef := metav1.GetControllerOf(&pod)
349-
if controllerRef == nil {
350-
return nil, nil
351-
}
352-
353-
// We assume the only reason for an error is because the controller is
354-
// gone/missing, not for any other cause.
355-
// TODO(mml): something more sophisticated than this
356-
// TODO(juntee): determine if it's safe to remove getController(),
357-
// so that drain can work for controller types that we don't know about
358-
_, err := o.getController(pod.Namespace, controllerRef)
359-
if err != nil {
360-
return nil, err
361-
}
362-
return controllerRef, nil
341+
func (o *DrainOptions) getPodController(pod corev1.Pod) *metav1.OwnerReference {
342+
return metav1.GetControllerOf(&pod)
363343
}
364344

365345
func (o *DrainOptions) unreplicatedFilter(pod corev1.Pod) (bool, *warning, *fatal) {
@@ -368,21 +348,15 @@ func (o *DrainOptions) unreplicatedFilter(pod corev1.Pod) (bool, *warning, *fata
368348
return true, nil, nil
369349
}
370350

371-
controllerRef, err := o.getPodController(pod)
372-
if err != nil {
373-
// if we're forcing, remove orphaned pods with a warning
374-
if apierrors.IsNotFound(err) && o.Force {
375-
return true, &warning{err.Error()}, nil
376-
}
377-
return false, nil, &fatal{err.Error()}
378-
}
351+
controllerRef := o.getPodController(pod)
379352
if controllerRef != nil {
380353
return true, nil, nil
381354
}
382-
if !o.Force {
383-
return false, nil, &fatal{kUnmanagedFatal}
355+
if o.Force {
356+
return true, &warning{kUnmanagedWarning}, nil
384357
}
385-
return true, &warning{kUnmanagedWarning}, nil
358+
359+
return false, nil, &fatal{kUnmanagedFatal}
386360
}
387361

388362
func (o *DrainOptions) daemonsetFilter(pod corev1.Pod) (bool, *warning, *fatal) {
@@ -393,23 +367,22 @@ func (o *DrainOptions) daemonsetFilter(pod corev1.Pod) (bool, *warning, *fatal)
393367
// The exception is for pods that are orphaned (the referencing
394368
// management resource - including DaemonSet - is not found).
395369
// Such pods will be deleted if --force is used.
396-
controllerRef, err := o.getPodController(pod)
397-
if err != nil {
398-
// if we're forcing, remove orphaned pods with a warning
399-
if apierrors.IsNotFound(err) && o.Force {
400-
return true, &warning{err.Error()}, nil
401-
}
402-
return false, nil, &fatal{err.Error()}
403-
}
370+
controllerRef := o.getPodController(pod)
404371
if controllerRef == nil || controllerRef.Kind != "DaemonSet" {
405372
return true, nil, nil
406373
}
374+
407375
if _, err := o.client.Extensions().DaemonSets(pod.Namespace).Get(controllerRef.Name, metav1.GetOptions{}); err != nil {
376+
// remove orphaned pods with a warning if --force is used
377+
if apierrors.IsNotFound(err) && o.Force {
378+
return true, &warning{err.Error()}, nil
379+
}
408380
return false, nil, &fatal{err.Error()}
409381
}
410382
if !o.IgnoreDaemonsets {
411383
return false, nil, &fatal{kDaemonsetFatal}
412384
}
385+
413386
return false, &warning{kDaemonsetWarning}, nil
414387
}
415388

@@ -455,7 +428,13 @@ func (ps podStatuses) Message() string {
455428
// getPodsForDeletion receives resource info for a node, and returns all the pods from the given node that we
456429
// are planning on deleting. If there are any pods preventing us from deleting, we return that list in an error.
457430
func (o *DrainOptions) getPodsForDeletion(nodeInfo *resource.Info) (pods []corev1.Pod, err error) {
431+
labelSelector, err := labels.Parse(o.PodSelector)
432+
if err != nil {
433+
return pods, err
434+
}
435+
458436
podList, err := o.client.Core().Pods(metav1.NamespaceAll).List(metav1.ListOptions{
437+
LabelSelector: labelSelector.String(),
459438
FieldSelector: fields.SelectorFromSet(fields.Set{"spec.nodeName": nodeInfo.Name}).String()})
460439
if err != nil {
461440
return pods, err

0 commit comments

Comments
 (0)
Please sign in to comment.