目的:在go语言中ssh连接服务器,上传shell文件并执行
代码:
import "golang.org/x/crypto/ssh"
func InitHardware(username string, password string, ip string, ipv6 string, port int, arch string, ipStack string, classType string, classVersion string) error {logger.Debug("start InitHardware:", ip, port)installBootstrap := "xxx.sh" //自己的脚本文件名fullpath := path.Join(util.GetRootDir(), "sbin", installBootstrap) //脚本文件所在目录installBootstrapUrl := configure.GetBootstrapPackageUrl()if arch == "aarch64" { //判断机器架构以便替换文件urlinstallBootstrapUrl = strings.Replace(installBootstrapUrl, "/x86_64/", "/aarch64/", 1)}//连接配置config := &ssh.ClientConfig{User: username,Auth: []ssh.AuthMethod{ssh.Password(password),},HostKeyCallback: ssh.InsecureIgnoreHostKey(),}if len(ipv6) > 0 && ipv6 != "" {ip = "[" + ipv6 + "]"}conn, err := ssh.Dial("tcp", ip+":"+strconv.Itoa(port), config)if err != nil {return err}defer func(conn *ssh.Client) {err := conn.Close()if err != nil {}}(conn)session, err := conn.NewSession()if err != nil {return err}defer func(session *ssh.Session) {err := session.Close()if err != nil {}}(session)// 执行 "echo $HOME" 命令以获取用户目录var stdoutBuf strings.Buildersession.Stdout = &stdoutBuferr = session.Run("echo $HOME")if err != nil {logger.Errorf("get user dir, error: error=%s", err)return err}// 获取用户目录并删除末尾的换行符userDir := strings.TrimSpace(stdoutBuf.String())contents, err := os.ReadFile(fullpath)if err != nil {logger.Errorf("read shell file, error: fullpath=%s, error=%s", fullpath, err)return err}// 上传 shell 文件到远程服务器remoteShellFile := path.Join(userDir, installBootstrap)session1, err := conn.NewSession()if err != nil {return err}defer session1.Close()var b bytes.Buffersession1.Stdout = &berr = session1.Run(fmt.Sprintf("echo '%s' > %s", contents, remoteShellFile))if err != nil {logger.Errorf("upload shell file, error: remoteShellFile=%s, error=%s", remoteShellFile, err)return err}session2, err := conn.NewSession()if err != nil {return err}defer func(session2 *ssh.Session) {err := session2.Close()if err != nil {}}(session2)session2.Stdout = os.Stdoutsession2.Stderr = os.Stderrlogger.Infof("==========ipv6test==========")logger.Infof(fmt.Sprintf("sh %s %s %s %s %s %s", remoteShellFile, installBootstrapUrl, woodpeckerRpc, cmdRpc, emsRpc, ipStack))err = session2.Run(fmt.Sprintf("sh %s %s %s %s %s %s %s %s", remoteShellFile, installBootstrapUrl, woodpeckerRpc, cmdRpc, emsRpc, ipStack, classType, classVersion))if err != nil {logger.Errorf("InitHardware ip:%s, error: ", ip, session2.Stderr)return err}return nil
}