2014-02-22 08:29:21 +00:00
|
|
|
package nsinit
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"github.com/dotcloud/docker/pkg/libcontainer"
|
2014-02-25 23:19:13 +00:00
|
|
|
"github.com/dotcloud/docker/pkg/system"
|
2014-02-22 08:29:21 +00:00
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
)
|
|
|
|
|
2014-02-25 05:11:52 +00:00
|
|
|
// CommandFactory takes the container's configuration and options passed by the
|
|
|
|
// parent processes and creates an *exec.Cmd that will be used to fork/exec the
|
|
|
|
// namespaced init process
|
2014-02-22 08:29:21 +00:00
|
|
|
type CommandFactory interface {
|
2014-02-25 05:11:52 +00:00
|
|
|
Create(container *libcontainer.Container, console string, syncFd uintptr, args []string) *exec.Cmd
|
2014-02-22 08:29:21 +00:00
|
|
|
}
|
|
|
|
|
2014-02-25 23:19:13 +00:00
|
|
|
type DefaultCommandFactory struct {
|
|
|
|
Root string
|
|
|
|
}
|
2014-02-22 08:29:21 +00:00
|
|
|
|
|
|
|
// Create will return an exec.Cmd with the Cloneflags set to the proper namespaces
|
|
|
|
// defined on the container's configuration and use the current binary as the init with the
|
|
|
|
// args provided
|
2014-02-25 05:11:52 +00:00
|
|
|
func (c *DefaultCommandFactory) Create(container *libcontainer.Container, console string, pipe uintptr, args []string) *exec.Cmd {
|
2014-02-25 23:19:13 +00:00
|
|
|
// get our binary name from arg0 so we can always reexec ourself
|
|
|
|
command := exec.Command(os.Args[0], append([]string{
|
2014-02-22 08:29:21 +00:00
|
|
|
"-console", console,
|
|
|
|
"-pipe", fmt.Sprint(pipe),
|
2014-02-25 23:19:13 +00:00
|
|
|
"-root", c.Root,
|
2014-02-22 08:29:21 +00:00
|
|
|
"init"}, args...)...)
|
|
|
|
|
2014-02-25 23:19:13 +00:00
|
|
|
system.SetCloneFlags(command, uintptr(GetNamespaceFlags(container.Namespaces)))
|
2014-02-22 08:29:21 +00:00
|
|
|
command.Env = container.Env
|
|
|
|
return command
|
|
|
|
}
|
2014-02-25 23:19:13 +00:00
|
|
|
|
|
|
|
// GetNamespaceFlags parses the container's Namespaces options to set the correct
|
|
|
|
// flags on clone, unshare, and setns
|
|
|
|
func GetNamespaceFlags(namespaces libcontainer.Namespaces) (flag int) {
|
|
|
|
for _, ns := range namespaces {
|
|
|
|
flag |= ns.Value
|
|
|
|
}
|
|
|
|
return flag
|
|
|
|
}
|