package main import ( "context" "encoding/json" "fmt" "math/rand" "os" "os/exec" "path/filepath" "strings" "time" "github.com/bitfield/script" "github.com/bramvdbogaerde/go-scp" pcmd "github.com/elulcao/progress-bar/cmd" "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" ) type envConfig struct { Host string `json:"Host"` Port int `json:"Port"` Username string `json:"Username"` Password string `json:"Password"` Geekbench_License string `json:"Geekbench_License"` } // 在本地启动一个 iperf3 服务端 func iperfServer() { cmd := exec.Command("benchmark/tools/iperf3", "-s") cmd.Run() } func pBar(hsotNum int) { pb := pcmd.NewPBar() pb.SignalHandler() pb.Total = uint16(150 * hsotNum) // pb.RenderPBar(i) for i := 1; uint16(i) <= pb.Total; i++ { pb.RenderPBar(i) if uint16(i) == pb.Total-1 { i -= 2 } time.Sleep(1 * time.Second) } } func randomString(length int) string { const charset = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" var seededRand *rand.Rand = rand.New( rand.NewSource(time.Now().UnixNano())) b := make([]byte, length) for i := range b { b[i] = charset[seededRand.Intn(len(charset))] } return string(b) } // 封装 远程执行 shell 命令 func remoteShellExec(rClient ssh.Client, commands []string, logOut bool) error { outputStr := "" for _, command := range commands { session, err := rClient.NewSession() if err != nil { logrus.Errorf("Failed to create session: %s", err.Error()) } defer session.Close() output, err := session.CombinedOutput(command) if err != nil { logrus.Errorf("Failed to run: %s", err.Error()) } outputStr = string(output) if logOut { fmt.Println(" ") fmt.Println(outputStr) } } return nil } // 测试 SSH 目标主机是否可联通 func testSSH(rClient ssh.Client) bool { session, err := rClient.NewSession() if err != nil { logrus.Error("Failed to dial: ", err) return false } defer session.Close() return true } func main() { file, err := os.Open("config.json") if err != nil { logrus.Error("Error opening file:", err) return } defer file.Close() envConfig := &envConfig{} decoder := json.NewDecoder(file) err = decoder.Decode(&envConfig) if err != nil { fmt.Println("Error decoding file:", err) return } // 读取本地 config.json 文件, 注入成变量 username := envConfig.Username password := envConfig.Password port := envConfig.Port geekbenchLicense := envConfig.Geekbench_License HostExecOut, _ := script.Exec("hostname -I").String() hostIPS := strings.Split(HostExecOut, " ") config := &ssh.ClientConfig{ User: username, Auth: []ssh.AuthMethod{ ssh.Password(password), }, HostKeyCallback: ssh.InsecureIgnoreHostKey(), } // 打印开始 motto logrus.Info("Benchmarking...") // 获取当前时间 start := time.Now() // 获取当前时间 // 初始化 bar cmd go pBar(len(strings.Split(envConfig.Host, ","))) srcDir := "benchmark" dstDir := "/tmp/" + randomString(10) + "/" // 创建 iperfServer 协程 go iperfServer() // 自动关闭 iperfServer 协程 defer func() { cmd := exec.Command("killall", "iperf3") _, err := cmd.Output() if err != nil { logrus.Error("Failed to kill iperf3") } }() // 使用 testSSH 函数测试目标主机是否可联通 for _, host := range strings.Split(envConfig.Host, ",") { serverURL := fmt.Sprintf("%s:%d", host, port) client, err := ssh.Dial("tcp", serverURL, config) if err != nil { logrus.Error("Failed to dial: ", err) } if testSSH(*client) { logrus.Infof("Host: %s , SSH 连接成功", host) } else { logrus.Errorf("Host: %s , SSH 连接失败", host) } } // 按 , 切 config.Host 中的每一个 host for _, host := range strings.Split(envConfig.Host, ",") { serverURL := fmt.Sprintf("%s:%d", host, port) client, err := ssh.Dial("tcp", serverURL, config) if err != nil { logrus.Error("Failed to dial: ", err) } _ = remoteShellExec(*client, []string{"mkdir -p " + dstDir}, false) filepath.Walk(srcDir, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if info.IsDir() { remoteShellExec(*client, []string{"mkdir -p " + dstDir + path}, false) } else { scpClient, err := scp.NewClientBySSH(client) scpClient.Connect() file, err := os.Open(path) defer file.Close() if err != nil { logrus.Error("Failed to open file: ", err) } err = scpClient.CopyFile(context.Background(), file, dstDir+path, "0655") if err != nil { logrus.Error("Failed to copy file: ", err) } scpClient.Close() } return nil }) // 执行 远端 脚本 logrus.Infof("Host: %s , 正在执行远端脚本中...", host) _ = remoteShellExec(*client, []string{ "cd " + dstDir + srcDir + " && " + "./run.sh " + hostIPS[0] + " " + "'" + geekbenchLicense + "'", }, true) // 删除远端文件 remoteShellExec(*client, []string{"rm -rf " + dstDir}, false) } // 打印执行时间 logrus.Infof("本次总计执行时间: %s", time.Since(start)) }