@@ -2,13 +2,15 @@ package e2e
22
33import (
44 "bytes"
5+ "fmt"
56 "io/ioutil"
67 "log"
78 "net"
89 "os"
910
1011 "golang.org/x/crypto/ssh"
1112 "golang.org/x/crypto/ssh/agent"
13+ "golang.org/x/crypto/ssh/terminal"
1214)
1315
1416type SSHClient struct {
@@ -79,3 +81,58 @@ func (c *SSHClient) SSH(host, cmd string) (stdout, stderr []byte, err error) {
7981
8082 return stdout , stderr , err
8183}
84+
85+ // Manhole connects os.Stdin, os.Stdout, and os.Stderr to an interactive shell
86+ // session on the Machine m. Manhole blocks until the shell session has ended.
87+ // If os.Stdin does not refer to a TTY, Manhole returns immediately with a nil
88+ // error. Copied from github.com/coreos/mantle/platform/util.go
89+ func (c * SSHClient ) Manhole (host string ) error {
90+ fd := int (os .Stdin .Fd ())
91+ if ! terminal .IsTerminal (fd ) {
92+ return nil
93+ }
94+
95+ tstate , _ := terminal .MakeRaw (fd )
96+ defer terminal .Restore (fd , tstate )
97+
98+ client , err := ssh .Dial ("tcp" , host + ":22" , c .ClientConfig )
99+ if err != nil {
100+ return err
101+ }
102+ defer client .Close ()
103+
104+ session , err := client .NewSession ()
105+ if err != nil {
106+ return fmt .Errorf ("SSH session failed: %v" , err )
107+ }
108+
109+ defer session .Close ()
110+
111+ session .Stdin = os .Stdin
112+ session .Stdout = os .Stdout
113+ session .Stderr = os .Stderr
114+
115+ modes := ssh.TerminalModes {
116+ ssh .TTY_OP_ISPEED : 115200 ,
117+ ssh .TTY_OP_OSPEED : 115200 ,
118+ }
119+
120+ cols , lines , err := terminal .GetSize (int (os .Stdin .Fd ()))
121+ if err != nil {
122+ return err
123+ }
124+
125+ if err = session .RequestPty (os .Getenv ("TERM" ), lines , cols , modes ); err != nil {
126+ return fmt .Errorf ("failed to request pseudo terminal: %s" , err )
127+ }
128+
129+ if err := session .Shell (); err != nil {
130+ return fmt .Errorf ("failed to start shell: %s" , err )
131+ }
132+
133+ if err := session .Wait (); err != nil {
134+ return fmt .Errorf ("failed to wait for session: %s" , err )
135+ }
136+
137+ return nil
138+ }
0 commit comments