Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit76bdde7

Browse files
authored
fix(agent): Prevent SSH TTYs from losing command output on exit (#6777)
1 parentd7d210d commit76bdde7

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

‎agent/agent.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,7 @@ func (a *agent) init(ctx context.Context) {
844844
_=session.Exit(MagicSessionErrorCode)
845845
return
846846
}
847+
_=session.Exit(0)
847848
},
848849
HostSigners: []ssh.Signer{randomSigner},
849850
LocalPortForwardingCallback:func(ctx ssh.Context,destinationHoststring,destinationPortuint32)bool {
@@ -1100,7 +1101,9 @@ func (a *agent) handleSSHSession(session ssh.Session) (retErr error) {
11001101
iferr!=nil {
11011102
returnxerrors.Errorf("start command: %w",err)
11021103
}
1104+
varwg sync.WaitGroup
11031105
deferfunc() {
1106+
deferwg.Wait()
11041107
closeErr:=ptty.Close()
11051108
ifcloseErr!=nil {
11061109
a.logger.Warn(ctx,"failed to close tty",slog.Error(closeErr))
@@ -1117,10 +1120,16 @@ func (a *agent) handleSSHSession(session ssh.Session) (retErr error) {
11171120
}
11181121
}
11191122
}()
1123+
// We don't add input copy to wait group because
1124+
// it won't return until the session is closed.
11201125
gofunc() {
11211126
_,_=io.Copy(ptty.Input(),session)
11221127
}()
1128+
wg.Add(1)
11231129
gofunc() {
1130+
// Ensure data is flushed to session on command exit, if we
1131+
// close the session too soon, we might lose data.
1132+
deferwg.Done()
11241133
_,_=io.Copy(session,ptty.Output())
11251134
}()
11261135
err=process.Wait()

‎agent/agent_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,57 @@ func TestAgent_Session_TTY_Hushlogin(t *testing.T) {
348348
require.NotContains(t,stdout.String(),wantNotMOTD,"should not show motd")
349349
}
350350

351+
funcTestAgent_Session_TTY_FastCommandHasOutput(t*testing.T) {
352+
t.Parallel()
353+
ifruntime.GOOS=="windows" {
354+
// This might be our implementation, or ConPTY itself.
355+
// It's difficult to find extensive tests for it, so
356+
// it seems like it could be either.
357+
t.Skip("ConPTY appears to be inconsistent on Windows.")
358+
}
359+
360+
// This test is here to prevent regressions where quickly executing
361+
// commands (with TTY) don't flush their output to the SSH session.
362+
//
363+
// See: https://github.com/coder/coder/issues/6656
364+
ctx,cancel:=context.WithTimeout(context.Background(),testutil.WaitLong)
365+
defercancel()
366+
//nolint:dogsled
367+
conn,_,_,_,_:=setupAgent(t, agentsdk.Metadata{},0)
368+
sshClient,err:=conn.SSHClient(ctx)
369+
require.NoError(t,err)
370+
defersshClient.Close()
371+
372+
ptty:=ptytest.New(t)
373+
374+
varstdout bytes.Buffer
375+
// NOTE(mafredri): Increase iterations to increase chance of failure,
376+
// assuming bug is present.
377+
// Using 1000 iterations is basically a guaranteed failure (but let's
378+
// not increase test times needlessly).
379+
fori:=0;i<5;i++ {
380+
func() {
381+
stdout.Reset()
382+
383+
session,err:=sshClient.NewSession()
384+
require.NoError(t,err)
385+
defersession.Close()
386+
err=session.RequestPty("xterm",128,128, ssh.TerminalModes{})
387+
require.NoError(t,err)
388+
389+
session.Stdout=&stdout
390+
session.Stderr=ptty.Output()
391+
session.Stdin=ptty.Input()
392+
err=session.Start("echo wazzup")
393+
require.NoError(t,err)
394+
395+
err=session.Wait()
396+
require.NoError(t,err)
397+
require.Contains(t,stdout.String(),"wazzup","should output greeting")
398+
}()
399+
}
400+
}
401+
351402
//nolint:paralleltest // This test reserves a port.
352403
funcTestAgent_TCPLocalForwarding(t*testing.T) {
353404
random,err:=net.Listen("tcp","127.0.0.1:0")

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp