Skip to content
This repository was archived by the owner on Jul 30, 2021. It is now read-only.

Commit 3ccb3c4

Browse files
author
Patrick Baxter
committed
e2e: add ability to drop out of test and into SSH shell
The ergonomics could be improved a bit (not all tests have ready access to the list of hostnames), but that is more in-scope for other framework-ish cleanups.
1 parent 14add7e commit 3ccb3c4

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

e2e/ssh_client.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ package e2e
22

33
import (
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

1416
type 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

Comments
 (0)