github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/test/e2e/util/smoke_util.go (about) 1 /* 2 Copyright (C) 2022-2023 ApeCloud Co., Ltd 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package util 18 19 import ( 20 "bufio" 21 "bytes" 22 "io" 23 "io/ioutil" 24 "log" 25 "os" 26 executil "os/exec" 27 "path/filepath" 28 "strings" 29 "sync" 30 31 "github.com/pkg/errors" 32 "k8s.io/utils/exec" 33 ) 34 35 const label = "app.kubernetes.io/instance" 36 37 func GetFiles(path string) ([]string, error) { 38 var result []string 39 e := filepath.Walk(path, func(path string, fi os.FileInfo, err error) error { 40 if err != nil { 41 log.Println(err) 42 return err 43 } 44 if !fi.IsDir() { 45 if strings.HasSuffix(path, ".yaml") || strings.HasSuffix(path, ".yml") { 46 result = append(result, path) 47 } 48 } 49 return nil 50 }) 51 if e != nil { 52 log.Println(e) 53 return result, e 54 } 55 return result, nil 56 } 57 58 func GetFolders(path string) ([]string, error) { 59 var result []string 60 e := filepath.Walk(path, func(path string, fi os.FileInfo, err error) error { 61 if err != nil { 62 log.Println(err) 63 return err 64 } 65 if fi.IsDir() { 66 result = append(result, path) 67 } 68 return nil 69 }) 70 if e != nil { 71 log.Println(e) 72 return result, e 73 } 74 return result, nil 75 } 76 77 func CheckClusterStatus(name, ns string, status string) bool { 78 cmd := "kubectl get cluster " + name + " -n " + ns + " | grep " + name + " | awk '{print $5}'" 79 log.Println(cmd) 80 clusterStatus := ExecCommand(cmd) 81 log.Println("clusterStatus is " + clusterStatus) 82 return strings.TrimSpace(clusterStatus) == status 83 } 84 85 func CheckPodStatus(name, ns string) map[string]bool { 86 var podStatusResult = make(map[string]bool) 87 cmd := "kubectl get pod -n " + ns + " -l '" + label + "=" + name + "'| grep " + name + " | awk '{print $1}'" 88 log.Println(cmd) 89 arr := ExecCommandReadline(cmd) 90 log.Println(arr) 91 if len(arr) > 0 { 92 for _, podName := range arr { 93 command := "kubectl get pod " + podName + " -n " + ns + " | grep " + podName + " | awk '{print $3}'" 94 log.Println(command) 95 podStatus := ExecCommand(command) 96 log.Println("podStatus is " + podStatus) 97 if strings.TrimSpace(podStatus) == "Running" { 98 podStatusResult[podName] = true 99 } else { 100 podStatusResult[podName] = false 101 } 102 } 103 } 104 return podStatusResult 105 } 106 107 func OpsYaml(file string, ops string) bool { 108 cmd := "kubectl " + ops + " -f " + file 109 log.Println(cmd) 110 b := ExecuteCommand(cmd) 111 return b 112 } 113 114 func ExecuteCommand(command string) bool { 115 exeFlag := true 116 cmd := exec.New().Command("bash", "-c", command) 117 // Create a fetch command output pipe 118 stdout, err := cmd.StdoutPipe() 119 if err != nil { 120 log.Printf("Error:can not obtain stdout pipe for command:%s\n", err) 121 exeFlag = false 122 } 123 // Create a fetch command err output pipe 124 stderr, err1 := cmd.StderrPipe() 125 if err1 != nil { 126 log.Printf("Error:can not obtain stderr pipe for command:%s\n", err1) 127 exeFlag = false 128 } 129 // Run command 130 if err := cmd.Start(); err != nil { 131 log.Printf("Error:The command is err:%s\n", err) 132 exeFlag = false 133 } 134 // Use buffered readers 135 go asyncLog(stdout) 136 go asyncLog(stderr) 137 if err := cmd.Wait(); err != nil { 138 log.Printf("wait:%s\n", err.Error()) 139 exeFlag = false 140 } 141 return exeFlag 142 } 143 144 func asyncLog(reader io.Reader) { 145 cache := "" 146 buf := make([]byte, 1024) 147 for { 148 num, err := reader.Read(buf) 149 if err != nil && errors.Is(err, io.EOF) { 150 return 151 } 152 if num > 0 { 153 b := buf[:num] 154 s := strings.Split(string(b), "\n") 155 line := strings.Join(s[:len(s)-1], "\n") 156 log.Printf("%s%s\n", cache, line) 157 cache = s[len(s)-1] 158 } 159 if errors.Is(err, io.EOF) { 160 break 161 } 162 } 163 } 164 165 func ExecCommandReadline(strCommand string) []string { 166 var arr []string 167 cmd := exec.New().Command("/bin/bash", "-c", strCommand) 168 stdout, _ := cmd.StdoutPipe() 169 if err := cmd.Start(); err != nil { 170 log.Printf("Execute failed when Start:%s\n\n", err.Error()) 171 } 172 reader := bufio.NewReader(stdout) 173 for { 174 line, err := reader.ReadString('\n') 175 line = strings.TrimSpace(line) 176 if err != nil || io.EOF == err { 177 break 178 } 179 arr = append(arr, line) 180 } 181 if err := cmd.Wait(); err != nil { 182 log.Printf("wait:%s\n\n", err.Error()) 183 } 184 return arr 185 } 186 187 func ExecCommand(strCommand string) string { 188 cmd := exec.New().Command("/bin/bash", "-c", strCommand) 189 stdout, _ := cmd.StdoutPipe() 190 if err := cmd.Start(); err != nil { 191 log.Printf("failed to Start:%s\n", err.Error()) 192 return "" 193 } 194 outBytes, _ := io.ReadAll(stdout) 195 err := stdout.Close() 196 if err != nil { 197 return "" 198 } 199 if err := cmd.Wait(); err != nil { 200 log.Printf("failed to Wait:%s\n", err.Error()) 201 return "" 202 } 203 return string(outBytes) 204 } 205 206 func WaitTime(num int) { 207 wg := sync.WaitGroup{} 208 wg.Add(num) 209 for i := 0; i < num; i++ { 210 go func(i int) { 211 defer wg.Done() 212 }(i) 213 } 214 wg.Wait() 215 } 216 217 func GetClusterCreateYaml(files []string) string { 218 for _, file := range files { 219 if strings.Contains(file, "00") { 220 return file 221 } 222 } 223 return "" 224 } 225 226 func GetClusterVersion(folder string) (result []string) { 227 dbType := GetPrefix(folder, "/") 228 WaitTime(3000000) 229 cmd := "kubectl get ClusterVersion | grep " + dbType + " | awk '{print $1}'" 230 log.Println("cmd: " + cmd) 231 result = ExecCommandReadline(cmd) 232 log.Println(result) 233 return result 234 } 235 236 func GetPrefix(str string, sub string) (s string) { 237 index := strings.LastIndex(str, sub) 238 s = str[index+1:] 239 return 240 } 241 242 func ReplaceClusterVersionRef(fileName string, clusterVersionRef string) { 243 file, err := os.OpenFile(fileName, os.O_RDWR, 0666) 244 if err != nil { 245 log.Println("open file filed.", err) 246 return 247 } 248 reader := bufio.NewReader(file) 249 pos := int64(0) 250 for { 251 line, err := reader.ReadString('\n') 252 if err != nil { 253 if err == io.EOF { 254 log.Println("file read ok!") 255 break 256 } else { 257 log.Println("file read error ", err) 258 return 259 } 260 } 261 if strings.Contains(line, "app.kubernetes.io/version") { 262 version := GetPrefix(clusterVersionRef, "-") 263 bytes := []byte(" app.kubernetes.io/version: \"" + version + "\"\n") 264 _, err := file.WriteAt(bytes, pos) 265 if err != nil { 266 log.Println("file open failed ", err) 267 } 268 } 269 if strings.Contains(line, "clusterVersionRef") { 270 bytes := []byte(" clusterVersionRef: " + clusterVersionRef + "\n") 271 _, err := file.WriteAt(bytes, pos) 272 if err != nil { 273 log.Println("file open failed ", err) 274 } 275 } 276 pos += int64(len(line)) 277 } 278 } 279 280 func StringStrip(str string) string { 281 str = strings.ReplaceAll(str, " ", "") 282 str = strings.ReplaceAll(str, "\n", "") 283 return str 284 } 285 286 func CheckKbcliExists() error { 287 _, err := exec.New().LookPath("kbcli") 288 return err 289 } 290 291 func Check(command string, input string) (string, error) { 292 cmd := executil.Command("bash", "-c", command) 293 294 var output bytes.Buffer 295 cmd.Stdout = &output 296 297 inPipe, err := cmd.StdinPipe() 298 if err != nil { 299 return "", err 300 } 301 302 err = cmd.Start() 303 if err != nil { 304 return "", err 305 } 306 307 _, e := io.WriteString(inPipe, input) 308 if e != nil { 309 return "", e 310 } 311 312 err = cmd.Wait() 313 if err != nil { 314 return "", err 315 } 316 317 return output.String(), nil 318 } 319 320 func GetName(fileName string) (name, ns string) { 321 file, err := os.Open(fileName) 322 if err != nil { 323 log.Println(err) 324 } 325 br := bufio.NewReader(file) 326 for { 327 line, err := br.ReadString('\n') 328 if err == io.EOF { 329 break 330 } 331 if strings.Contains(line, "cluster.yaml") { 332 for { 333 line, err := br.ReadString('\n') 334 if err == io.EOF { 335 break 336 } 337 if strings.Contains(line, "---") { 338 break 339 } 340 if strings.Contains(line, " name:") { 341 name = StringSplit(line) 342 } 343 if strings.Contains(line, " namespace:") { 344 ns = StringSplit(line) 345 } else { 346 ns = "default" 347 } 348 } 349 break 350 } 351 } 352 353 return name, ns 354 } 355 356 func ReadLineLast(fileName string, name string) string { 357 file, err := os.Open(fileName) 358 if err != nil { 359 log.Fatalln(err) 360 } 361 scanner := bufio.NewScanner(file) 362 var last string 363 364 for scanner.Scan() { 365 line := scanner.Text() 366 if strings.Contains(line, name) { 367 last = line 368 } 369 } 370 return last 371 } 372 373 func StringSplit(str string) string { 374 s := strings.Split(str, ":")[1] 375 s = strings.ReplaceAll(s, "\n", "") 376 s = strings.ReplaceAll(s, "\n", "") 377 return s 378 } 379 380 func ReadLine(fileName string, name string) string { 381 file, _ := os.Open(fileName) 382 fileScanner := bufio.NewScanner(file) 383 for fileScanner.Scan() { 384 line := fileScanner.Text() 385 if strings.Contains(line, name) { 386 return line 387 } 388 } 389 return "" 390 } 391 392 func Count(filename, substring string) (int, error) { 393 bytes, err := ioutil.ReadFile(filename) 394 if err != nil { 395 return 0, err 396 } 397 content := string(bytes) 398 return countSubstring(content, substring), nil 399 } 400 401 func countSubstring(str, sub string) int { 402 count := 0 403 index := strings.Index(str, sub) 404 for index >= 0 { 405 count++ 406 index = strings.Index(str[index+1:], sub) 407 } 408 return count 409 } 410 411 func CheckCommand(command string, path string) bool { 412 cmdPath := path + "/" + command 413 if fi, err := os.Stat(cmdPath); err == nil && fi.Mode()&0111 != 0 { 414 return true 415 } 416 if _, err := exec.New().LookPath(cmdPath); err == nil { 417 return true 418 } 419 420 return false 421 } 422 423 func RemoveElements(arr []string, elemsToRemove []string) []string { 424 var result []string 425 m := make(map[string]bool) 426 for _, e := range elemsToRemove { 427 m[e] = true 428 } 429 for _, e := range arr { 430 if !m[e] { 431 result = append(result, e) 432 } 433 } 434 return result 435 }