From 4d895dcb5472da19b886ca1662182556242fe5d4 Mon Sep 17 00:00:00 2001 From: Brent Baude Date: Fri, 3 Apr 2020 14:56:10 -0500 Subject: v2podman attach and exec add the ability to attach to a running container. the tunnel side of this is not enabled yet as we have work on the endpoints and plumbing to do yet. add the ability to exec a command in a running container. the tunnel side is also being deferred for same reason. Signed-off-by: Brent Baude --- pkg/domain/infra/abi/terminal/terminal_linux.go | 123 ++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 pkg/domain/infra/abi/terminal/terminal_linux.go (limited to 'pkg/domain/infra/abi/terminal/terminal_linux.go') diff --git a/pkg/domain/infra/abi/terminal/terminal_linux.go b/pkg/domain/infra/abi/terminal/terminal_linux.go new file mode 100644 index 000000000..664205df1 --- /dev/null +++ b/pkg/domain/infra/abi/terminal/terminal_linux.go @@ -0,0 +1,123 @@ +// +build ABISupport + +package terminal + +import ( + "bufio" + "context" + "fmt" + "os" + + "github.com/containers/libpod/libpod" + "github.com/containers/libpod/libpod/define" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "golang.org/x/crypto/ssh/terminal" + "k8s.io/client-go/tools/remotecommand" +) + +// ExecAttachCtr execs and attaches to a container +func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, tty, privileged bool, env map[string]string, cmd []string, user, workDir string, streams *define.AttachStreams, preserveFDs uint, detachKeys string) (int, error) { + resize := make(chan remotecommand.TerminalSize) + haveTerminal := terminal.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 && tty { + cancel, oldTermState, err := handleTerminalAttach(ctx, resize) + if err != nil { + return -1, err + } + defer cancel() + defer func() { + if err := restoreTerminal(oldTermState); err != nil { + logrus.Errorf("unable to restore terminal: %q", err) + } + }() + } + + execConfig := new(libpod.ExecConfig) + execConfig.Command = cmd + execConfig.Terminal = tty + execConfig.Privileged = privileged + execConfig.Environment = env + execConfig.User = user + execConfig.WorkDir = workDir + execConfig.DetachKeys = &detachKeys + execConfig.PreserveFDs = preserveFDs + + return ctr.Exec(execConfig, streams, resize) +} + +// 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, recursive bool) error { //nolint-interfacer + resize := make(chan remotecommand.TerminalSize) + + haveTerminal := terminal.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, recursive) + 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 errors.Wrapf(err, "error attaching to container %s", ctr.ID()) + } + + return nil +} -- cgit v1.2.3-54-g00ecf