Skip to content

Commit b2f1fa0

Browse files
juanvallejoliggitt
authored andcommitted
UPSTREAM: 56864: pick pod-selector changes from kubernetes#56864: pick of origin kubernetes#17616
:100644 100644 5a7c9db38b... 4e59f91ec8... M pkg/kubectl/cmd/drain.go
1 parent cfb44a9 commit b2f1fa0

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/strategicpatch"
@@ -59,6 +60,7 @@ type DrainOptions struct {
5960
Timeout time.Duration
6061
backOff clockwork.Clock
6162
DeleteLocalData bool
63+
PodSelector string
6264
mapper meta.RESTMapper
6365
nodeInfo *resource.Info
6466
Out io.Writer
@@ -190,6 +192,7 @@ func NewCmdDrain(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
190192
cmd.Flags().BoolVar(&options.DeleteLocalData, "delete-local-data", false, "Continue even if there are pods using emptyDir (local data that will be deleted when the node is drained).")
191193
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.")
192194
cmd.Flags().DurationVar(&options.Timeout, "timeout", 0, "The length of time to wait before giving up, zero means infinite")
195+
cmd.Flags().StringVarP(&options.PodSelector, "pod-selector", "", options.PodSelector, "Label selector to filter pods on the node")
193196
return cmd
194197
}
195198

@@ -201,6 +204,12 @@ func (o *DrainOptions) SetupDrain(cmd *cobra.Command, args []string) error {
201204
return cmdutil.UsageErrorf(cmd, "USAGE: %s [flags]", cmd.Use)
202205
}
203206

207+
if len(o.PodSelector) > 0 {
208+
if _, err := labels.Parse(o.PodSelector); err != nil {
209+
return errors.New("--pod-selector=<pod_selector> must be a valid label selector")
210+
}
211+
}
212+
204213
if o.client, err = o.Factory.ClientSet(); err != nil {
205214
return err
206215
}
@@ -268,38 +277,8 @@ func (o *DrainOptions) deleteOrEvictPodsSimple() error {
268277
return err
269278
}
270279

271-
func (o *DrainOptions) getController(namespace string, controllerRef *metav1.OwnerReference) (interface{}, error) {
272-
switch controllerRef.Kind {
273-
case "ReplicationController":
274-
return o.client.Core().ReplicationControllers(namespace).Get(controllerRef.Name, metav1.GetOptions{})
275-
case "DaemonSet":
276-
return o.client.Extensions().DaemonSets(namespace).Get(controllerRef.Name, metav1.GetOptions{})
277-
case "Job":
278-
return o.client.Batch().Jobs(namespace).Get(controllerRef.Name, metav1.GetOptions{})
279-
case "ReplicaSet":
280-
return o.client.Extensions().ReplicaSets(namespace).Get(controllerRef.Name, metav1.GetOptions{})
281-
case "StatefulSet":
282-
return o.client.Apps().StatefulSets(namespace).Get(controllerRef.Name, metav1.GetOptions{})
283-
}
284-
return nil, fmt.Errorf("Unknown controller kind %q", controllerRef.Kind)
285-
}
286-
287-
func (o *DrainOptions) getPodController(pod api.Pod) (*metav1.OwnerReference, error) {
288-
controllerRef := metav1.GetControllerOf(&pod)
289-
if controllerRef == nil {
290-
return nil, nil
291-
}
292-
293-
// We assume the only reason for an error is because the controller is
294-
// gone/missing, not for any other cause.
295-
// TODO(mml): something more sophisticated than this
296-
// TODO(juntee): determine if it's safe to remove getController(),
297-
// so that drain can work for controller types that we don't know about
298-
_, err := o.getController(pod.Namespace, controllerRef)
299-
if err != nil {
300-
return nil, err
301-
}
302-
return controllerRef, nil
280+
func (o *DrainOptions) getPodController(pod api.Pod) *metav1.OwnerReference {
281+
return metav1.GetControllerOf(&pod)
303282
}
304283

305284
func (o *DrainOptions) unreplicatedFilter(pod api.Pod) (bool, *warning, *fatal) {
@@ -308,21 +287,15 @@ func (o *DrainOptions) unreplicatedFilter(pod api.Pod) (bool, *warning, *fatal)
308287
return true, nil, nil
309288
}
310289

311-
controllerRef, err := o.getPodController(pod)
312-
if err != nil {
313-
// if we're forcing, remove orphaned pods with a warning
314-
if apierrors.IsNotFound(err) && o.Force {
315-
return true, &warning{err.Error()}, nil
316-
}
317-
return false, nil, &fatal{err.Error()}
318-
}
290+
controllerRef := o.getPodController(pod)
319291
if controllerRef != nil {
320292
return true, nil, nil
321293
}
322-
if !o.Force {
323-
return false, nil, &fatal{kUnmanagedFatal}
294+
if o.Force {
295+
return true, &warning{kUnmanagedWarning}, nil
324296
}
325-
return true, &warning{kUnmanagedWarning}, nil
297+
298+
return false, nil, &fatal{kUnmanagedFatal}
326299
}
327300

328301
func (o *DrainOptions) daemonsetFilter(pod api.Pod) (bool, *warning, *fatal) {
@@ -333,23 +306,23 @@ func (o *DrainOptions) daemonsetFilter(pod api.Pod) (bool, *warning, *fatal) {
333306
// The exception is for pods that are orphaned (the referencing
334307
// management resource - including DaemonSet - is not found).
335308
// Such pods will be deleted if --force is used.
336-
controllerRef, err := o.getPodController(pod)
337-
if err != nil {
338-
// if we're forcing, remove orphaned pods with a warning
339-
if apierrors.IsNotFound(err) && o.Force {
340-
return true, &warning{err.Error()}, nil
341-
}
342-
return false, nil, &fatal{err.Error()}
343-
}
309+
controllerRef := o.getPodController(pod)
344310
if controllerRef == nil || controllerRef.Kind != "DaemonSet" {
345311
return true, nil, nil
346312
}
313+
347314
if _, err := o.client.Extensions().DaemonSets(pod.Namespace).Get(controllerRef.Name, metav1.GetOptions{}); err != nil {
315+
// remove orphaned pods with a warning if --force is used
316+
if apierrors.IsNotFound(err) && o.Force {
317+
return true, &warning{err.Error()}, nil
318+
}
348319
return false, nil, &fatal{err.Error()}
349320
}
321+
350322
if !o.IgnoreDaemonsets {
351323
return false, nil, &fatal{kDaemonsetFatal}
352324
}
325+
353326
return false, &warning{kDaemonsetWarning}, nil
354327
}
355328

@@ -395,7 +368,13 @@ func (ps podStatuses) Message() string {
395368
// getPodsForDeletion returns all the pods we're going to delete. If there are
396369
// any pods preventing us from deleting, we return that list in an error.
397370
func (o *DrainOptions) getPodsForDeletion() (pods []api.Pod, err error) {
371+
labelSelector, err := labels.Parse(o.PodSelector)
372+
if err != nil {
373+
return pods, err
374+
}
375+
398376
podList, err := o.client.Core().Pods(metav1.NamespaceAll).List(metav1.ListOptions{
377+
LabelSelector: labelSelector.String(),
399378
FieldSelector: fields.SelectorFromSet(fields.Set{"spec.nodeName": o.nodeInfo.Name}).String()})
400379
if err != nil {
401380
return pods, err

0 commit comments

Comments
 (0)