cheliequan
2023-05-24 bb18319bdcaf408e822456c0ab2285bb01ae3e0a
src/util/util.go
@@ -1,6 +1,15 @@
package util
import "os"
import (
   "context"
   "crypto/tls"
   "fmt"
   "net/http"
   "os"
   "time"
   "golang.org/x/crypto/ssh"
)
// homeDir 获取当前用户的家目录路径
func homeDir() string {
@@ -9,3 +18,130 @@
   }
   return os.Getenv("USERPROFILE") // Windows 环境下获取用户目录
}
func sshExec(nodeIP, sshUsername, sshPassword, remoteSSHCommand string, sshPort int) (string, error) {
   // SSH 连接配置
   config := &ssh.ClientConfig{
      User: sshUsername,
      Auth: []ssh.AuthMethod{
         ssh.Password(sshPassword),
      },
      HostKeyCallback: ssh.InsecureIgnoreHostKey(),
   }
   // 连接到远程服务器
   client, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", nodeIP, sshPort), config)
   if err != nil {
      return "", fmt.Errorf("failed to connect to node %s: %v", nodeIP, err)
   }
   defer client.Close()
   // 创建会话
   session, err := client.NewSession()
   if err != nil {
      return "", fmt.Errorf("failed to create SSH session: %v", err)
   }
   defer session.Close()
   // 创建一个具有超时的上下文
   ctx, cancel := context.WithTimeout(context.Background(), 300*time.Second)
   defer cancel()
   // 通过会话执行远程命令
   outputChan := make(chan string)
   errorChan := make(chan error)
   go func() {
      // 创建一个连接标准输入的管道
      stdinPipe, err := session.StdinPipe()
      if err != nil {
         errorChan <- fmt.Errorf("failed to create stdin pipe: %v", err)
         return
      }
      // 启动会话
      if err := session.Start(fmt.Sprintf("sudo -SE %s", remoteSSHCommand)); err != nil {
         errorChan <- fmt.Errorf("failed to start command: %v err:%v", remoteSSHCommand, err)
         return
      }
      // 将密码写入标准输入管道
      _, err = fmt.Fprintf(stdinPipe, "%s\n", sshPassword)
      if err != nil {
         errorChan <- fmt.Errorf("failed to write password to stdin: %v", err)
         return
      }
      // 等待会话结束
      if err := session.Wait(); err != nil {
         errorChan <- fmt.Errorf("command execution failed: %v err:%v", remoteSSHCommand, err)
         return
      }
      outputChan <- ""
   }()
   // 等待结果或超时
   select {
   case <-ctx.Done():
      // 关闭会话以终止远程命令
      session.Close()
      // 等待会话关闭的 goroutine 结束
      <-outputChan
      return "", fmt.Errorf("SSH command execution timed out")
   case err := <-errorChan:
      return "", err
   case <-outputChan:
      fmt.Printf("Command: %v executed on the remote server: %s\n", remoteSSHCommand, nodeIP)
      return "", nil
   }
}
// 安装Docker
func installDocker(nodeIP, sshUsername, sshPassword string, sshPort int) error {
   // 检查Docker是否已安装
   checkCommand := "which docker"
   _, err := sshExec(nodeIP, sshUsername, sshPassword, checkCommand, sshPort)
   if err == nil {
      fmt.Println("Docker is already installed on the remote server.")
      return nil
   }
   // 安装Docker
   installCommand := "sudo curl -fsSL https://get.docker.com -o get-docker.sh && sudo sh get-docker.sh"
   _, err = sshExec(nodeIP, sshUsername, sshPassword, installCommand, sshPort)
   if err != nil {
      return fmt.Errorf("failed to install Docker on the remote server: %v", err)
   }
   fmt.Println("Docker has been installed on the remote server.")
   return nil
}
// Create an HTTP client with insecure TLS configuration
func createHTTPClient() *http.Client {
   transport := &http.Transport{
      TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
   }
   return &http.Client{Transport: transport}
}
// 安装kubectl
func installKubectl(nodeIP, sshUsername, sshPassword string, sshPort int) error {
   // 检查kubectl是否已安装
   checkCommand := "which kubectl"
   _, err := sshExec(nodeIP, sshUsername, sshPassword, checkCommand, sshPort)
   if err == nil {
      fmt.Println("kubectl is already installed on the remote server.")
      return nil
   }
   // 安装kubectl
   installCommand := "sudo curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && sudo chmod +x kubectl && sudo mv kubectl /usr/local/bin/"
   _, err = sshExec(nodeIP, sshUsername, sshPassword, installCommand, sshPort)
   if err != nil {
      return fmt.Errorf("failed to install kubectl on the remote server: %v", err)
   }
   fmt.Println("kubectl has been installed on the remote server.")
   return nil
}