summaryrefslogtreecommitdiff
path: root/pkg/libcontainer/nsinit/command.go
blob: 153a48ab59a942690c92a8ba29145de9439ef21f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package nsinit

import (
	"github.com/dotcloud/docker/pkg/libcontainer"
	"github.com/dotcloud/docker/pkg/system"
	"os"
	"os/exec"
)

// 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
type CommandFactory interface {
	Create(container *libcontainer.Container, console string, syncFd *os.File, args []string) *exec.Cmd
}

type DefaultCommandFactory struct {
	Root string
}

// 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
func (c *DefaultCommandFactory) Create(container *libcontainer.Container, console string, pipe *os.File, args []string) *exec.Cmd {
	// get our binary name from arg0 so we can always reexec ourself
	command := exec.Command(os.Args[0], append([]string{
		"-console", console,
		"-pipe", "3",
		"-root", c.Root,
		"init"}, args...)...)

	system.SetCloneFlags(command, uintptr(GetNamespaceFlags(container.Namespaces)))
	command.Env = container.Env
	command.ExtraFiles = []*os.File{pipe}
	return command
}

// 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 {
		if ns.Enabled {
			flag |= ns.Value
		}
	}
	return flag
}