diff options
Diffstat (limited to 'pkg/domain/infra/abi/terminal/terminal_common.go')
-rw-r--r-- | pkg/domain/infra/abi/terminal/terminal_common.go | 113 |
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 +} |