execin.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. // +build linux
  2. package namespaces
  3. import (
  4. "encoding/json"
  5. "os"
  6. "strconv"
  7. "github.com/dotcloud/docker/pkg/label"
  8. "github.com/dotcloud/docker/pkg/libcontainer"
  9. "github.com/dotcloud/docker/pkg/system"
  10. )
  11. // ExecIn uses an existing pid and joins the pid's namespaces with the new command.
  12. func ExecIn(container *libcontainer.Container, nspid int, args []string) error {
  13. // TODO(vmarmol): If this gets too long, send it over a pipe to the child.
  14. // Marshall the container into JSON since it won't be available in the namespace.
  15. containerJson, err := json.Marshal(container)
  16. if err != nil {
  17. return err
  18. }
  19. // TODO(vmarmol): Move this to the container JSON.
  20. processLabel, err := label.GetPidCon(nspid)
  21. if err != nil {
  22. return err
  23. }
  24. // Enter the namespace and then finish setup
  25. finalArgs := []string{os.Args[0], "nsenter", strconv.Itoa(nspid), processLabel, string(containerJson)}
  26. finalArgs = append(finalArgs, args...)
  27. if err := system.Execv(finalArgs[0], finalArgs[0:], os.Environ()); err != nil {
  28. return err
  29. }
  30. panic("unreachable")
  31. }
  32. // NsEnter is run after entering the namespace.
  33. func NsEnter(container *libcontainer.Container, processLabel string, nspid int, args []string) error {
  34. // clear the current processes env and replace it with the environment
  35. // defined on the container
  36. if err := LoadContainerEnvironment(container); err != nil {
  37. return err
  38. }
  39. if err := FinalizeNamespace(container); err != nil {
  40. return err
  41. }
  42. if err := label.SetProcessLabel(processLabel); err != nil {
  43. return err
  44. }
  45. if err := system.Execv(args[0], args[0:], container.Env); err != nil {
  46. return err
  47. }
  48. panic("unreachable")
  49. }