command.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. package nsinit
  2. import (
  3. "github.com/dotcloud/docker/pkg/libcontainer"
  4. "github.com/dotcloud/docker/pkg/system"
  5. "os"
  6. "os/exec"
  7. )
  8. // CommandFactory takes the container's configuration and options passed by the
  9. // parent processes and creates an *exec.Cmd that will be used to fork/exec the
  10. // namespaced init process
  11. type CommandFactory interface {
  12. Create(container *libcontainer.Container, console string, syncFd *os.File, args []string) *exec.Cmd
  13. }
  14. type DefaultCommandFactory struct {
  15. Root string
  16. }
  17. // Create will return an exec.Cmd with the Cloneflags set to the proper namespaces
  18. // defined on the container's configuration and use the current binary as the init with the
  19. // args provided
  20. func (c *DefaultCommandFactory) Create(container *libcontainer.Container, console string, pipe *os.File, args []string) *exec.Cmd {
  21. // get our binary name from arg0 so we can always reexec ourself
  22. command := exec.Command(os.Args[0], append([]string{
  23. "-console", console,
  24. "-pipe", "3",
  25. "-root", c.Root,
  26. "init"}, args...)...)
  27. system.SetCloneFlags(command, uintptr(GetNamespaceFlags(container.Namespaces)))
  28. command.Env = container.Env
  29. command.ExtraFiles = []*os.File{pipe}
  30. return command
  31. }
  32. // GetNamespaceFlags parses the container's Namespaces options to set the correct
  33. // flags on clone, unshare, and setns
  34. func GetNamespaceFlags(namespaces libcontainer.Namespaces) (flag int) {
  35. for _, ns := range namespaces {
  36. flag |= ns.Value
  37. }
  38. return flag
  39. }