Allow Exec API user to override streams

Allow passing in of AttachStreams to libpod.Exec() for usage in podman healthcheck. An API caller can now specify different streams for stdout, stderr and stdin, or no streams at all.

Signed-off-by: Peter Hunt <pehunt@redhat.com>
This commit is contained in:
Peter Hunt 2019-02-28 13:29:56 -05:00
parent 2e463b7720
commit d780e69559
3 changed files with 23 additions and 8 deletions

View File

@ -105,5 +105,13 @@ func execCmd(c *cliconfig.ExecValues) error {
envs = append(envs, fmt.Sprintf("%s=%s", k, v)) envs = append(envs, fmt.Sprintf("%s=%s", k, v))
} }
return ctr.Exec(c.Tty, c.Privileged, envs, cmd, c.User, c.Workdir) streams := new(libpod.AttachStreams)
streams.OutputStream = os.Stdout
streams.ErrorStream = os.Stderr
streams.InputStream = os.Stdin
streams.AttachOutput = true
streams.AttachError = true
streams.AttachInput = true
return ctr.Exec(c.Tty, c.Privileged, envs, cmd, c.User, c.Workdir, streams)
} }

View File

@ -203,9 +203,8 @@ func (c *Container) Kill(signal uint) error {
} }
// Exec starts a new process inside the container // Exec starts a new process inside the container
// TODO allow specifying streams to attach to
// TODO investigate allowing exec without attaching // TODO investigate allowing exec without attaching
func (c *Container) Exec(tty, privileged bool, env, cmd []string, user, workDir string) error { func (c *Container) Exec(tty, privileged bool, env, cmd []string, user, workDir string, streams *AttachStreams) error {
var capList []string var capList []string
locked := false locked := false
@ -267,7 +266,7 @@ func (c *Container) Exec(tty, privileged bool, env, cmd []string, user, workDir
logrus.Debugf("Creating new exec session in container %s with session id %s", c.ID(), sessionID) logrus.Debugf("Creating new exec session in container %s with session id %s", c.ID(), sessionID)
execCmd, err := c.runtime.ociRuntime.execContainer(c, cmd, capList, env, tty, workDir, hostUser, sessionID) execCmd, err := c.runtime.ociRuntime.execContainer(c, cmd, capList, env, tty, workDir, hostUser, sessionID, streams)
if err != nil { if err != nil {
return errors.Wrapf(err, "error exec %s", c.ID()) return errors.Wrapf(err, "error exec %s", c.ID())
} }

View File

@ -733,7 +733,7 @@ func (r *OCIRuntime) unpauseContainer(ctr *Container) error {
// TODO: Add --detach support // TODO: Add --detach support
// TODO: Convert to use conmon // TODO: Convert to use conmon
// TODO: add --pid-file and use that to generate exec session tracking // TODO: add --pid-file and use that to generate exec session tracking
func (r *OCIRuntime) execContainer(c *Container, cmd, capAdd, env []string, tty bool, cwd, user, sessionID string) (*exec.Cmd, error) { func (r *OCIRuntime) execContainer(c *Container, cmd, capAdd, env []string, tty bool, cwd, user, sessionID string, streams *AttachStreams) (*exec.Cmd, error) {
if len(cmd) == 0 { if len(cmd) == 0 {
return nil, errors.Wrapf(ErrInvalidArg, "must provide a command to execute") return nil, errors.Wrapf(ErrInvalidArg, "must provide a command to execute")
} }
@ -789,9 +789,17 @@ func (r *OCIRuntime) execContainer(c *Container, cmd, capAdd, env []string, tty
logrus.Debugf("Starting runtime %s with following arguments: %v", r.path, args) logrus.Debugf("Starting runtime %s with following arguments: %v", r.path, args)
execCmd := exec.Command(r.path, args...) execCmd := exec.Command(r.path, args...)
execCmd.Stdout = os.Stdout
execCmd.Stderr = os.Stderr if streams.AttachOutput {
execCmd.Stdin = os.Stdin execCmd.Stdout = streams.OutputStream
}
if streams.AttachInput {
execCmd.Stdin = streams.InputStream
}
if streams.AttachError {
execCmd.Stderr = streams.ErrorStream
}
execCmd.Env = append(execCmd.Env, fmt.Sprintf("XDG_RUNTIME_DIR=%s", runtimeDir)) execCmd.Env = append(execCmd.Env, fmt.Sprintf("XDG_RUNTIME_DIR=%s", runtimeDir))
if err := execCmd.Start(); err != nil { if err := execCmd.Start(); err != nil {