github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/pkg/domain/infra/abi/terminal/terminal_linux.go (about) 1 package terminal 2 3 import ( 4 "bufio" 5 "context" 6 "fmt" 7 "os" 8 9 "github.com/containers/podman/v2/libpod" 10 "github.com/containers/podman/v2/libpod/define" 11 "github.com/pkg/errors" 12 "github.com/sirupsen/logrus" 13 "golang.org/x/crypto/ssh/terminal" 14 "k8s.io/client-go/tools/remotecommand" 15 ) 16 17 // ExecAttachCtr execs and attaches to a container 18 func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, execConfig *libpod.ExecConfig, streams *define.AttachStreams) (int, error) { 19 resize := make(chan remotecommand.TerminalSize) 20 haveTerminal := terminal.IsTerminal(int(os.Stdin.Fd())) 21 22 // Check if we are attached to a terminal. If we are, generate resize 23 // events, and set the terminal to raw mode 24 if haveTerminal && execConfig.Terminal { 25 cancel, oldTermState, err := handleTerminalAttach(ctx, resize) 26 if err != nil { 27 return -1, err 28 } 29 defer cancel() 30 defer func() { 31 if err := restoreTerminal(oldTermState); err != nil { 32 logrus.Errorf("unable to restore terminal: %q", err) 33 } 34 }() 35 } 36 37 return ctr.Exec(execConfig, streams, resize) 38 } 39 40 // StartAttachCtr starts and (if required) attaches to a container 41 // if you change the signature of this function from os.File to io.Writer, it will trigger a downstream 42 // error. we may need to just lint disable this one. 43 func StartAttachCtr(ctx context.Context, ctr *libpod.Container, stdout, stderr, stdin *os.File, detachKeys string, sigProxy bool, startContainer bool, recursive bool) error { //nolint-interfacer 44 resize := make(chan remotecommand.TerminalSize) 45 46 haveTerminal := terminal.IsTerminal(int(os.Stdin.Fd())) 47 48 // Check if we are attached to a terminal. If we are, generate resize 49 // events, and set the terminal to raw mode 50 if haveTerminal && ctr.Spec().Process.Terminal { 51 cancel, oldTermState, err := handleTerminalAttach(ctx, resize) 52 if err != nil { 53 return err 54 } 55 defer func() { 56 if err := restoreTerminal(oldTermState); err != nil { 57 logrus.Errorf("unable to restore terminal: %q", err) 58 } 59 }() 60 defer cancel() 61 } 62 63 streams := new(define.AttachStreams) 64 streams.OutputStream = stdout 65 streams.ErrorStream = stderr 66 streams.InputStream = bufio.NewReader(stdin) 67 streams.AttachOutput = true 68 streams.AttachError = true 69 streams.AttachInput = true 70 71 if stdout == nil { 72 logrus.Debugf("Not attaching to stdout") 73 streams.AttachOutput = false 74 } 75 if stderr == nil { 76 logrus.Debugf("Not attaching to stderr") 77 streams.AttachError = false 78 } 79 if stdin == nil { 80 logrus.Debugf("Not attaching to stdin") 81 streams.AttachInput = false 82 } 83 84 if !startContainer { 85 if sigProxy { 86 ProxySignals(ctr) 87 } 88 89 return ctr.Attach(streams, detachKeys, resize) 90 } 91 92 attachChan, err := ctr.StartAndAttach(ctx, streams, detachKeys, resize, recursive) 93 if err != nil { 94 return err 95 } 96 97 if sigProxy { 98 ProxySignals(ctr) 99 } 100 101 if stdout == nil && stderr == nil { 102 fmt.Printf("%s\n", ctr.ID()) 103 } 104 105 err = <-attachChan 106 if err != nil { 107 return errors.Wrapf(err, "error attaching to container %s", ctr.ID()) 108 } 109 110 return nil 111 }