Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 503d09c

Browse files
authored
feat: Add support for executing processes with Windows ConPty (#311)
* Initial agent * fix: Use buffered reader in peer to fix ShortBuffer This prevents a io.ErrShortBuffer from occurring when the byte slice being read is smaller than the chunks sent from the opposite pipe. This makes sense for unordered connections, where transmission is not guarunteed, but does not make sense for TCP-like connections. We use a bufio.Reader when ordered to ensure data isn't lost. * SSH server works! * Start Windows support * Something works * Refactor pty package to support Windows spawn * SSH server now works on Windows * Fix non-Windows * Fix Linux PTY render * FIx linux build tests * Remove agent and wintest * Add test for Windows resize * Fix linting errors * Add Windows environment variables * Add strings import * Add comment for attrs * Add goleak * Add require import
1 parent c2ad91b commit 503d09c

32 files changed

+582
-1140
lines changed

.vscode/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"drpcserver",
3434
"fatih",
3535
"goleak",
36+
"gossh",
3637
"hashicorp",
3738
"httpmw",
3839
"isatty",
@@ -51,9 +52,12 @@
5152
"protobuf",
5253
"provisionerd",
5354
"provisionersdk",
55+
"ptty",
56+
"ptytest",
5457
"retrier",
5558
"sdkproto",
5659
"stretchr",
60+
"tcpip",
5761
"tfexec",
5862
"tfstate",
5963
"unconvert",

cli/clitest/clitest_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88

99
"github.com/coder/coder/cli/clitest"
1010
"github.com/coder/coder/coderd/coderdtest"
11-
"github.com/coder/coder/console"
11+
"github.com/coder/coder/pty/ptytest"
1212
)
1313

1414
func TestMain(m *testing.M) {
@@ -21,11 +21,12 @@ func TestCli(t *testing.T) {
2121
client := coderdtest.New(t)
2222
cmd, config := clitest.New(t)
2323
clitest.SetupConfig(t, client, config)
24-
cons := console.New(t, cmd)
24+
pty := ptytest.New(t)
25+
cmd.SetIn(pty.Input())
26+
cmd.SetOut(pty.Output())
2527
go func() {
2628
err := cmd.Execute()
2729
require.NoError(t, err)
2830
}()
29-
_, err := cons.ExpectString("coder")
30-
require.NoError(t, err)
31+
pty.ExpectMatch("coder")
3132
}

cli/login_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ package cli_test
33
import (
44
"testing"
55

6+
"github.com/stretchr/testify/require"
7+
68
"github.com/coder/coder/cli/clitest"
79
"github.com/coder/coder/coderd/coderdtest"
8-
"github.com/coder/coder/console"
9-
"github.com/stretchr/testify/require"
10+
"github.com/coder/coder/pty/ptytest"
1011
)
1112

1213
func TestLogin(t *testing.T) {
@@ -26,7 +27,9 @@ func TestLogin(t *testing.T) {
2627
// accurately detect Windows ptys when they are not attached to a process:
2728
// https://github.com/mattn/go-isatty/issues/59
2829
root, _ := clitest.New(t, "login", client.URL.String(), "--force-tty")
29-
cons := console.New(t, root)
30+
pty := ptytest.New(t)
31+
root.SetIn(pty.Input())
32+
root.SetOut(pty.Output())
3033
go func() {
3134
err := root.Execute()
3235
require.NoError(t, err)
@@ -42,12 +45,9 @@ func TestLogin(t *testing.T) {
4245
for i := 0; i < len(matches); i += 2 {
4346
match := matches[i]
4447
value := matches[i+1]
45-
_, err := cons.ExpectString(match)
46-
require.NoError(t, err)
47-
_, err = cons.SendLine(value)
48-
require.NoError(t, err)
48+
pty.ExpectMatch(match)
49+
pty.WriteLine(value)
4950
}
50-
_, err := cons.ExpectString("Welcome to Coder")
51-
require.NoError(t, err)
51+
pty.ExpectMatch("Welcome to Coder")
5252
})
5353
}

cli/projectcreate_test.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import (
77

88
"github.com/coder/coder/cli/clitest"
99
"github.com/coder/coder/coderd/coderdtest"
10-
"github.com/coder/coder/console"
1110
"github.com/coder/coder/database"
1211
"github.com/coder/coder/provisioner/echo"
1312
"github.com/coder/coder/provisionersdk/proto"
13+
"github.com/coder/coder/pty/ptytest"
1414
)
1515

1616
func TestProjectCreate(t *testing.T) {
@@ -26,7 +26,9 @@ func TestProjectCreate(t *testing.T) {
2626
cmd, root := clitest.New(t, "projects", "create", "--directory", source, "--provisioner", string(database.ProvisionerTypeEcho))
2727
clitest.SetupConfig(t, client, root)
2828
_ = coderdtest.NewProvisionerDaemon(t, client)
29-
console := console.New(t, cmd)
29+
pty := ptytest.New(t)
30+
cmd.SetIn(pty.Input())
31+
cmd.SetOut(pty.Output())
3032
closeChan := make(chan struct{})
3133
go func() {
3234
err := cmd.Execute()
@@ -43,10 +45,8 @@ func TestProjectCreate(t *testing.T) {
4345
for i := 0; i < len(matches); i += 2 {
4446
match := matches[i]
4547
value := matches[i+1]
46-
_, err := console.ExpectString(match)
47-
require.NoError(t, err)
48-
_, err = console.SendLine(value)
49-
require.NoError(t, err)
48+
pty.ExpectMatch(match)
49+
pty.WriteLine(value)
5050
}
5151
<-closeChan
5252
})
@@ -73,7 +73,9 @@ func TestProjectCreate(t *testing.T) {
7373
cmd, root := clitest.New(t, "projects", "create", "--directory", source, "--provisioner", string(database.ProvisionerTypeEcho))
7474
clitest.SetupConfig(t, client, root)
7575
coderdtest.NewProvisionerDaemon(t, client)
76-
cons := console.New(t, cmd)
76+
pty := ptytest.New(t)
77+
cmd.SetIn(pty.Input())
78+
cmd.SetOut(pty.Output())
7779
closeChan := make(chan struct{})
7880
go func() {
7981
err := cmd.Execute()
@@ -91,10 +93,8 @@ func TestProjectCreate(t *testing.T) {
9193
for i := 0; i < len(matches); i += 2 {
9294
match := matches[i]
9395
value := matches[i+1]
94-
_, err := cons.ExpectString(match)
95-
require.NoError(t, err)
96-
_, err = cons.SendLine(value)
97-
require.NoError(t, err)
96+
pty.ExpectMatch(match)
97+
pty.WriteLine(value)
9898
}
9999
<-closeChan
100100
})

cli/root.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"github.com/manifoldco/promptui"
1313
"github.com/mattn/go-isatty"
1414
"github.com/spf13/cobra"
15-
"golang.org/x/xerrors"
1615

1716
"github.com/coder/coder/cli/config"
1817
"github.com/coder/coder/coderd"
@@ -138,14 +137,9 @@ func isTTY(cmd *cobra.Command) bool {
138137
}
139138

140139
func prompt(cmd *cobra.Command, prompt *promptui.Prompt) (string, error) {
141-
var ok bool
142-
prompt.Stdin, ok = cmd.InOrStdin().(io.ReadCloser)
143-
if !ok {
144-
return "", xerrors.New("stdin must be a readcloser")
145-
}
146-
prompt.Stdout, ok = cmd.OutOrStdout().(io.WriteCloser)
147-
if !ok {
148-
return "", xerrors.New("stdout must be a readcloser")
140+
prompt.Stdin = io.NopCloser(cmd.InOrStdin())
141+
prompt.Stdout = readWriteCloser{
142+
Writer: cmd.OutOrStdout(),
149143
}
150144

151145
// The prompt library displays defaults in a jarring way for the user
@@ -199,3 +193,10 @@ func prompt(cmd *cobra.Command, prompt *promptui.Prompt) (string, error) {
199193

200194
return value, err
201195
}
196+
197+
// readWriteCloser fakes reads, writes, and closing!
198+
type readWriteCloser struct {
199+
io.Reader
200+
io.Writer
201+
io.Closer
202+
}

cli/workspacecreate_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ package cli_test
33
import (
44
"testing"
55

6+
"github.com/stretchr/testify/require"
7+
68
"github.com/coder/coder/cli/clitest"
79
"github.com/coder/coder/coderd/coderdtest"
8-
"github.com/coder/coder/console"
910
"github.com/coder/coder/provisioner/echo"
1011
"github.com/coder/coder/provisionersdk/proto"
11-
"github.com/stretchr/testify/require"
12+
"github.com/coder/coder/pty/ptytest"
1213
)
1314

1415
func TestWorkspaceCreate(t *testing.T) {
@@ -36,7 +37,9 @@ func TestWorkspaceCreate(t *testing.T) {
3637
cmd, root := clitest.New(t, "workspaces", "create", project.Name)
3738
clitest.SetupConfig(t, client, root)
3839

39-
cons := console.New(t, cmd)
40+
pty := ptytest.New(t)
41+
cmd.SetIn(pty.Input())
42+
cmd.SetOut(pty.Output())
4043
closeChan := make(chan struct{})
4144
go func() {
4245
err := cmd.Execute()
@@ -51,13 +54,10 @@ func TestWorkspaceCreate(t *testing.T) {
5154
for i := 0; i < len(matches); i += 2 {
5255
match := matches[i]
5356
value := matches[i+1]
54-
_, err := cons.ExpectString(match)
55-
require.NoError(t, err)
56-
_, err = cons.SendLine(value)
57-
require.NoError(t, err)
57+
pty.ExpectMatch(match)
58+
pty.WriteLine(value)
5859
}
59-
_, err := cons.ExpectString("Create")
60-
require.NoError(t, err)
60+
pty.ExpectMatch("Create")
6161
<-closeChan
6262
})
6363
}

coderd/projectimport_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import (
55
"net/http"
66
"testing"
77

8+
"github.com/stretchr/testify/require"
9+
810
"github.com/coder/coder/coderd"
911
"github.com/coder/coder/coderd/coderdtest"
1012
"github.com/coder/coder/codersdk"
1113
"github.com/coder/coder/database"
1214
"github.com/coder/coder/provisioner/echo"
1315
"github.com/coder/coder/provisionersdk/proto"
14-
"github.com/stretchr/testify/require"
1516
)
1617

1718
func TestPostProjectImportByOrganization(t *testing.T) {

codersdk/projectimport_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ import (
55
"testing"
66
"time"
77

8+
"github.com/google/uuid"
9+
"github.com/stretchr/testify/require"
10+
811
"github.com/coder/coder/coderd"
912
"github.com/coder/coder/coderd/coderdtest"
1013
"github.com/coder/coder/provisioner/echo"
1114
"github.com/coder/coder/provisionersdk/proto"
12-
"github.com/google/uuid"
13-
"github.com/stretchr/testify/require"
1415
)
1516

1617
func TestCreateProjectImportJob(t *testing.T) {

console/conpty/conpty.go

Lines changed: 0 additions & 107 deletions
This file was deleted.

0 commit comments

Comments
 (0)