1
16
17 package common
18
19 import (
20 "bytes"
21 "context"
22 "fmt"
23 "text/template"
24 "time"
25
26 v1 "k8s.io/api/core/v1"
27 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28 "k8s.io/apimachinery/pkg/util/intstr"
29 "k8s.io/apimachinery/pkg/util/sets"
30 "k8s.io/apimachinery/pkg/util/wait"
31 clientset "k8s.io/client-go/kubernetes"
32 "k8s.io/kubernetes/test/e2e/framework"
33 e2erc "k8s.io/kubernetes/test/e2e/framework/rc"
34 imageutils "k8s.io/kubernetes/test/utils/image"
35
36 "github.com/onsi/ginkgo/v2"
37 )
38
39
40
41
42 type Suite string
43
44 const (
45
46 E2E Suite = "e2e"
47
48 NodeE2E Suite = "node e2e"
49 )
50
51
52 var CurrentSuite Suite
53
54
55
56
57
58
59 var PrePulledImages = sets.NewString(
60 imageutils.GetE2EImage(imageutils.Agnhost),
61 imageutils.GetE2EImage(imageutils.BusyBox),
62 imageutils.GetE2EImage(imageutils.IpcUtils),
63 imageutils.GetE2EImage(imageutils.Nginx),
64 imageutils.GetE2EImage(imageutils.Httpd),
65 imageutils.GetE2EImage(imageutils.VolumeNFSServer),
66 imageutils.GetE2EImage(imageutils.NonRoot),
67 )
68
69
70
71
72 var WindowsPrePulledImages = sets.NewString(
73 imageutils.GetE2EImage(imageutils.Agnhost),
74 imageutils.GetE2EImage(imageutils.BusyBox),
75 imageutils.GetE2EImage(imageutils.Nginx),
76 imageutils.GetE2EImage(imageutils.Httpd),
77 )
78
79 type testImagesStruct struct {
80 AgnhostImage string
81 BusyBoxImage string
82 KittenImage string
83 NautilusImage string
84 NginxImage string
85 NginxNewImage string
86 HttpdImage string
87 HttpdNewImage string
88 PauseImage string
89 RedisImage string
90 }
91
92 var testImages testImagesStruct
93
94 func init() {
95 testImages = testImagesStruct{
96 imageutils.GetE2EImage(imageutils.Agnhost),
97 imageutils.GetE2EImage(imageutils.BusyBox),
98 imageutils.GetE2EImage(imageutils.Kitten),
99 imageutils.GetE2EImage(imageutils.Nautilus),
100 imageutils.GetE2EImage(imageutils.Nginx),
101 imageutils.GetE2EImage(imageutils.NginxNew),
102 imageutils.GetE2EImage(imageutils.Httpd),
103 imageutils.GetE2EImage(imageutils.HttpdNew),
104 imageutils.GetE2EImage(imageutils.Pause),
105 imageutils.GetE2EImage(imageutils.Redis),
106 }
107 }
108
109
110 func SubstituteImageName(content string) string {
111 contentWithImageName := new(bytes.Buffer)
112 tmpl, err := template.New("imagemanifest").Parse(content)
113 if err != nil {
114 framework.Failf("Failed Parse the template: %v", err)
115 }
116 err = tmpl.Execute(contentWithImageName, testImages)
117 if err != nil {
118 framework.Failf("Failed executing template: %v", err)
119 }
120 return contentWithImageName.String()
121 }
122
123 func svcByName(name string, port int) *v1.Service {
124 return &v1.Service{
125 ObjectMeta: metav1.ObjectMeta{
126 Name: name,
127 },
128 Spec: v1.ServiceSpec{
129 Type: v1.ServiceTypeNodePort,
130 Selector: map[string]string{
131 "name": name,
132 },
133 Ports: []v1.ServicePort{{
134 Port: int32(port),
135 TargetPort: intstr.FromInt32(int32(port)),
136 }},
137 },
138 }
139 }
140
141
142 func NewSVCByName(c clientset.Interface, ns, name string) error {
143 const testPort = 9376
144 _, err := c.CoreV1().Services(ns).Create(context.TODO(), svcByName(name, testPort), metav1.CreateOptions{})
145 return err
146 }
147
148
149 func NewRCByName(c clientset.Interface, ns, name string, replicas int32, gracePeriod *int64, containerArgs []string) (*v1.ReplicationController, error) {
150 ginkgo.By(fmt.Sprintf("creating replication controller %s", name))
151
152 if containerArgs == nil {
153 containerArgs = []string{"serve-hostname"}
154 }
155
156 return c.CoreV1().ReplicationControllers(ns).Create(context.TODO(), rcByNamePort(
157 name, replicas, framework.ServeHostnameImage, containerArgs, 9376, v1.ProtocolTCP, map[string]string{}, gracePeriod), metav1.CreateOptions{})
158 }
159
160
161 func RestartNodes(c clientset.Interface, nodes []v1.Node) error {
162
163 nodeNamesByZone := make(map[string][]string)
164 for i := range nodes {
165 node := &nodes[i]
166 zone := framework.TestContext.CloudConfig.Zone
167 if z, ok := node.Labels[v1.LabelFailureDomainBetaZone]; ok {
168 zone = z
169 } else if z, ok := node.Labels[v1.LabelTopologyZone]; ok {
170 zone = z
171 }
172 nodeNamesByZone[zone] = append(nodeNamesByZone[zone], node.Name)
173 }
174
175
176 for zone, nodeNames := range nodeNamesByZone {
177 args := []string{
178 "compute",
179 fmt.Sprintf("--project=%s", framework.TestContext.CloudConfig.ProjectID),
180 "instances",
181 "reset",
182 }
183 args = append(args, nodeNames...)
184 args = append(args, fmt.Sprintf("--zone=%s", zone))
185 stdout, stderr, err := framework.RunCmd("gcloud", args...)
186 if err != nil {
187 return fmt.Errorf("error restarting nodes: %s\nstdout: %s\nstderr: %s", err, stdout, stderr)
188 }
189 }
190
191
192 for i := range nodes {
193 node := &nodes[i]
194 if err := wait.Poll(30*time.Second, framework.RestartNodeReadyAgainTimeout, func() (bool, error) {
195 newNode, err := c.CoreV1().Nodes().Get(context.TODO(), node.Name, metav1.GetOptions{})
196 if err != nil {
197 return false, fmt.Errorf("error getting node info after reboot: %w", err)
198 }
199 return node.Status.NodeInfo.BootID != newNode.Status.NodeInfo.BootID, nil
200 }); err != nil {
201 return fmt.Errorf("error waiting for node %s boot ID to change: %w", node.Name, err)
202 }
203 }
204 return nil
205 }
206
207
208 func rcByNamePort(name string, replicas int32, image string, containerArgs []string, port int, protocol v1.Protocol,
209 labels map[string]string, gracePeriod *int64) *v1.ReplicationController {
210
211 return e2erc.ByNameContainer(name, replicas, labels, v1.Container{
212 Name: name,
213 Image: image,
214 Args: containerArgs,
215 Ports: []v1.ContainerPort{{ContainerPort: int32(port), Protocol: protocol}},
216 }, gracePeriod)
217 }
218
View as plain text