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

Commit 31e9396

Browse files
authored
Merge pull request #1512 from docker/resize
resize terminal and monitor SIGWINCH
2 parents 5841e75 + be5d78a commit 31e9396

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed

local/compose/exec.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,13 @@ func (s *composeService) Exec(ctx context.Context, project *types.Project, opts
8282
}
8383
defer resp.Close()
8484

85+
if opts.Tty {
86+
err := s.monitorTTySize(ctx, exec.ID, s.apiClient.ContainerExecResize)
87+
if err != nil {
88+
return err
89+
}
90+
}
91+
8592
readChannel := make(chan error, 10)
8693
writeChannel := make(chan error, 10)
8794

local/compose/resize.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
Copyright 2020 Docker Compose CLI authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package compose
18+
19+
import (
20+
"context"
21+
"os"
22+
gosignal "os/signal"
23+
"runtime"
24+
"time"
25+
26+
"github.com/buger/goterm"
27+
moby "github.com/docker/docker/api/types"
28+
"github.com/docker/docker/pkg/signal"
29+
)
30+
31+
func (s *composeService) monitorTTySize(ctx context.Context, container string, resize func(context.Context, string, moby.ResizeOptions) error) error {
32+
err := resize(ctx, container, moby.ResizeOptions{ // nolint:errcheck
33+
Height: uint(goterm.Height()),
34+
Width: uint(goterm.Width()),
35+
})
36+
if err != nil {
37+
return err
38+
}
39+
40+
sigchan := make(chan os.Signal, 1)
41+
gosignal.Notify(sigchan, signal.SIGWINCH)
42+
43+
if runtime.GOOS == "windows" {
44+
// Windows has no SIGWINCH support, so we have to poll tty size ¯\_(ツ)_/¯
45+
go func() {
46+
prevH := goterm.Height()
47+
prevW := goterm.Width()
48+
for {
49+
time.Sleep(time.Millisecond * 250)
50+
h := goterm.Height()
51+
w := goterm.Width()
52+
if prevW != w || prevH != h {
53+
sigchan <- signal.SIGWINCH
54+
}
55+
prevH = h
56+
prevW = w
57+
}
58+
}()
59+
}
60+
61+
go func() {
62+
for {
63+
select {
64+
case <-sigchan:
65+
resize(ctx, container, moby.ResizeOptions{ // nolint:errcheck
66+
Height: uint(goterm.Height()),
67+
Width: uint(goterm.Width()),
68+
})
69+
case <-ctx.Done():
70+
return
71+
}
72+
}
73+
}()
74+
return nil
75+
}

local/compose/run.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ func (s *composeService) RunOneOffContainer(ctx context.Context, project *types.
9494
return 0, err
9595
}
9696

97+
err = s.monitorTTySize(ctx, containerID, s.apiClient.ContainerResize)
98+
if err != nil {
99+
return 0, err
100+
}
101+
97102
statusC, errC := s.apiClient.ContainerWait(context.Background(), oneoffContainer.ID, container.WaitConditionNotRunning)
98103
select {
99104
case status := <-statusC:

0 commit comments

Comments
 (0)