exec.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. // +build linux
  2. package native
  3. import (
  4. "fmt"
  5. "log"
  6. "os"
  7. "os/exec"
  8. "path/filepath"
  9. "runtime"
  10. "github.com/docker/docker/daemon/execdriver"
  11. "github.com/docker/docker/reexec"
  12. "github.com/docker/libcontainer"
  13. "github.com/docker/libcontainer/namespaces"
  14. )
  15. const commandName = "nsenter-exec"
  16. func init() {
  17. reexec.Register(commandName, nsenterExec)
  18. }
  19. func nsenterExec() {
  20. runtime.LockOSThread()
  21. userArgs := findUserArgs()
  22. config, err := loadConfigFromFd()
  23. if err != nil {
  24. log.Fatalf("docker-exec: unable to receive config from sync pipe: %s", err)
  25. }
  26. if err := namespaces.FinalizeSetns(config, userArgs); err != nil {
  27. log.Fatalf("docker-exec: failed to exec: %s", err)
  28. }
  29. }
  30. // TODO(vishh): Add support for running in priviledged mode and running as a different user.
  31. func (d *driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) {
  32. active := d.activeContainers[c.ID]
  33. if active == nil {
  34. return -1, fmt.Errorf("No active container exists with ID %s", c.ID)
  35. }
  36. state, err := libcontainer.GetState(filepath.Join(d.root, c.ID))
  37. if err != nil {
  38. return -1, fmt.Errorf("State unavailable for container with ID %s. The container may have been cleaned up already. Error: %s", c.ID, err)
  39. }
  40. var term execdriver.Terminal
  41. if processConfig.Tty {
  42. term, err = NewTtyConsole(processConfig, pipes)
  43. } else {
  44. term, err = execdriver.NewStdConsole(processConfig, pipes)
  45. }
  46. processConfig.Terminal = term
  47. args := append([]string{processConfig.Entrypoint}, processConfig.Arguments...)
  48. return namespaces.ExecIn(active.container, state, args, os.Args[0], "exec", processConfig.Stdin, processConfig.Stdout, processConfig.Stderr, processConfig.Console,
  49. func(cmd *exec.Cmd) {
  50. if startCallback != nil {
  51. startCallback(&c.ProcessConfig, cmd.Process.Pid)
  52. }
  53. })
  54. }