123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- package container
- import (
- "fmt"
- "os"
- gosignal "os/signal"
- "runtime"
- "time"
- "github.com/Sirupsen/logrus"
- "github.com/docker/docker/api/types"
- "github.com/docker/docker/cli/command"
- "github.com/docker/docker/client"
- "github.com/docker/docker/pkg/signal"
- "golang.org/x/net/context"
- )
- // resizeTtyTo resizes tty to specific height and width
- func resizeTtyTo(ctx context.Context, client client.ContainerAPIClient, id string, height, width uint, isExec bool) {
- if height == 0 && width == 0 {
- return
- }
- options := types.ResizeOptions{
- Height: height,
- Width: width,
- }
- var err error
- if isExec {
- err = client.ContainerExecResize(ctx, id, options)
- } else {
- err = client.ContainerResize(ctx, id, options)
- }
- if err != nil {
- logrus.Debugf("Error resize: %s", err)
- }
- }
- // MonitorTtySize updates the container tty size when the terminal tty changes size
- func MonitorTtySize(ctx context.Context, cli *command.DockerCli, id string, isExec bool) error {
- resizeTty := func() {
- height, width := cli.Out().GetTtySize()
- resizeTtyTo(ctx, cli.Client(), id, height, width, isExec)
- }
- resizeTty()
- if runtime.GOOS == "windows" {
- go func() {
- prevH, prevW := cli.Out().GetTtySize()
- for {
- time.Sleep(time.Millisecond * 250)
- h, w := cli.Out().GetTtySize()
- if prevW != w || prevH != h {
- resizeTty()
- }
- prevH = h
- prevW = w
- }
- }()
- } else {
- sigchan := make(chan os.Signal, 1)
- gosignal.Notify(sigchan, signal.SIGWINCH)
- go func() {
- for range sigchan {
- resizeTty()
- }
- }()
- }
- return nil
- }
- // ForwardAllSignals forwards signals to the container
- func ForwardAllSignals(ctx context.Context, cli *command.DockerCli, cid string) chan os.Signal {
- sigc := make(chan os.Signal, 128)
- signal.CatchAll(sigc)
- go func() {
- for s := range sigc {
- if s == signal.SIGCHLD || s == signal.SIGPIPE {
- continue
- }
- var sig string
- for sigStr, sigN := range signal.SignalMap {
- if sigN == s {
- sig = sigStr
- break
- }
- }
- if sig == "" {
- fmt.Fprintf(cli.Err(), "Unsupported signal: %v. Discarding.\n", s)
- continue
- }
- if err := cli.Client().ContainerKill(ctx, cid, sig); err != nil {
- logrus.Debugf("Error sending signal: %s", err)
- }
- }
- }()
- return sigc
- }
|