diff options
author | Peter Hunt <pehunt@redhat.com> | 2019-07-01 13:55:03 -0400 |
---|---|---|
committer | Peter Hunt <pehunt@redhat.com> | 2019-07-22 15:57:23 -0400 |
commit | a1a79c08b72793cf2f75490d8ffc844c3d16bd4a (patch) | |
tree | 0ba4dd73229399a4c57e9d073327886fa3640707 /pkg/adapter/containers.go | |
parent | cf9efa90e5dcf89e10408eae5229c4ce904d9fc7 (diff) | |
download | podman-a1a79c08b72793cf2f75490d8ffc844c3d16bd4a.tar.gz podman-a1a79c08b72793cf2f75490d8ffc844c3d16bd4a.tar.bz2 podman-a1a79c08b72793cf2f75490d8ffc844c3d16bd4a.zip |
Implement conmon exec
This includes:
Implement exec -i and fix some typos in description of -i docs
pass failed runtime status to caller
Add resize handling for a terminal connection
Customize exec systemd-cgroup slice
fix healthcheck
fix top
add --detach-keys
Implement podman-remote exec (jhonce)
* Cleanup some orphaned code (jhonce)
adapt remote exec for conmon exec (pehunt)
Fix healthcheck and exec to match docs
Introduce two new OCIRuntime errors to more comprehensively describe situations in which the runtime can error
Use these different errors in branching for exit code in healthcheck and exec
Set conmon to use new api version
Signed-off-by: Jhon Honce <jhonce@redhat.com>
Signed-off-by: Peter Hunt <pehunt@redhat.com>
Diffstat (limited to 'pkg/adapter/containers.go')
-rw-r--r-- | pkg/adapter/containers.go | 130 |
1 files changed, 73 insertions, 57 deletions
diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go index 9726b237f..47f1b091e 100644 --- a/pkg/adapter/containers.go +++ b/pkg/adapter/containers.go @@ -924,13 +924,85 @@ func (r *LocalRuntime) execPS(c *libpod.Container, args []string) ([]string, err }() cmd := append([]string{"ps"}, args...) - if err := c.Exec(false, false, []string{}, cmd, "", "", streams, 0); err != nil { + ec, err := c.Exec(false, false, []string{}, cmd, "", "", streams, 0, nil, "") + if err != nil { return nil, err + } else if ec != 0 { + return nil, errors.Errorf("Runtime failed with exit status: %d and output: %s", ec, strings.Join(psOutput, " ")) } return psOutput, nil } +// ExecContainer executes a command in the container +func (r *LocalRuntime) ExecContainer(ctx context.Context, cli *cliconfig.ExecValues) (int, error) { + var ( + ctr *Container + err error + cmd []string + ) + // default invalid command exit code + ec := 125 + + if cli.Latest { + if ctr, err = r.GetLatestContainer(); err != nil { + return ec, err + } + cmd = cli.InputArgs[0:] + } else { + if ctr, err = r.LookupContainer(cli.InputArgs[0]); err != nil { + return ec, err + } + cmd = cli.InputArgs[1:] + } + + if cli.PreserveFDs > 0 { + entries, err := ioutil.ReadDir("/proc/self/fd") + if err != nil { + return ec, errors.Wrapf(err, "unable to read /proc/self/fd") + } + + m := make(map[int]bool) + for _, e := range entries { + i, err := strconv.Atoi(e.Name()) + if err != nil { + return ec, errors.Wrapf(err, "cannot parse %s in /proc/self/fd", e.Name()) + } + m[i] = true + } + + for i := 3; i < 3+cli.PreserveFDs; i++ { + if _, found := m[i]; !found { + return ec, errors.New("invalid --preserve-fds=N specified. Not enough FDs available") + } + } + } + + // Validate given environment variables + env := map[string]string{} + if err := parse.ReadKVStrings(env, []string{}, cli.Env); err != nil { + return ec, errors.Wrapf(err, "unable to process environment variables") + } + + // Build env slice of key=value strings for Exec + envs := []string{} + for k, v := range env { + envs = append(envs, fmt.Sprintf("%s=%s", k, v)) + } + + streams := new(libpod.AttachStreams) + streams.OutputStream = os.Stdout + streams.ErrorStream = os.Stderr + if cli.Interactive { + streams.InputStream = os.Stdin + streams.AttachInput = true + } + streams.AttachOutput = true + streams.AttachError = true + + return ExecAttachCtr(ctx, ctr.Container, cli.Tty, cli.Privileged, envs, cmd, cli.User, cli.Workdir, streams, cli.PreserveFDs, cli.DetachKeys) +} + // Prune removes stopped containers func (r *LocalRuntime) Prune(ctx context.Context, maxWorkers int, force bool) ([]string, map[string]error, error) { var ( @@ -1129,59 +1201,3 @@ func (r *LocalRuntime) Commit(ctx context.Context, c *cliconfig.CommitValues, co } return newImage.ID(), nil } - -// Exec a command in a container -func (r *LocalRuntime) Exec(c *cliconfig.ExecValues, cmd []string) error { - var ctr *Container - var err error - - if c.Latest { - ctr, err = r.GetLatestContainer() - } else { - ctr, err = r.LookupContainer(c.InputArgs[0]) - } - if err != nil { - return errors.Wrapf(err, "unable to exec into %s", c.InputArgs[0]) - } - - if c.PreserveFDs > 0 { - entries, err := ioutil.ReadDir("/proc/self/fd") - if err != nil { - return errors.Wrapf(err, "unable to read /proc/self/fd") - } - m := make(map[int]bool) - for _, e := range entries { - i, err := strconv.Atoi(e.Name()) - if err != nil { - return errors.Wrapf(err, "cannot parse %s in /proc/self/fd", e.Name()) - } - m[i] = true - } - for i := 3; i < 3+c.PreserveFDs; i++ { - if _, found := m[i]; !found { - return errors.New("invalid --preserve-fds=N specified. Not enough FDs available") - } - } - } - - // ENVIRONMENT VARIABLES - env := map[string]string{} - - if err := parse.ReadKVStrings(env, []string{}, c.Env); err != nil { - return errors.Wrapf(err, "unable to process environment variables") - } - envs := []string{} - for k, v := range env { - envs = append(envs, fmt.Sprintf("%s=%s", k, v)) - } - - 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, c.PreserveFDs) -} |