func (p *Project) installOnRemote(step int, conn *ssh.Client) { // Git and some other programs can send us an unsuccessful exit (< 0) // even if the command was successfully executed on the remote shell. // On these cases, we want to ignore those errors and move onto the next step. ignoredError := "Reason was: ()" // Creates a session over the ssh connection to execute the commands session, err := conn.NewSession() if err != nil { log.Fatal("Failed to build session: ", err) } defer session.Close() var stdoutBuf bytes.Buffer session.Stdout = &stdoutBuf fmt.Println(p.typ.program.setup[step]) err = session.Run(p.typ.program.setup[step]) if err != nil && !strings.Contains(err.Error(), ignoredError) { log.Printf("Command '%s' failed on execution", p.typ.program.setup[step]) log.Fatal("Error on command execution: ", err.Error()) } }
func tailFilesOnClient(client *ssh.Client, files []string, sudo bool, linec chan<- string, errc chan<- error) { var sessions []*ssh.Session closeSessions := func() { for _, session := range sessions { _ = session.Signal(ssh.SIGKILL) _ = session.Close() } } var wg sync.WaitGroup for _, file := range files { session, err := client.NewSession() if err != nil { closeSessions() errc <- fmt.Errorf("can't open session: %v", err) return } sessions = append(sessions, session) wg.Add(1) go func(file string) { defer wg.Done() err := tailFile(session, file, sudo, linec) if err != nil { errc <- err } }(file) } wg.Wait() }
func ExecuteCmd(client *ssh.Client, command string, stdout *string, stderr *string) error { session, err := client.NewSession() if err != nil { panic("Failed to create session: " + err.Error()) } defer session.Close() //session.Setenv("PATH", "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin") //apparently needs serverside support // Once a Session is created, you can execute a single command on // the remote side using the Run method. var b bytes.Buffer var a bytes.Buffer session.Stdout = &b session.Stderr = &a log.Printf("CMD: %s\n", command) if err := session.Run(command); err != nil { return err } if stdout != nil { *stdout = b.String() } if stderr != nil { *stderr = a.String() } return err }
func scpAndRun(client ssh.Client) { scpSession, err := client.NewSession() if err != nil { panic("Failed to create SCP session: " + err.Error()) } defer scpSession.Close() scriptContents := `#!/bin/bash echo "this script is located at $dirname $0" ` scriptReader := strings.NewReader(scriptContents) scpError := copy(int64(len(scriptContents)), os.FileMode(0777), "test-script", scriptReader, "/tmp/scripts/", scpSession) if scpError != nil { panic(scpError) } execSession, err := client.NewSession() if err != nil { panic("Failed to create session: " + err.Error()) } defer execSession.Close() var stdoutBytes bytes.Buffer execSession.Stdout = &stdoutBytes if err := execSession.Run("/tmp/scripts/test-script"); err != nil { panic("Failed to run: " + err.Error()) } }
func sshExec(client *ssh.Client, cmd string) (string, string, int, error) { framework.Logf("Executing '%s' on %v", cmd, client.RemoteAddr()) session, err := client.NewSession() if err != nil { return "", "", 0, fmt.Errorf("error creating session to host %s: '%v'", client.RemoteAddr(), err) } defer session.Close() // Run the command. code := 0 var bout, berr bytes.Buffer session.Stdout, session.Stderr = &bout, &berr err = session.Run(cmd) if err != nil { // Check whether the command failed to run or didn't complete. if exiterr, ok := err.(*ssh.ExitError); ok { // If we got an ExitError and the exit code is nonzero, we'll // consider the SSH itself successful (just that the command run // errored on the host). if code = exiterr.ExitStatus(); code != 0 { err = nil } } else { // Some other kind of error happened (e.g. an IOError); consider the // SSH unsuccessful. err = fmt.Errorf("failed running `%s` on %s: '%v'", cmd, client.RemoteAddr(), err) } } return bout.String(), berr.String(), code, err }
//Execute ssh commands until "exit" is entered func runCommands(client *ssh.Client) { var cmd string for strings.ToLower(cmd) != "exit" { //Creates a new session. Only one command per session session, err := client.NewSession() if err != nil { panic("Failed to create session: " + err.Error()) } defer session.Close() fmt.Scanf("%s", &cmd) var b bytes.Buffer session.Stdout = &b err1 := session.Run(cmd) if err1 != nil { fmt.Print("You used an invalid command.") err1 = nil } fmt.Println(b.String()) } //clear the terminal and display conn closed clear := exec.Command("clear") clear.Stdout = os.Stdout clear.Run() fmt.Println("\n\nConnection Closed") }
func (n *SSHNode) getClientAndSession() (*ssh.Client, *ssh.Session, error) { var client *ssh.Client var s *ssh.Session var err error // Retry few times if ssh connection fails for i := 0; i < MaxSSHRetries; i++ { client, err = n.dial() if err != nil { time.Sleep(SSHRetryDelay) continue } s, err = client.NewSession() if err != nil { client.Close() time.Sleep(SSHRetryDelay) continue } return client, s, nil } return nil, nil, err }
func CopyLocalFileToRemote(client *ssh.Client, localFilePath string, filename string) error { // Each ClientConn can support multiple interactive sessions, // represented by a Session. session, err := client.NewSession() if err != nil { log.Fatal("Failed to create session: " + err.Error()) } defer session.Close() writer, err := session.StdinPipe() if err != nil { return err } defer writer.Close() go func() { fileContents, _ := ioutil.ReadFile(localFilePath + "/" + filename) content := string(fileContents) fmt.Fprintln(writer, "C0644", len(content), filename) fmt.Fprint(writer, content) fmt.Fprintln(writer, "\x00") // transfer end with \x00\ }() session.Run("/usr/bin/scp -t ./") return nil }
func NewClient(conn *ssh.Client, readLimitBytesPerSecond, writeLimitBytesPerSecond int64, opts ...func(*sftp.Client) error) (*sftp.Client, error) { s, err := conn.NewSession() if err != nil { return nil, err } if err := s.RequestSubsystem("sftp"); err != nil { return nil, err } pw, err := s.StdinPipe() if err != nil { return nil, err } pr, err := s.StdoutPipe() if err != nil { return nil, err } if readLimitBytesPerSecond > 0 { pr = flowrate.NewReader(pr, readLimitBytesPerSecond) } if writeLimitBytesPerSecond > 0 { pw = flowrate.NewWriter(pw, writeLimitBytesPerSecond) } return sftp.NewClientPipe(pr, pw, opts...) }
func (n *SSHNode) getClientAndSession() (*ssh.Client, *ssh.Session, error) { var client *ssh.Client var s *ssh.Session var err error // Retry few times if ssh connection fails for i := 0; i < MaxSSHRetries; i++ { client, err = n.dial() if err != nil { time.Sleep(SSHRetryDelay) continue } s, err = client.NewSession() if err != nil { client.Close() time.Sleep(SSHRetryDelay) continue } modes := ssh.TerminalModes{ ssh.ECHO: 0, ssh.TTY_OP_ISPEED: 14400, ssh.TTY_OP_OSPEED: 14400, } // Request pseudo terminal if err := s.RequestPty("xterm", 40, 80, modes); err != nil { return nil, nil, fmt.Errorf("failed to get pseudo-terminal: %v", err) } return client, s, nil } return nil, nil, err }
func sshExecNative(c conf.ServerInfo, cmd string, sudo bool) (result execResult) { result.Servername = c.ServerName result.Host = c.Host result.Port = c.Port var client *ssh.Client var err error if client, err = sshConnect(c); err != nil { result.Error = err result.ExitStatus = 999 return } defer client.Close() var session *ssh.Session if session, err = client.NewSession(); err != nil { result.Error = fmt.Errorf( "Failed to create a new session. servername: %s, err: %s", c.ServerName, err) result.ExitStatus = 999 return } defer session.Close() // http://blog.ralch.com/tutorial/golang-ssh-connection/ modes := ssh.TerminalModes{ ssh.ECHO: 0, // disable echoing ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud } if err = session.RequestPty("xterm", 400, 256, modes); err != nil { result.Error = fmt.Errorf( "Failed to request for pseudo terminal. servername: %s, err: %s", c.ServerName, err) result.ExitStatus = 999 return } var stdoutBuf, stderrBuf bytes.Buffer session.Stdout = &stdoutBuf session.Stderr = &stderrBuf cmd = decolateCmd(c, cmd, sudo) if err := session.Run(cmd); err != nil { if exitErr, ok := err.(*ssh.ExitError); ok { result.ExitStatus = exitErr.ExitStatus() } else { result.ExitStatus = 999 } } else { result.ExitStatus = 0 } result.Stdout = stdoutBuf.String() result.Stderr = stderrBuf.String() result.Cmd = strings.Replace(cmd, "\n", "", -1) return }
func RunCommand(c *ssh.Client, cmd string) error { s, err := c.NewSession() defer s.Close() if err != nil { return errors.Wrap(err, "Error creating new session for ssh client") } return s.Run(cmd) }
func RunCommand(c *ssh.Client, cmd string) error { s, err := c.NewSession() defer s.Close() if err != nil { return err } return s.Run(cmd) }
func combined(c *ssh.Client, cmd string) ([]byte, error) { s, err := c.NewSession() if err != nil { return nil, err } defer s.Close() return s.CombinedOutput(cmd) }
func createSession(client *ssh.Client) (*ssh.Session, error) { fmt.Println("Creating new session") session, err := client.NewSession() if err != nil { fmt.Println("Failed to create session") fmt.Println("Error : ", err.Error()) return nil, err } return session, nil }
// NewPty creates a new SSH session to the client using inCh as stdin, and quiting on a receive to quit. // Returns stdout, stderr channels and error channel func NewPty(client *ssh.Client, inCh <-chan []byte, quit <-chan struct{}) (<-chan []byte, <-chan []byte, <-chan error) { errCh := make(chan error, 1) // Create a new session from the given configuration func. session, err := client.NewSession() if err != nil { errCh <- err return nil, nil, nil } // Get session std in/out/err stdin, stdout, stderr, err := sessionStreams(session) if err != nil { errCh <- err return nil, nil, nil } // Stream from readers to channels stdoutCh := make(chan []byte) stderrCh := make(chan []byte) go streamToChan(stdout, stdoutCh, errCh) go streamToChan(stderr, stderrCh, errCh) // Set terminal modes modes := ssh.TerminalModes{ ssh.VREPRINT: 0, ssh.CS8: 1, ssh.ECHOE: 1, ssh.ECHOCTL: 0, } // Request pseudo terminal err = session.RequestPty("xterm", 24, 80, modes) //err = session.RequestPty("vt100", 24, 80, modes) if err != nil { errCh <- err return nil, nil, nil } // Invoke SSH shell err = session.Shell() if err != nil { errCh <- err return nil, nil, nil } // Listen for input/quit go func() { for { select { case b := <-inCh: stdin.Write(b) case <-quit: session.Close() return } } }() return stdoutCh, stderrCh, errCh }
func Mkdir(client *ssh.Client, destDir string) error { session, err := client.NewSession() if err != nil { return err } defer session.Close() err = session.Run(`bash -c "mkdir -p ` + destDir + `"`) if err != nil { return err } return nil }
func ChangeDir(client *ssh.Client, dir string) error { session, err := client.NewSession() if err != nil { return err } defer session.Close() err = session.Run(`bash -c "cd ` + dir + `"`) if err != nil { return err } return nil }
func Pwd(client *ssh.Client) (string, error) { session, err := client.NewSession() if err != nil { return "", err } defer session.Close() output, err := session.CombinedOutput(`bash -c "pwd"`) if err != nil { return "", err } return string(output), nil }
func NewSession(conn *ssh.Client, deadline *time.Time, idleTimeout int) (ss *SshSession, err error) { session, err := conn.NewSession() if err != nil { return nil, err } sshSession := new(SshSession) sshSession.session = session sshSession.deadline = deadline sshSession.idleTimeout = idleTimeout sshSession.id = Rand().Hex() //check session timeout go sshSession.checkSessionTimeout() return sshSession, nil }
func readSecret(client *ssh.Client) (string, error) { session, err := client.NewSession() if err != nil { return "", err } defer session.Close() var b bytes.Buffer session.Stdout = &b if err := session.Run("cat /etc/openvpn/secret.key"); err != nil { return "", err } return b.String(), nil }
func runRemoteCmd(client *ssh.Client, cmd string, args ...string) (string, error) { session, err := client.NewSession() if err != nil { return "", fmt.Errorf("failed to create session: %s", err) } defer session.Close() var out bytes.Buffer session.Stdout = &out session.Stderr = &out fullCmd := shellJoin(cmd, args) if err := session.Run(fullCmd); err != nil { return "", fmt.Errorf("failed to run %s: %s", fullCmd, err) } return out.String(), nil }
func sendFileToRemoteHost(client *ssh.Client, limit int64, sourceFile, targetUser, targetHost, targetFile string) { session, err := client.NewSession() if err != nil { log.Fatalln("Failed to create session: " + err.Error()) } defer session.Close() go func() { iw, err := session.StdinPipe() if err != nil { log.Fatalln("Failed to create input pipe: " + err.Error()) } w := flowrate.NewWriter(iw, limit) src, srcErr := os.Open(sourceFile) if srcErr != nil { log.Fatalln("Failed to open source file: " + srcErr.Error()) } srcStat, statErr := src.Stat() if statErr != nil { log.Fatalln("Failed to stat file: " + statErr.Error()) } fmt.Fprintln(w, "C0644", srcStat.Size(), filepath.Base(sourceFile)) if srcStat.Size() > 0 { bar := pb.New(int(srcStat.Size())) bar.Units = pb.U_BYTES bar.ShowSpeed = true bar.Start() wp := io.MultiWriter(w, bar) fmt.Printf("Transferring %s to %s@%s:%s\n", sourceFile, targetUser, targetHost, targetFile) fmt.Printf("Speed limited to %d bytes/sec\n", limit) io.Copy(wp, src) bar.Finish() fmt.Fprint(w, "\x00") w.Close() } else { fmt.Printf("Transferred empty file %s to %s@%s:%s\n", sourceFile, targetUser, targetHost, targetFile) fmt.Fprint(w, "\x00") w.Close() } }() if err := session.Run(fmt.Sprintf("scp -t %s", targetFile)); err != nil { log.Fatalln("Failed to run: " + err.Error()) } }
func executeCommand(client *ssh.Client, command string) (string, string, error) { session, err := client.NewSession() if err != nil { return "", "", err } defer session.Close() var outBuf bytes.Buffer var errBuf bytes.Buffer session.Stdout = &outBuf session.Stderr = &errBuf session.Run(command) return outBuf.String(), errBuf.String(), nil }
func runBootstrap(ssh *ssh.Client, info PathInfo, progress chan<- ProgressCmd) { type BootstrapStep struct { Description string `json:"description"` Status string `json:"status"` } status := struct { Steps []BootstrapStep `json:"steps"` }{make([]BootstrapStep, 0)} for _, cmd := range info.SSHTunnel.Bootstrap { status.Steps = append(status.Steps, BootstrapStep{cmd.Description, ""}) } for idx, cmd := range info.SSHTunnel.Bootstrap { log.Printf("Started running bootstrap '%s'", cmd.Command) status.Steps[idx].Status = "started" progress <- ProgressCmd{"bootstrap_status", status} session, _ := ssh.NewSession() defer session.Close() session.Stdout = os.Stdout session.Stderr = os.Stderr session.Run(cmd.Command) status.Steps[idx].Status = "done" progress <- ProgressCmd{"bootstrap_status", status} log.Printf("Finished running bootstrap '%s'", cmd.Command) } }
func RunCommand(client *ssh.Client, cmd string) (output string, err error) { session, err := client.NewSession() if err != nil { return "", err } defer session.Close() var b bytes.Buffer session.Stdout = &b err = session.Run(cmd) if err != nil { return "", err } return b.String(), nil }
func getFileFromRemoteHost(client *ssh.Client, localFile, targetUser, targetHost, targetFile string) { session, err := client.NewSession() if err != nil { log.Fatalln("Failed to create session: " + err.Error()) } defer session.Close() go func() { iw, err := session.StdinPipe() if err != nil { log.Fatalln("Failed to create input pipe: " + err.Error()) } or, err := session.StdoutPipe() if err != nil { log.Fatalln("Failed to create output pipe: " + err.Error()) } fmt.Fprint(iw, "\x00") sr := bufio.NewReader(or) src, srcErr := os.Create(localFile) if srcErr != nil { log.Fatalln("Failed to create source file: " + srcErr.Error()) } if controlString, ok := sr.ReadString('\n'); ok == nil && strings.HasPrefix(controlString, "C") { fmt.Fprint(iw, "\x00") controlParts := strings.Split(controlString, " ") size, _ := strconv.ParseInt(controlParts[1], 10, 64) bar := pb.New(int(size)) bar.Units = pb.U_BYTES bar.ShowSpeed = true bar.Start() rp := io.MultiReader(sr, bar) if n, ok := io.CopyN(src, rp, size); ok != nil || n < size { fmt.Println(n) fmt.Fprint(iw, "\x02") return } bar.Finish() sr.Read(make([]byte, 1)) } fmt.Fprint(iw, "\x00") }() if err := session.Run(fmt.Sprintf("scp -f %s", targetFile)); err != nil { log.Fatalln("Failed to run: " + err.Error()) } }
func Run(Con *ssh.Client, cmd string) { defer Con.Close() s, err := Con.NewSession() if err != nil { color.Red("%s:新建会话失败.命令未执行.", Con.RemoteAddr()) return } fmt.Printf("成功连接:%s\n", Con.RemoteAddr()) buf, err := s.Output(cmd) if err != nil { color.Red("%s:命令执行失败.", Con.RemoteAddr()) return } str := fmt.Sprintf("%s 的执行结果:\n%s\n", Con.RemoteAddr().String(), string(buf)) fmt.Println(str) Result <- str }
func runCommand( sshClient *ssh.Client, cmd string, execTimeout time.Duration, ) (string, error) { session, err := sshClient.NewSession() if err != nil { return "", err } defer session.Close() termModes := ssh.TerminalModes{ ssh.ECHO: 0, // do not echo ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud } if err := session.RequestPty("xterm", 80, 40, termModes); err != nil { return "", err } stdinBuf, stdoutBuf, stderrBuf := new(bytes.Buffer), new(bytes.Buffer), new(bytes.Buffer) session.Stdin = stdinBuf session.Stdout = stdoutBuf session.Stderr = stderrBuf outputChan := make(chan string) errChan := make(chan error) go func() { if err := session.Run(cmd); err != nil { errChan <- fmt.Errorf("%v, %s", err, stderrBuf.String()) return } outputChan <- stdoutBuf.String() }() select { case output := <-outputChan: return output, nil case err := <-errChan: return "", err case <-time.After(execTimeout): return "", fmt.Errorf("execution timeout.") } }
// NewClient creates a new SFTP client on conn, using zero or more option // functions. func NewClient(conn *ssh.Client, opts ...func(*Client) error) (*Client, error) { s, err := conn.NewSession() if err != nil { return nil, err } if err := s.RequestSubsystem("sftp"); err != nil { return nil, err } pw, err := s.StdinPipe() if err != nil { return nil, err } pr, err := s.StdoutPipe() if err != nil { return nil, err } return NewClientPipe(pr, pw, opts...) }