| | |
| | | package util |
| | | |
| | | import "os" |
| | | import ( |
| | | "context" |
| | | "crypto/tls" |
| | | "fmt" |
| | | "net/http" |
| | | "os" |
| | | "time" |
| | | |
| | | "golang.org/x/crypto/ssh" |
| | | ) |
| | | |
| | | // homeDir 获取当前用户的家目录路径 |
| | | func homeDir() string { |
| | |
| | | } |
| | | 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 |
| | | } |