Skip to content

Commit 26a3b2f

Browse files
committed
refactor: Enable external triggering of graceful/ungraceful node reboots
This commit refactors the node reboot functionality in `test/e2e/upgrade/monitor.go` to allow external triggering of graceful and ungraceful node reboots. The functionality was moved to `test/extended/util/nodes.go`, and only used in the `Disrupt` function in `test/e2e/upgrade/monitor.go`. No new functionality was added, only the code was refactored. This change enables other components to initiate node reboots.
1 parent 6a5d795 commit 26a3b2f

File tree

2 files changed

+75
-65
lines changed

2 files changed

+75
-65
lines changed

test/e2e/upgrade/monitor.go

Lines changed: 4 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,15 @@ import (
1010
"text/tabwriter"
1111
"time"
1212

13-
corev1 "k8s.io/api/core/v1"
14-
"k8s.io/apimachinery/pkg/api/errors"
1513
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1614
"k8s.io/apimachinery/pkg/util/wait"
1715
"k8s.io/client-go/kubernetes"
1816
"k8s.io/kubernetes/test/e2e/framework"
1917

2018
configv1 "github.com/openshift/api/config/v1"
2119
configv1client "github.com/openshift/client-go/config/clientset/versioned"
20+
"github.com/openshift/origin/test/extended/util"
2221
"github.com/openshift/origin/test/extended/util/disruption"
23-
"github.com/openshift/origin/test/extended/util/image"
2422
)
2523

2624
type versionMonitor struct {
@@ -189,13 +187,13 @@ func (m *versionMonitor) Describe(f *framework.Framework) {
189187
}
190188

191189
func (m *versionMonitor) Disrupt(ctx context.Context, kubeClient kubernetes.Interface, rebootPolicy string) {
192-
rebootHard := false
190+
rebootFunc := util.TriggerNodeRebootGraceful
193191
switch rebootPolicy {
194192
case "graceful":
195193
framework.Logf("Periodically reboot master nodes with clean shutdown")
196194
case "force":
197195
framework.Logf("Periodically reboot master nodes without allowing for clean shutdown")
198-
rebootHard = true
196+
rebootFunc = util.TriggerNodeRebootUngraceful
199197
case "":
200198
return
201199
}
@@ -212,7 +210,7 @@ func (m *versionMonitor) Disrupt(ctx context.Context, kubeClient kubernetes.Inte
212210
rand.Shuffle(len(nodes.Items), func(i, j int) { nodes.Items[i], nodes.Items[j] = nodes.Items[j], nodes.Items[i] })
213211
name := nodes.Items[0].Name
214212
framework.Logf("DISRUPTION: Triggering reboot of %s", name)
215-
if err := triggerReboot(kubeClient, name, 0, rebootHard); err != nil {
213+
if err := rebootFunc(kubeClient, name); err != nil {
216214
framework.Logf("Failed to reboot %s: %v", name, err)
217215
continue
218216
}
@@ -317,62 +315,3 @@ func versionString(update configv1.Update) string {
317315
return "<empty>"
318316
}
319317
}
320-
321-
func triggerReboot(kubeClient kubernetes.Interface, target string, attempt int, rebootHard bool) error {
322-
command := "echo 'reboot in 1 minute'; exec chroot /host shutdown -r 1"
323-
if rebootHard {
324-
command = "echo 'reboot in 1 minute'; exec chroot /host sudo systemd-run sh -c 'sleep 60 && reboot --force --force'"
325-
}
326-
isTrue := true
327-
zero := int64(0)
328-
name := fmt.Sprintf("reboot-%s-%d", target, attempt)
329-
_, err := kubeClient.CoreV1().Pods("kube-system").Create(context.Background(), &corev1.Pod{
330-
ObjectMeta: metav1.ObjectMeta{
331-
Name: name,
332-
Annotations: map[string]string{
333-
"test.openshift.io/upgrades-target": target,
334-
},
335-
},
336-
Spec: corev1.PodSpec{
337-
HostPID: true,
338-
RestartPolicy: corev1.RestartPolicyNever,
339-
NodeName: target,
340-
Volumes: []corev1.Volume{
341-
{
342-
Name: "host",
343-
VolumeSource: corev1.VolumeSource{
344-
HostPath: &corev1.HostPathVolumeSource{
345-
Path: "/",
346-
},
347-
},
348-
},
349-
},
350-
Containers: []corev1.Container{
351-
{
352-
Name: "reboot",
353-
SecurityContext: &corev1.SecurityContext{
354-
RunAsUser: &zero,
355-
Privileged: &isTrue,
356-
},
357-
Image: image.ShellImage(),
358-
Command: []string{
359-
"/bin/bash",
360-
"-c",
361-
command,
362-
},
363-
TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError,
364-
VolumeMounts: []corev1.VolumeMount{
365-
{
366-
MountPath: "/host",
367-
Name: "host",
368-
},
369-
},
370-
},
371-
},
372-
},
373-
}, metav1.CreateOptions{})
374-
if errors.IsAlreadyExists(err) {
375-
return triggerReboot(kubeClient, target, attempt+1, rebootHard)
376-
}
377-
return err
378-
}

test/extended/util/nodes.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@ package util
22

33
import (
44
"context"
5+
"fmt"
56
"strings"
67
"time"
78

9+
"github.com/openshift/origin/test/extended/util/image"
810
corev1 "k8s.io/api/core/v1"
11+
"k8s.io/apimachinery/pkg/api/errors"
912
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1013
"k8s.io/apimachinery/pkg/util/wait"
14+
"k8s.io/client-go/kubernetes"
1115
)
1216

1317
// GetClusterNodesByRole returns the cluster nodes by role
@@ -87,3 +91,70 @@ func DebugSelectedNodesRetryWithOptionsAndChroot(oc *CLI, selector string, debug
8791
func DebugAllNodesRetryWithOptionsAndChroot(oc *CLI, debugNodeNamespace string, cmd ...string) (map[string]string, error) {
8892
return DebugSelectedNodesRetryWithOptionsAndChroot(oc, "", debugNodeNamespace, cmd...)
8993
}
94+
95+
// TriggerNodeRebootGraceful initiates a graceful node reboot which allows the system to terminate processes cleanly before rebooting.
96+
func TriggerNodeRebootGraceful(kubeClient kubernetes.Interface, nodeName string) error {
97+
command := "echo 'reboot in 1 minute'; exec chroot /host shutdown -r 1"
98+
return triggerNodeReboot(kubeClient, nodeName, 0, command)
99+
}
100+
101+
// TriggerNodeRebootUngraceful initiates an ungraceful node reboot which does not allow the system to terminate processes cleanly before rebooting.
102+
func TriggerNodeRebootUngraceful(kubeClient kubernetes.Interface, nodeName string) error {
103+
command := "echo 'reboot in 1 minute'; exec chroot /host sudo systemd-run sh -c 'sleep 60 && reboot --force --force'"
104+
return triggerNodeReboot(kubeClient, nodeName, 0, command)
105+
}
106+
107+
func triggerNodeReboot(kubeClient kubernetes.Interface, nodeName string, attempt int, command string) error {
108+
isTrue := true
109+
zero := int64(0)
110+
name := fmt.Sprintf("reboot-%s-%d", nodeName, attempt)
111+
_, err := kubeClient.CoreV1().Pods("kube-system").Create(context.Background(), &corev1.Pod{
112+
ObjectMeta: metav1.ObjectMeta{
113+
Name: name,
114+
Annotations: map[string]string{
115+
"test.openshift.io/disrupt-target": nodeName,
116+
},
117+
},
118+
Spec: corev1.PodSpec{
119+
HostPID: true,
120+
RestartPolicy: corev1.RestartPolicyNever,
121+
NodeName: nodeName,
122+
Volumes: []corev1.Volume{
123+
{
124+
Name: "host",
125+
VolumeSource: corev1.VolumeSource{
126+
HostPath: &corev1.HostPathVolumeSource{
127+
Path: "/",
128+
},
129+
},
130+
},
131+
},
132+
Containers: []corev1.Container{
133+
{
134+
Name: "reboot",
135+
SecurityContext: &corev1.SecurityContext{
136+
RunAsUser: &zero,
137+
Privileged: &isTrue,
138+
},
139+
Image: image.ShellImage(),
140+
Command: []string{
141+
"/bin/bash",
142+
"-c",
143+
command,
144+
},
145+
TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError,
146+
VolumeMounts: []corev1.VolumeMount{
147+
{
148+
MountPath: "/host",
149+
Name: "host",
150+
},
151+
},
152+
},
153+
},
154+
},
155+
}, metav1.CreateOptions{})
156+
if errors.IsAlreadyExists(err) {
157+
return triggerNodeReboot(kubeClient, nodeName, attempt+1, command)
158+
}
159+
return err
160+
}

0 commit comments

Comments
 (0)