func configureSessionIO(session *ssh.Session) error { fmt.Println("Requesting Pseudo Terminal") if err := session.RequestPty("xterm", 80, 40, modes); err != nil { fmt.Println("Unable to request Pseudo Terminal") fmt.Println("Error : ", err.Error()) return err } fmt.Println("Setting up STDIN") stdin, err := session.StdinPipe() if err != nil { fmt.Println("Unable to setup STDIN") fmt.Println("Error : ", err.Error()) return err } go io.Copy(stdin, os.Stdin) fmt.Println("Setting up STDOUT") stdout, err := session.StdoutPipe() if err != nil { fmt.Println("Unable to setup STDOUT") fmt.Println("Error : ", err.Error()) return err } go io.Copy(os.Stdout, stdout) fmt.Println("Setting up STDERR") stderr, err := session.StderrPipe() if err != nil { fmt.Println("Unable to setup STDERR") fmt.Println("Error : ", err.Error()) return err } go io.Copy(os.Stderr, stderr) return nil }
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 }
// RunCommand runs a shell command in a vagrant node and returns it's exit status func (n *VagrantNode) RunCommand(cmd string) error { var ( s *ssh.Session err error ) if s, err = n.client.NewSession(); err != nil { return err } defer s.Close() if err := s.RequestPty("vt100", 80, 25, ssh.TerminalModes{}); err != nil { fmt.Println(err) return err } return s.Run(newCmdStrWithSource(cmd)) }
func (sshTransport *SSHTransport) execCmd(session *ssh.Session, cmd string) (*bytes.Buffer, error) { modes := ssh.TerminalModes{ ECHO: 0, TTY_OP_ISPEED: 14400, TTY_OP_OSPEED: 14400, } if err := session.RequestPty("xterm", 100, 80, modes); err != nil { return nil, HenchErr(err, nil, "request for psuedo terminal failed") } var stdoutbuf bytes.Buffer session.Stdout = &stdoutbuf err := session.Run(cmd) if err != nil { return nil, HenchErr(err, map[string]interface{}{ "output": string(stdoutbuf.String()), }, "While retrieving output from ssh") } return &stdoutbuf, nil }
Expect(err).NotTo(HaveOccurred()) Expect(stdoutBytes).NotTo(ContainSubstring("ENV3")) }) }) }) Context("when a pty request is received", func() { var terminalModes ssh.TerminalModes BeforeEach(func() { terminalModes = ssh.TerminalModes{} }) JustBeforeEach(func() { err := session.RequestPty("vt100", 43, 80, terminalModes) Expect(err).NotTo(HaveOccurred()) }) It("should allocate a tty for the session", func() { result, err := session.Output("tty") Expect(err).NotTo(HaveOccurred()) Expect(result).NotTo(ContainSubstring("not a tty")) }) It("returns when the process exits", func() { stdin, err := session.StdinPipe() Expect(err).NotTo(HaveOccurred()) err = session.Run("ls")
func sshExecNative(c conf.ServerInfo, cmd string, sudo bool, log ...*logrus.Entry) (result sshResult) { logger := getSSHLogger(log...) cmd = decolateCmd(c, cmd, sudo) logger.Debugf("Command: %s", strings.Replace(maskPassword(cmd, c.Password), "\n", "", -1)) var client *ssh.Client var err error client, err = sshConnect(c) defer client.Close() var session *ssh.Session if session, err = client.NewSession(); err != nil { logger.Errorf("Failed to new session. err: %s, c: %s", err, pp.Sprintf("%v", c)) 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 { logger.Errorf("Failed to request for pseudo terminal. err: %s, c: %s", err, pp.Sprintf("%v", c)) result.ExitStatus = 999 return } var stdoutBuf, stderrBuf bytes.Buffer session.Stdout = &stdoutBuf session.Stderr = &stderrBuf 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.Host = c.Host result.Port = c.Port logger.Debugf( "SSH executed. cmd: %s, err: %#v, status: %d\nstdout: \n%s\nstderr: \n%s", maskPassword(cmd, c.Password), err, result.ExitStatus, result.Stdout, result.Stderr) return }