Bladeren bron

Merge pull request #1512 from docker/resize

resize terminal and monitor SIGWINCH
Nicolas De loof 4 jaren geleden
bovenliggende
commit
31e93963f7
3 gewijzigde bestanden met toevoegingen van 87 en 0 verwijderingen
  1. 7 0
      local/compose/exec.go
  2. 75 0
      local/compose/resize.go
  3. 5 0
      local/compose/run.go

+ 7 - 0
local/compose/exec.go

@@ -82,6 +82,13 @@ func (s *composeService) Exec(ctx context.Context, project *types.Project, opts
 	}
 	defer resp.Close()
 
+	if opts.Tty {
+		err := s.monitorTTySize(ctx, exec.ID, s.apiClient.ContainerExecResize)
+		if err != nil {
+			return err
+		}
+	}
+
 	readChannel := make(chan error, 10)
 	writeChannel := make(chan error, 10)
 

+ 75 - 0
local/compose/resize.go

@@ -0,0 +1,75 @@
+/*
+   Copyright 2020 Docker Compose CLI authors
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+package compose
+
+import (
+	"context"
+	"os"
+	gosignal "os/signal"
+	"runtime"
+	"time"
+
+	"github.com/buger/goterm"
+	moby "github.com/docker/docker/api/types"
+	"github.com/docker/docker/pkg/signal"
+)
+
+func (s *composeService) monitorTTySize(ctx context.Context, container string, resize func(context.Context, string, moby.ResizeOptions) error) error {
+	err := resize(ctx, container, moby.ResizeOptions{ // nolint:errcheck
+		Height: uint(goterm.Height()),
+		Width:  uint(goterm.Width()),
+	})
+	if err != nil {
+		return err
+	}
+
+	sigchan := make(chan os.Signal, 1)
+	gosignal.Notify(sigchan, signal.SIGWINCH)
+
+	if runtime.GOOS == "windows" {
+		// Windows has no SIGWINCH support, so we have to poll tty size ¯\_(ツ)_/¯
+		go func() {
+			prevH := goterm.Height()
+			prevW := goterm.Width()
+			for {
+				time.Sleep(time.Millisecond * 250)
+				h := goterm.Height()
+				w := goterm.Width()
+				if prevW != w || prevH != h {
+					sigchan <- signal.SIGWINCH
+				}
+				prevH = h
+				prevW = w
+			}
+		}()
+	}
+
+	go func() {
+		for {
+			select {
+			case <-sigchan:
+				resize(ctx, container, moby.ResizeOptions{ // nolint:errcheck
+					Height: uint(goterm.Height()),
+					Width:  uint(goterm.Width()),
+				})
+			case <-ctx.Done():
+				return
+			}
+		}
+	}()
+	return nil
+}

+ 5 - 0
local/compose/run.go

@@ -94,6 +94,11 @@ func (s *composeService) RunOneOffContainer(ctx context.Context, project *types.
 		return 0, err
 	}
 
+	err = s.monitorTTySize(ctx, containerID, s.apiClient.ContainerResize)
+	if err != nil {
+		return 0, err
+	}
+
 	statusC, errC := s.apiClient.ContainerWait(context.Background(), oneoffContainer.ID, container.WaitConditionNotRunning)
 	select {
 	case status := <-statusC: