summaryrefslogtreecommitdiff
path: root/pkg/domain/infra/abi/terminal/terminal_common.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/domain/infra/abi/terminal/terminal_common.go')
-rw-r--r--pkg/domain/infra/abi/terminal/terminal_common.go113
1 files changed, 113 insertions, 0 deletions
diff --git a/pkg/domain/infra/abi/terminal/terminal_common.go b/pkg/domain/infra/abi/terminal/terminal_common.go
new file mode 100644
index 000000000..afae2c085
--- /dev/null
+++ b/pkg/domain/infra/abi/terminal/terminal_common.go
@@ -0,0 +1,113 @@
+//go:build linux || freebsd
+// +build linux freebsd
+
+package terminal
+
+import (
+ "bufio"
+ "context"
+ "fmt"
+ "os"
+
+ "github.com/containers/common/pkg/resize"
+ "github.com/containers/podman/v4/libpod"
+ "github.com/containers/podman/v4/libpod/define"
+ "github.com/sirupsen/logrus"
+ "golang.org/x/term"
+)
+
+// ExecAttachCtr execs and attaches to a container
+func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, execConfig *libpod.ExecConfig, streams *define.AttachStreams) (int, error) {
+ var resizechan chan resize.TerminalSize
+ haveTerminal := term.IsTerminal(int(os.Stdin.Fd()))
+
+ // Check if we are attached to a terminal. If we are, generate resize
+ // events, and set the terminal to raw mode
+ if haveTerminal && execConfig.Terminal {
+ resizechan = make(chan resize.TerminalSize)
+ cancel, oldTermState, err := handleTerminalAttach(ctx, resizechan)
+ if err != nil {
+ return -1, err
+ }
+ defer cancel()
+ defer func() {
+ if err := restoreTerminal(oldTermState); err != nil {
+ logrus.Errorf("Unable to restore terminal: %q", err)
+ }
+ }()
+ }
+ return ctr.Exec(execConfig, streams, resizechan)
+}
+
+// StartAttachCtr starts and (if required) attaches to a container
+// if you change the signature of this function from os.File to io.Writer, it will trigger a downstream
+// error. we may need to just lint disable this one.
+func StartAttachCtr(ctx context.Context, ctr *libpod.Container, stdout, stderr, stdin *os.File, detachKeys string, sigProxy bool, startContainer bool) error { //nolint: interfacer
+ resize := make(chan resize.TerminalSize)
+
+ haveTerminal := term.IsTerminal(int(os.Stdin.Fd()))
+
+ // Check if we are attached to a terminal. If we are, generate resize
+ // events, and set the terminal to raw mode
+ if haveTerminal && ctr.Spec().Process.Terminal {
+ cancel, oldTermState, err := handleTerminalAttach(ctx, resize)
+ if err != nil {
+ return err
+ }
+ defer func() {
+ if err := restoreTerminal(oldTermState); err != nil {
+ logrus.Errorf("Unable to restore terminal: %q", err)
+ }
+ }()
+ defer cancel()
+ }
+
+ streams := new(define.AttachStreams)
+ streams.OutputStream = stdout
+ streams.ErrorStream = stderr
+ streams.InputStream = bufio.NewReader(stdin)
+ streams.AttachOutput = true
+ streams.AttachError = true
+ streams.AttachInput = true
+
+ if stdout == nil {
+ logrus.Debugf("Not attaching to stdout")
+ streams.AttachOutput = false
+ }
+ if stderr == nil {
+ logrus.Debugf("Not attaching to stderr")
+ streams.AttachError = false
+ }
+ if stdin == nil {
+ logrus.Debugf("Not attaching to stdin")
+ streams.AttachInput = false
+ }
+
+ if !startContainer {
+ if sigProxy {
+ ProxySignals(ctr)
+ }
+
+ return ctr.Attach(streams, detachKeys, resize)
+ }
+
+ attachChan, err := ctr.StartAndAttach(ctx, streams, detachKeys, resize, true)
+ if err != nil {
+ return err
+ }
+
+ if sigProxy {
+ ProxySignals(ctr)
+ }
+
+ if stdout == nil && stderr == nil {
+ fmt.Printf("%s\n", ctr.ID())
+ }
+
+ err = <-attachChan
+ if err != nil {
+ return fmt.Errorf("error attaching to container %s: %w", ctr.ID(), err)
+ }
+
+ return nil
+}