diff options
author | Matthew Heon <matthew.heon@pm.me> | 2020-05-18 17:27:27 -0400 |
---|---|---|
committer | Matthew Heon <matthew.heon@pm.me> | 2020-05-20 16:11:05 -0400 |
commit | 05a034118fcb5057593cb1492f1c9be59f7a88d8 (patch) | |
tree | d85e6737ba5117d893985788bb79007247e74578 /pkg/domain/infra | |
parent | 43413887c0d8a20095e454d1046df46a42810e75 (diff) | |
download | podman-05a034118fcb5057593cb1492f1c9be59f7a88d8.tar.gz podman-05a034118fcb5057593cb1492f1c9be59f7a88d8.tar.bz2 podman-05a034118fcb5057593cb1492f1c9be59f7a88d8.zip |
Add CLI frontend for detached exec
Add a new ContainerEngine method for creating a detached exec
session, and wire in the frontend code to do this. As part of
this, move Streams out of ExecOptions to the function signature
in an effort to share the struct between both methods.
Fixes #5884
Signed-off-by: Matthew Heon <matthew.heon@pm.me>
Diffstat (limited to 'pkg/domain/infra')
-rw-r--r-- | pkg/domain/infra/abi/containers.go | 56 | ||||
-rw-r--r-- | pkg/domain/infra/abi/terminal/terminal_linux.go | 14 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/containers.go | 6 |
3 files changed, 61 insertions, 15 deletions
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index 035efe575..18282bb79 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -536,7 +536,22 @@ func (ic *ContainerEngine) ContainerAttach(ctx context.Context, nameOrId string, return nil } -func (ic *ContainerEngine) ContainerExec(ctx context.Context, nameOrId string, options entities.ExecOptions) (int, error) { +func makeExecConfig(options entities.ExecOptions) *libpod.ExecConfig { + execConfig := new(libpod.ExecConfig) + execConfig.Command = options.Cmd + execConfig.Terminal = options.Tty + execConfig.Privileged = options.Privileged + execConfig.Environment = options.Envs + execConfig.User = options.User + execConfig.WorkDir = options.WorkDir + execConfig.DetachKeys = &options.DetachKeys + execConfig.PreserveFDs = options.PreserveFDs + execConfig.AttachStdin = options.Interactive + + return execConfig +} + +func checkExecPreserveFDs(options entities.ExecOptions) (int, error) { ec := define.ExecErrorCodeGeneric if options.PreserveFDs > 0 { entries, err := ioutil.ReadDir("/proc/self/fd") @@ -559,15 +574,52 @@ func (ic *ContainerEngine) ContainerExec(ctx context.Context, nameOrId string, o } } } + return ec, nil +} + +func (ic *ContainerEngine) ContainerExec(ctx context.Context, nameOrId string, options entities.ExecOptions, streams define.AttachStreams) (int, error) { + ec, err := checkExecPreserveFDs(options) + if err != nil { + return ec, err + } ctrs, err := getContainersByContext(false, options.Latest, []string{nameOrId}, ic.Libpod) if err != nil { return ec, err } ctr := ctrs[0] - ec, err = terminal.ExecAttachCtr(ctx, ctr, options.Tty, options.Privileged, options.Envs, options.Cmd, options.User, options.WorkDir, &options.Streams, options.PreserveFDs, options.DetachKeys) + + execConfig := makeExecConfig(options) + + ec, err = terminal.ExecAttachCtr(ctx, ctr, execConfig, &streams) return define.TranslateExecErrorToExitCode(ec, err), err } +func (ic *ContainerEngine) ContainerExecDetached(ctx context.Context, nameOrId string, options entities.ExecOptions) (string, error) { + _, err := checkExecPreserveFDs(options) + if err != nil { + return "", err + } + ctrs, err := getContainersByContext(false, options.Latest, []string{nameOrId}, ic.Libpod) + if err != nil { + return "", err + } + ctr := ctrs[0] + + execConfig := makeExecConfig(options) + + // Create and start the exec session + id, err := ctr.ExecCreate(execConfig) + if err != nil { + return "", err + } + + // TODO: we should try and retrieve exit code if this fails. + if err := ctr.ExecStart(id); err != nil { + return "", err + } + return id, nil +} + func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []string, options entities.ContainerStartOptions) ([]*entities.ContainerStartReport, error) { var reports []*entities.ContainerStartReport var exitCode = define.ExecErrorCodeGeneric diff --git a/pkg/domain/infra/abi/terminal/terminal_linux.go b/pkg/domain/infra/abi/terminal/terminal_linux.go index 15701342f..8d9cdde03 100644 --- a/pkg/domain/infra/abi/terminal/terminal_linux.go +++ b/pkg/domain/infra/abi/terminal/terminal_linux.go @@ -15,13 +15,13 @@ import ( ) // 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) { +func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, execConfig *libpod.ExecConfig, streams *define.AttachStreams) (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 { + if haveTerminal && execConfig.Terminal { cancel, oldTermState, err := handleTerminalAttach(ctx, resize) if err != nil { return -1, err @@ -34,16 +34,6 @@ func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, tty, privileged b }() } - 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) } diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index cebd332e3..b460e3e91 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -329,10 +329,14 @@ func (ic *ContainerEngine) ContainerAttach(ctx context.Context, nameOrId string, return containers.Attach(ic.ClientCxt, nameOrId, &options.DetachKeys, nil, bindings.PTrue, options.Stdin, options.Stdout, options.Stderr) } -func (ic *ContainerEngine) ContainerExec(ctx context.Context, nameOrId string, options entities.ExecOptions) (int, error) { +func (ic *ContainerEngine) ContainerExec(ctx context.Context, nameOrId string, options entities.ExecOptions, streams define.AttachStreams) (int, error) { return 125, errors.New("not implemented") } +func (ic *ContainerEngine) ContainerExecDetached(ctx context.Context, nameOrID string, options entities.ExecOptions) (string, error) { + return "", errors.New("not implemented") +} + func startAndAttach(ic *ContainerEngine, name string, detachKeys *string, input, output, errput *os.File) error { //nolint attachErr := make(chan error) go func() { |