From 0b34327ad40e04861dac7f73870d87633a5c637e Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 25 Feb 2019 11:44:06 +0100 Subject: exec: support --preserve-fds Allow to pass additional FDs to the process being executed. Closes: https://github.com/containers/libpod/issues/2372 Signed-off-by: Giuseppe Scrivano --- cmd/podman/cliconfig/config.go | 1 + cmd/podman/create.go | 2 +- cmd/podman/exec.go | 30 ++++++++++++++++++++++++++++-- cmd/podman/top.go | 2 +- 4 files changed, 31 insertions(+), 4 deletions(-) (limited to 'cmd') diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go index 702e20040..ea99aafc2 100644 --- a/cmd/podman/cliconfig/config.go +++ b/cmd/podman/cliconfig/config.go @@ -100,6 +100,7 @@ type ExecValues struct { User string Latest bool Workdir string + PreserveFDs int } type ImageExistsValues struct { diff --git a/cmd/podman/create.go b/cmd/podman/create.go index 95cb732d9..129c886b2 100644 --- a/cmd/podman/create.go +++ b/cmd/podman/create.go @@ -869,7 +869,7 @@ func joinOrCreateRootlessUserNamespace(createConfig *cc.CreateConfig, runtime *l } return false, -1, errors.Errorf("dependency container %s is not running", ctr.ID()) } - return rootless.JoinNS(uint(pid)) + return rootless.JoinNS(uint(pid), 0) } } return rootless.BecomeRootInUserNS() diff --git a/cmd/podman/exec.go b/cmd/podman/exec.go index 4917fb606..32a6e4bb5 100644 --- a/cmd/podman/exec.go +++ b/cmd/podman/exec.go @@ -4,7 +4,9 @@ import ( "fmt" "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/spf13/cobra" + "io/ioutil" "os" + "strconv" "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/libpod" @@ -47,6 +49,7 @@ func init() { flags.BoolVarP(&execCommand.Tty, "tty", "t", false, "Allocate a pseudo-TTY. The default is false") flags.StringVarP(&execCommand.User, "user", "u", "", "Sets the username or UID used and optionally the groupname or GID for the specified command") + flags.IntVar(&execCommand.PreserveFDs, "preserve-fds", 0, "Pass N additional file descriptors to the container") flags.StringVarP(&execCommand.Workdir, "workdir", "w", "", "Working directory inside the container") markFlagHiddenForRemoteClient("latest", flags) } @@ -82,11 +85,34 @@ func execCmd(c *cliconfig.ExecValues) error { return errors.Wrapf(err, "unable to exec into %s", args[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 { + 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") + } + } + + } + pid, err := ctr.PID() if err != nil { return err } - became, ret, err := rootless.JoinNS(uint(pid)) + became, ret, err := rootless.JoinNS(uint(pid), c.PreserveFDs) if err != nil { return err } @@ -113,5 +139,5 @@ func execCmd(c *cliconfig.ExecValues) error { streams.AttachError = true streams.AttachInput = true - return ctr.Exec(c.Tty, c.Privileged, envs, cmd, c.User, c.Workdir, streams) + return ctr.Exec(c.Tty, c.Privileged, envs, cmd, c.User, c.Workdir, streams, c.PreserveFDs) } diff --git a/cmd/podman/top.go b/cmd/podman/top.go index cdf270fa7..d96402f1a 100644 --- a/cmd/podman/top.go +++ b/cmd/podman/top.go @@ -108,7 +108,7 @@ func topCmd(c *cliconfig.TopValues) error { if err != nil { return err } - became, ret, err := rootless.JoinNS(uint(pid)) + became, ret, err := rootless.JoinNS(uint(pid), 0) if err != nil { return err } -- cgit v1.2.3-54-g00ecf