code: func (o *DrainCmdOptions) RunDrain() error {
  	if err := o.RunCordonOrUncordon(true); err != nil {
  		return err
  	}
  
  	printObj, err := o.ToPrinter("drained")
  	if err != nil {
  		return err
  	}
  
  	drainedNodes := sets.NewString()
  	var fatal error
  
  	for _, info := range o.nodeInfos {
  		var err error
  		if !o.drainer.DryRun {
  			err = o.deleteOrEvictPodsSimple(info)
  		}
  		if err == nil || o.drainer.DryRun {
  			drainedNodes.Insert(info.Name)
  			printObj(info.Object, o.Out)
  		} else {
  			fmt.Fprintf(o.ErrOut, "error: unable to drain node %q, aborting command...\n\n", info.Name)
  			remainingNodes := []string{}
  			fatal = err
  			for _, remainingInfo := range o.nodeInfos {
  				if drainedNodes.Has(remainingInfo.Name) {
  					continue
  				}
  				remainingNodes = append(remainingNodes, remainingInfo.Name)
  			}
  
  			if len(remainingNodes) > 0 {
  				fmt.Fprintf(o.ErrOut, "There are pending nodes to be drained:\n")
  				for _, nodeName := range remainingNodes {
  					fmt.Fprintf(o.ErrOut, " %s\n", nodeName)
  				}
  			}
  			break
  		}
  	}
  
  	return fatal
  }
docs: // RunDrain runs the 'drain' command