1
16
17 package services
18
19 import (
20 "fmt"
21 "os"
22 "os/exec"
23 "path"
24 "testing"
25
26 "k8s.io/klog/v2"
27
28 "k8s.io/kubernetes/test/e2e/framework"
29 )
30
31
32
33 type E2EServices struct {
34
35
36 rmDirs []string
37 monitorParent bool
38 services *server
39 kubelet *server
40 logs logFiles
41 }
42
43
44 func NewE2EServices(monitorParent bool) *E2EServices {
45 return &E2EServices{
46 monitorParent: monitorParent,
47
48 logs: getLogFiles(),
49 }
50 }
51
52
53
54
55
56
57
58
59
60
61
62
63 func (e *E2EServices) Start(featureGates map[string]bool) error {
64 var err error
65 if e.services, err = e.startInternalServices(); err != nil {
66 return fmt.Errorf("failed to start internal services: %w", err)
67 }
68 klog.Infof("Node services started.")
69
70 if framework.TestContext.NodeConformance {
71 klog.Info("nothing to do in node-e2e-services, running conformance suite")
72 } else {
73
74 e.kubelet, err = e.startKubelet(featureGates)
75 if err != nil {
76 return fmt.Errorf("failed to start kubelet: %w", err)
77 }
78 klog.Infof("Kubelet started.")
79 }
80 return nil
81 }
82
83
84 func (e *E2EServices) Stop() {
85 defer func() {
86 if !framework.TestContext.NodeConformance {
87
88 e.collectLogFiles()
89 }
90 }()
91 if e.services != nil {
92 if err := e.services.kill(); err != nil {
93 klog.Errorf("Failed to stop services: %v", err)
94 }
95 }
96 if e.kubelet != nil {
97 if err := e.kubelet.kill(); err != nil {
98 klog.Errorf("Failed to kill kubelet: %v", err)
99 }
100
101 if err := e.kubelet.stopUnit(); err != nil {
102 klog.Errorf("Failed to stop kubelet systemd unit: %v", err)
103 }
104 }
105 for _, d := range e.rmDirs {
106 err := os.RemoveAll(d)
107 if err != nil {
108 klog.Errorf("Failed to delete directory %s: %v", d, err)
109 }
110 }
111 }
112
113
114
115 func RunE2EServices(t *testing.T) {
116 e := newE2EServices()
117 if err := e.run(t); err != nil {
118 klog.Fatalf("Failed to run e2e services: %v", err)
119 }
120 }
121
122 const (
123
124 servicesLogFile = "services.log"
125
126 LogVerbosityLevel = "4"
127 )
128
129
130 func (e *E2EServices) startInternalServices() (*server, error) {
131 testBin, err := os.Executable()
132 if err != nil {
133 return nil, fmt.Errorf("can't get current binary: %w", err)
134 }
135
136 startCmd := exec.Command(testBin,
137 append(
138 []string{"--run-services-mode", fmt.Sprintf("--bearer-token=%s", framework.TestContext.BearerToken)},
139 os.Args[1:]...,
140 )...)
141 server := newServer("services", startCmd, nil, nil, getServicesHealthCheckURLs(), servicesLogFile, e.monitorParent, false, "")
142 return server, server.start()
143 }
144
145
146
147
148 func (e *E2EServices) collectLogFiles() {
149
150 if framework.TestContext.ReportDir == "" {
151 return
152 }
153 klog.Info("Fetching log files...")
154 journaldFound := isJournaldAvailable()
155 for targetFileName, log := range e.logs {
156 targetLink := path.Join(framework.TestContext.ReportDir, targetFileName)
157 if journaldFound {
158
159 if len(log.JournalctlCommand) == 0 {
160 continue
161 }
162 klog.Infof("Get log file %q with journalctl command %v.", targetFileName, log.JournalctlCommand)
163 out, err := exec.Command("journalctl", log.JournalctlCommand...).CombinedOutput()
164 if err != nil {
165 klog.Errorf("failed to get %q from journald: %v, %v", targetFileName, string(out), err)
166 } else {
167 if err = os.WriteFile(targetLink, out, 0644); err != nil {
168 klog.Errorf("failed to write logs to %q: %v", targetLink, err)
169 }
170 }
171 continue
172 }
173 for _, file := range log.Files {
174 if _, err := os.Stat(file); err != nil {
175
176 continue
177 }
178 if err := copyLogFile(file, targetLink); err != nil {
179 klog.Error(err)
180 } else {
181 break
182 }
183 }
184 }
185 }
186
187
188
189 func isJournaldAvailable() bool {
190 _, err := exec.LookPath("journalctl")
191 return err == nil
192 }
193
194 func copyLogFile(src, target string) error {
195
196 if out, err := exec.Command("cp", src, target).CombinedOutput(); err != nil {
197 return fmt.Errorf("failed to copy %q to %q: %v, %v", src, target, out, err)
198 }
199 if out, err := exec.Command("chmod", "a+r", target).CombinedOutput(); err != nil {
200 return fmt.Errorf("failed to make log file %q world readable: %v, %v", target, out, err)
201 }
202 return nil
203 }
204
View as plain text