Skip to content
This repository was archived by the owner on Nov 27, 2023. It is now read-only.

Commit ee4e85a

Browse files
authored
Merge pull request #1462 from docker/rawTerminal
set terminal in character mode when attached to a container
2 parents d13bc95 + d4a8e92 commit ee4e85a

File tree

5 files changed

+44
-14
lines changed

5 files changed

+44
-14
lines changed

api/compose/api.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,8 @@ type RunOptions struct {
186186
Entrypoint []string
187187
Detach bool
188188
AutoRemove bool
189-
Writer io.Writer
190-
Reader io.Reader
189+
Writer io.WriteCloser
190+
Reader io.ReadCloser
191191
Tty bool
192192
WorkingDir string
193193
User string

local/compose/attach.go

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/docker/compose-cli/utils"
2828

2929
"github.com/compose-spec/compose-go/types"
30+
"github.com/docker/cli/cli/streams"
3031
moby "github.com/docker/docker/api/types"
3132
"github.com/docker/docker/pkg/stdcopy"
3233
)
@@ -108,26 +109,40 @@ func (s *composeService) attachContainer(ctx context.Context, container moby.Con
108109
Service: container.Labels[serviceLabel],
109110
})
110111

111-
return s.attachContainerStreams(ctx, container.ID, service.Tty, nil, w)
112+
_, err = s.attachContainerStreams(ctx, container.ID, service.Tty, nil, w)
113+
return err
112114
}
113115

114-
func (s *composeService) attachContainerStreams(ctx context.Context, container string, tty bool, r io.Reader, w io.Writer) error {
116+
func (s *composeService) attachContainerStreams(ctx context.Context, container string, tty bool, r io.ReadCloser, w io.Writer) (func(), error) {
117+
var (
118+
in *streams.In
119+
restore = func() { /* noop */ }
120+
)
121+
if r != nil {
122+
in = streams.NewIn(r)
123+
restore = in.RestoreTerminal
124+
}
125+
115126
stdin, stdout, err := s.getContainerStreams(ctx, container)
116127
if err != nil {
117-
return err
128+
return restore, err
118129
}
119130

120131
go func() {
121132
<-ctx.Done()
122-
stdout.Close() //nolint:errcheck
123-
if stdin != nil {
124-
stdin.Close() //nolint:errcheck
133+
if in != nil {
134+
in.Close() //nolint:errcheck
125135
}
136+
stdout.Close() //nolint:errcheck
126137
}()
127138

128-
if r != nil && stdin != nil {
139+
if in != nil && stdin != nil {
140+
err := in.SetRawTerminal()
141+
if err != nil {
142+
return restore, err
143+
}
129144
go func() {
130-
io.Copy(stdin, r) //nolint:errcheck
145+
io.Copy(stdin, in) //nolint:errcheck
131146
}()
132147
}
133148

@@ -140,7 +155,7 @@ func (s *composeService) attachContainerStreams(ctx context.Context, container s
140155
}
141156
}()
142157
}
143-
return nil
158+
return restore, nil
144159
}
145160

146161
func (s *composeService) getContainerStreams(ctx context.Context, container string) (io.WriteCloser, io.ReadCloser, error) {

local/compose/create.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ func (s *composeService) getCreateOptions(ctx context.Context, p *types.Project,
249249
ExposedPorts: buildContainerPorts(service),
250250
Tty: tty,
251251
OpenStdin: stdinOpen,
252-
StdinOnce: true,
252+
StdinOnce: attachStdin && stdinOpen,
253253
AttachStdin: attachStdin,
254254
AttachStderr: true,
255255
AttachStdout: true,

local/compose/run.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,11 @@ func (s *composeService) RunOneOffContainer(ctx context.Context, project *types.
8686
return 0, err
8787
}
8888
oneoffContainer := containers[0]
89-
err = s.attachContainerStreams(ctx, oneoffContainer.ID, service.Tty, opts.Reader, opts.Writer)
89+
restore, err := s.attachContainerStreams(ctx, oneoffContainer.ID, service.Tty, opts.Reader, opts.Writer)
9090
if err != nil {
9191
return 0, err
9292
}
93+
defer restore()
9394

9495
err = s.apiClient.ContainerStart(ctx, containerID, apitypes.ContainerStartOptions{})
9596
if err != nil {

utils/logs.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func (a *allowListLogConsumer) Register(name string) {
6262
}
6363

6464
// GetWriter creates a io.Writer that will actually split by line and format by LogConsumer
65-
func GetWriter(container, service string, events compose.ContainerEventListener) io.Writer {
65+
func GetWriter(container, service string, events compose.ContainerEventListener) io.WriteCloser {
6666
return &splitBuffer{
6767
buffer: bytes.Buffer{},
6868
service: service,
@@ -100,3 +100,17 @@ func (s *splitBuffer) Write(b []byte) (int, error) {
100100
}
101101
return n, nil
102102
}
103+
104+
func (s *splitBuffer) Close() error {
105+
b := s.buffer.Bytes()
106+
if len(b) == 0 {
107+
return nil
108+
}
109+
s.consumer(compose.ContainerEvent{
110+
Type: compose.ContainerEventLog,
111+
Service: s.service,
112+
Container: s.container,
113+
Line: string(b),
114+
})
115+
return nil
116+
}

0 commit comments

Comments
 (0)