Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support draining multiple node #469

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
71 changes: 42 additions & 29 deletions chaoslib/litmus/node-drain/lib/node-drain.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,37 +114,50 @@ func PrepareNodeDrain(experimentsDetails *experimentTypes.ExperimentDetails, cli
// drainNode drain the application node
func drainNode(experimentsDetails *experimentTypes.ExperimentDetails, clients clients.ClientSets, chaosDetails *types.ChaosDetails) error {

select {
case <-inject:
// stopping the chaos execution, if abort signal received
os.Exit(0)
default:
log.Infof("[Inject]: Draining the %v node", experimentsDetails.TargetNode)

command := exec.Command("kubectl", "drain", experimentsDetails.TargetNode, "--ignore-daemonsets", "--delete-local-data", "--force", "--timeout", strconv.Itoa(experimentsDetails.ChaosDuration)+"s")
var out, stderr bytes.Buffer
command.Stdout = &out
command.Stderr = &stderr
if err := command.Run(); err != nil {
log.Infof("Error String: %v", stderr.String())
return errors.Errorf("Unable to drain the %v node, err: %v", experimentsDetails.TargetNode, err)
}
targetNodes := strings.Split(experimentsDetails.TargetNode, ",")

common.SetTargets(experimentsDetails.TargetNode, "injected", "node", chaosDetails)
log.Infof("Target nodes list: %v", targetNodes)
for _, targetNode := range targetNodes {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we also handle the panic case when the length of the list is zero and give an error message to provide the target node name.

Copy link
Member

@uditgaurav uditgaurav Jan 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we run chaos for more nodes we could perform the pre and post chaos check for all the target nodes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can also change experimentsDetails.TargetNode to experimentsDetails.TargetNodes in the structure and other places where it is used.


return retry.
Times(uint(experimentsDetails.Timeout / experimentsDetails.Delay)).
Wait(time.Duration(experimentsDetails.Delay) * time.Second).
Try(func(attempt uint) error {
nodeSpec, err := clients.KubeClient.CoreV1().Nodes().Get(experimentsDetails.TargetNode, v1.GetOptions{})
if err != nil {
return err
}
if !nodeSpec.Spec.Unschedulable {
return errors.Errorf("%v node is not in unschedulable state", experimentsDetails.TargetNode)
}
return nil
})
select {
case <-inject:
// stopping the chaos execution, if abort signal received
os.Exit(0)
default:
log.Infof("[Inject]: Draining the %v node", targetNode)

command := exec.Command("kubectl", "drain", targetNode, "--ignore-daemonsets", "--delete-emptydir-data", "--force", "--timeout", strconv.Itoa(experimentsDetails.ChaosDuration)+"s")
var out, stderr bytes.Buffer
command.Stdout = &out
command.Stderr = &stderr
if err := command.Run(); err != nil {
log.Infof("Error String: %v", stderr.String())
return errors.Errorf("Unable to drain the %v node, err: %v", experimentsDetails.TargetNode, err)
}

common.SetTargets(targetNode, "injected", "node", chaosDetails)

err = retry.
Times(uint(experimentsDetails.Timeout / experimentsDetails.Delay)).
Wait(time.Duration(experimentsDetails.Delay) * time.Second).
Try(func(attempt uint) error {
nodeSpec, err := clients.KubeClient.CoreV1().Nodes().Get(targetNode, v1.GetOptions{})
if err != nil {
if apierrors.IsNotFound(err) {
return nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we add a log here to specify that the resource was not found?

} else {
return err
}
}
if !nodeSpec.Spec.Unschedulable {
return errors.Errorf("%v node is not in unschedulable state", targetNode)
}
return nil
})
if err != nil {
return err
}
}
}
return nil
}
Expand Down