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  }