Browse code

Fix exec driver flag, rename new driver to 'native' Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)

Michael Crosby authored on 2014/02/25 13:41:09
Showing 9 changed files
... ...
@@ -39,7 +39,7 @@ func main() {
39 39
 		flDefaultIp          = flag.String([]string{"#ip", "-ip"}, "0.0.0.0", "Default IP address to use when binding container ports")
40 40
 		flInterContainerComm = flag.Bool([]string{"#icc", "-icc"}, true, "Enable inter-container communication")
41 41
 		flGraphDriver        = flag.String([]string{"s", "-storage-driver"}, "", "Force the docker runtime to use a specific storage driver")
42
-		flExecDriver         = flag.String([]string{"e", "-exec-driver"}, "", "Force the docker runtime to use a specific exec driver")
42
+		flExecDriver         = flag.String([]string{"e", "-exec-driver"}, "native", "Force the docker runtime to use a specific exec driver")
43 43
 		flHosts              = opts.NewListOpts(api.ValidateHost)
44 44
 		flMtu                = flag.Int([]string{"#mtu", "-mtu"}, 0, "Set the containers network MTU; if no value is provided: default to the default route MTU or 1500 if no default route is available")
45 45
 	)
46 46
deleted file mode 100644
... ...
@@ -1,41 +0,0 @@
1
-package docker
2
-
3
-import (
4
-	"github.com/dotcloud/docker/pkg/cgroups"
5
-	"github.com/dotcloud/docker/pkg/libcontainer"
6
-)
7
-
8
-// getDefaultTemplate returns the docker default for
9
-// the libcontainer configuration file
10
-func getDefaultTemplate() *libcontainer.Container {
11
-	return &libcontainer.Container{
12
-		Capabilities: libcontainer.Capabilities{
13
-			libcontainer.CAP_SETPCAP,
14
-			libcontainer.CAP_SYS_MODULE,
15
-			libcontainer.CAP_SYS_RAWIO,
16
-			libcontainer.CAP_SYS_PACCT,
17
-			libcontainer.CAP_SYS_ADMIN,
18
-			libcontainer.CAP_SYS_NICE,
19
-			libcontainer.CAP_SYS_RESOURCE,
20
-			libcontainer.CAP_SYS_TIME,
21
-			libcontainer.CAP_SYS_TTY_CONFIG,
22
-			libcontainer.CAP_MKNOD,
23
-			libcontainer.CAP_AUDIT_WRITE,
24
-			libcontainer.CAP_AUDIT_CONTROL,
25
-			libcontainer.CAP_MAC_ADMIN,
26
-			libcontainer.CAP_MAC_OVERRIDE,
27
-			libcontainer.CAP_NET_ADMIN,
28
-		},
29
-		Namespaces: libcontainer.Namespaces{
30
-			libcontainer.CLONE_NEWIPC,
31
-			libcontainer.CLONE_NEWNET,
32
-			libcontainer.CLONE_NEWNS,
33
-			libcontainer.CLONE_NEWPID,
34
-			libcontainer.CLONE_NEWUTS,
35
-		},
36
-		Cgroups: &cgroups.Cgroup{
37
-			Parent:       "docker",
38
-			DeviceAccess: false,
39
-		},
40
-	}
41
-}
42 1
deleted file mode 100644
... ...
@@ -1,315 +0,0 @@
1
-package docker
2
-
3
-import (
4
-	"encoding/json"
5
-	"errors"
6
-	"fmt"
7
-	"github.com/dotcloud/docker/execdriver"
8
-	"github.com/dotcloud/docker/execdriver/lxc"
9
-	"github.com/dotcloud/docker/pkg/cgroups"
10
-	"github.com/dotcloud/docker/pkg/libcontainer"
11
-	"github.com/dotcloud/docker/pkg/libcontainer/nsinit"
12
-	"io"
13
-	"io/ioutil"
14
-	"log"
15
-	"os"
16
-	"os/exec"
17
-	"path/filepath"
18
-	"strconv"
19
-	"strings"
20
-	"syscall"
21
-)
22
-
23
-const (
24
-	DriverName = "namespaces"
25
-	Version    = "0.1"
26
-)
27
-
28
-var (
29
-	ErrNotSupported = errors.New("not supported")
30
-	noOpLog         = log.New(ioutil.Discard, "[nsinit] ", log.LstdFlags)
31
-)
32
-
33
-func init() {
34
-	execdriver.RegisterInitFunc(DriverName, func(args *execdriver.InitArgs) error {
35
-		var container *libcontainer.Container
36
-		f, err := os.Open("container.json")
37
-		if err != nil {
38
-			return err
39
-		}
40
-		if err := json.NewDecoder(f).Decode(&container); err != nil {
41
-			f.Close()
42
-			return err
43
-		}
44
-		f.Close()
45
-
46
-		cwd, err := os.Getwd()
47
-		if err != nil {
48
-			return err
49
-		}
50
-		syncPipe, err := nsinit.NewSyncPipeFromFd(0, uintptr(args.Pipe))
51
-		if err != nil {
52
-			return err
53
-		}
54
-		ns := nsinit.NewNsInit(noOpLog, "", &nsinit.DefaultCommandFactory{}, &nsinit.DefaultStateWriter{})
55
-		if err := ns.Init(container, cwd, args.Console, syncPipe, args.Args); err != nil {
56
-			return err
57
-		}
58
-		return nil
59
-	})
60
-}
61
-
62
-type driver struct {
63
-	root string
64
-}
65
-
66
-type info struct {
67
-	ID     string
68
-	driver *driver
69
-}
70
-
71
-func (i *info) IsRunning() bool {
72
-	p := filepath.Join(i.driver.root, "containers", i.ID, "root", ".nspid")
73
-	if _, err := os.Stat(p); err == nil {
74
-		return true
75
-	}
76
-	return false
77
-}
78
-
79
-func NewDriver(root string) (*driver, error) {
80
-	return &driver{
81
-		root: root,
82
-	}, nil
83
-}
84
-
85
-func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) {
86
-	var (
87
-		term        nsinit.Terminal
88
-		container   = createContainer(c)
89
-		factory     = &dockerCommandFactory{c}
90
-		stateWriter = &dockerStateWriter{
91
-			callback: startCallback,
92
-			c:        c,
93
-			dsw:      &nsinit.DefaultStateWriter{c.Rootfs},
94
-		}
95
-	)
96
-	ns := nsinit.NewNsInit(noOpLog, "", factory, stateWriter)
97
-	if c.Tty {
98
-		term = &dockerTtyTerm{
99
-			pipes: pipes,
100
-		}
101
-	} else {
102
-		term = &dockerStdTerm{
103
-			pipes: pipes,
104
-		}
105
-	}
106
-	c.Terminal = term
107
-	if err := writeContainerFile(container, c.Rootfs); err != nil {
108
-		return -1, err
109
-	}
110
-	args := append([]string{c.Entrypoint}, c.Arguments...)
111
-	return ns.Exec(container, term, args)
112
-}
113
-
114
-func (d *driver) Kill(p *execdriver.Command, sig int) error {
115
-	return syscall.Kill(p.Process.Pid, syscall.Signal(sig))
116
-}
117
-
118
-func (d *driver) Restore(c *execdriver.Command) error {
119
-	var (
120
-		nspid int
121
-		p     = filepath.Join(d.root, "containers", c.ID, "root", ".nspid")
122
-	)
123
-	f, err := os.Open(p)
124
-	if err != nil {
125
-		return err
126
-	}
127
-	defer f.Close()
128
-	if _, err := fmt.Fscanf(f, "%d", &nspid); err != nil {
129
-		return err
130
-	}
131
-	proc, err := os.FindProcess(nspid)
132
-	if err != nil {
133
-		return err
134
-	}
135
-	_, err = proc.Wait()
136
-	return err
137
-}
138
-
139
-func (d *driver) Info(id string) execdriver.Info {
140
-	return &info{
141
-		ID:     id,
142
-		driver: d,
143
-	}
144
-}
145
-
146
-func (d *driver) Name() string {
147
-	return fmt.Sprintf("%s-%s", DriverName, Version)
148
-}
149
-
150
-func (d *driver) GetPidsForContainer(id string) ([]int, error) {
151
-	pids := []int{}
152
-
153
-	subsystem := "devices"
154
-	cgroupRoot, err := cgroups.FindCgroupMountpoint(subsystem)
155
-	if err != nil {
156
-		return pids, err
157
-	}
158
-	cgroupDir, err := cgroups.GetThisCgroupDir(subsystem)
159
-	if err != nil {
160
-		return pids, err
161
-	}
162
-
163
-	filename := filepath.Join(cgroupRoot, cgroupDir, id, "tasks")
164
-	if _, err := os.Stat(filename); os.IsNotExist(err) {
165
-		filename = filepath.Join(cgroupRoot, cgroupDir, "docker", id, "tasks")
166
-	}
167
-
168
-	output, err := ioutil.ReadFile(filename)
169
-	if err != nil {
170
-		return pids, err
171
-	}
172
-	for _, p := range strings.Split(string(output), "\n") {
173
-		if len(p) == 0 {
174
-			continue
175
-		}
176
-		pid, err := strconv.Atoi(p)
177
-		if err != nil {
178
-			return pids, fmt.Errorf("Invalid pid '%s': %s", p, err)
179
-		}
180
-		pids = append(pids, pid)
181
-	}
182
-	return pids, nil
183
-}
184
-
185
-func writeContainerFile(container *libcontainer.Container, rootfs string) error {
186
-	data, err := json.Marshal(container)
187
-	if err != nil {
188
-		return err
189
-	}
190
-	return ioutil.WriteFile(filepath.Join(rootfs, "container.json"), data, 0755)
191
-}
192
-
193
-func getEnv(key string, env []string) string {
194
-	for _, pair := range env {
195
-		parts := strings.Split(pair, "=")
196
-		if parts[0] == key {
197
-			return parts[1]
198
-		}
199
-	}
200
-	return ""
201
-}
202
-
203
-type dockerCommandFactory struct {
204
-	c *execdriver.Command
205
-}
206
-
207
-// createCommand will return an exec.Cmd with the Cloneflags set to the proper namespaces
208
-// defined on the container's configuration and use the current binary as the init with the
209
-// args provided
210
-func (d *dockerCommandFactory) Create(container *libcontainer.Container,
211
-	console, logFile string, syncFd uintptr, args []string) *exec.Cmd {
212
-	c := d.c
213
-	// we need to join the rootfs because nsinit will setup the rootfs and chroot
214
-	initPath := filepath.Join(c.Rootfs, c.InitPath)
215
-
216
-	c.Path = initPath
217
-	c.Args = append([]string{
218
-		initPath,
219
-		"-driver", DriverName,
220
-		"-console", console,
221
-		"-pipe", fmt.Sprint(syncFd),
222
-		"-log", logFile,
223
-	}, args...)
224
-	c.SysProcAttr = &syscall.SysProcAttr{
225
-		Cloneflags: uintptr(nsinit.GetNamespaceFlags(container.Namespaces)),
226
-	}
227
-	c.Env = container.Env
228
-	c.Dir = c.Rootfs
229
-
230
-	return &c.Cmd
231
-}
232
-
233
-type dockerStateWriter struct {
234
-	dsw      nsinit.StateWriter
235
-	c        *execdriver.Command
236
-	callback execdriver.StartCallback
237
-}
238
-
239
-func (d *dockerStateWriter) WritePid(pid int) error {
240
-	err := d.dsw.WritePid(pid)
241
-	if d.callback != nil {
242
-		d.callback(d.c)
243
-	}
244
-	return err
245
-}
246
-
247
-func (d *dockerStateWriter) DeletePid() error {
248
-	return d.dsw.DeletePid()
249
-}
250
-
251
-func createContainer(c *execdriver.Command) *libcontainer.Container {
252
-	container := getDefaultTemplate()
253
-
254
-	container.Hostname = getEnv("HOSTNAME", c.Env)
255
-	container.Tty = c.Tty
256
-	container.User = c.User
257
-	container.WorkingDir = c.WorkingDir
258
-	container.Env = c.Env
259
-
260
-	container.Env = append(container.Env, "container=docker")
261
-
262
-	if c.Network != nil {
263
-		container.Network = &libcontainer.Network{
264
-			Mtu:     c.Network.Mtu,
265
-			Address: fmt.Sprintf("%s/%d", c.Network.IPAddress, c.Network.IPPrefixLen),
266
-			Gateway: c.Network.Gateway,
267
-			Type:    "veth",
268
-			Context: libcontainer.Context{
269
-				"prefix": "dock",
270
-				"bridge": c.Network.Bridge,
271
-			},
272
-		}
273
-	}
274
-	container.Cgroups.Name = c.ID
275
-	if c.Privileged {
276
-		container.Capabilities = nil
277
-		container.Cgroups.DeviceAccess = true
278
-	}
279
-	if c.Resources != nil {
280
-		container.Cgroups.CpuShares = c.Resources.CpuShares
281
-		container.Cgroups.Memory = c.Resources.Memory
282
-		container.Cgroups.MemorySwap = c.Resources.MemorySwap
283
-	}
284
-	return container
285
-}
286
-
287
-type dockerStdTerm struct {
288
-	lxc.StdConsole
289
-	pipes *execdriver.Pipes
290
-}
291
-
292
-func (d *dockerStdTerm) Attach(cmd *exec.Cmd) error {
293
-	return d.AttachPipes(cmd, d.pipes)
294
-}
295
-
296
-func (d *dockerStdTerm) SetMaster(master *os.File) {
297
-	// do nothing
298
-}
299
-
300
-type dockerTtyTerm struct {
301
-	lxc.TtyConsole
302
-	pipes *execdriver.Pipes
303
-}
304
-
305
-func (t *dockerTtyTerm) Attach(cmd *exec.Cmd) error {
306
-	go io.Copy(t.pipes.Stdout, t.MasterPty)
307
-	if t.pipes.Stdin != nil {
308
-		go io.Copy(t.MasterPty, t.pipes.Stdin)
309
-	}
310
-	return nil
311
-}
312
-
313
-func (t *dockerTtyTerm) SetMaster(master *os.File) {
314
-	t.MasterPty = master
315
-}
316 1
deleted file mode 100644
... ...
@@ -1,26 +0,0 @@
1
-package docker
2
-
3
-import (
4
-	"github.com/dotcloud/docker/execdriver"
5
-	"github.com/dotcloud/docker/pkg/term"
6
-	"os"
7
-)
8
-
9
-type NsinitTerm struct {
10
-	master *os.File
11
-}
12
-
13
-func NewTerm(pipes *execdriver.Pipes, master *os.File) *NsinitTerm {
14
-	return &NsinitTerm{master}
15
-}
16
-
17
-func (t *NsinitTerm) Close() error {
18
-	return t.master.Close()
19
-}
20
-
21
-func (t *NsinitTerm) Resize(h, w int) error {
22
-	if t.master != nil {
23
-		return term.SetWinsize(t.master.Fd(), &term.Winsize{Height: uint16(h), Width: uint16(w)})
24
-	}
25
-	return nil
26
-}
27 1
new file mode 100644
... ...
@@ -0,0 +1,41 @@
0
+package native
1
+
2
+import (
3
+	"github.com/dotcloud/docker/pkg/cgroups"
4
+	"github.com/dotcloud/docker/pkg/libcontainer"
5
+)
6
+
7
+// getDefaultTemplate returns the docker default for
8
+// the libcontainer configuration file
9
+func getDefaultTemplate() *libcontainer.Container {
10
+	return &libcontainer.Container{
11
+		Capabilities: libcontainer.Capabilities{
12
+			libcontainer.CAP_SETPCAP,
13
+			libcontainer.CAP_SYS_MODULE,
14
+			libcontainer.CAP_SYS_RAWIO,
15
+			libcontainer.CAP_SYS_PACCT,
16
+			libcontainer.CAP_SYS_ADMIN,
17
+			libcontainer.CAP_SYS_NICE,
18
+			libcontainer.CAP_SYS_RESOURCE,
19
+			libcontainer.CAP_SYS_TIME,
20
+			libcontainer.CAP_SYS_TTY_CONFIG,
21
+			libcontainer.CAP_MKNOD,
22
+			libcontainer.CAP_AUDIT_WRITE,
23
+			libcontainer.CAP_AUDIT_CONTROL,
24
+			libcontainer.CAP_MAC_ADMIN,
25
+			libcontainer.CAP_MAC_OVERRIDE,
26
+			libcontainer.CAP_NET_ADMIN,
27
+		},
28
+		Namespaces: libcontainer.Namespaces{
29
+			libcontainer.CLONE_NEWIPC,
30
+			libcontainer.CLONE_NEWNET,
31
+			libcontainer.CLONE_NEWNS,
32
+			libcontainer.CLONE_NEWPID,
33
+			libcontainer.CLONE_NEWUTS,
34
+		},
35
+		Cgroups: &cgroups.Cgroup{
36
+			Parent:       "docker",
37
+			DeviceAccess: false,
38
+		},
39
+	}
40
+}
0 41
new file mode 100644
... ...
@@ -0,0 +1,315 @@
0
+package native
1
+
2
+import (
3
+	"encoding/json"
4
+	"errors"
5
+	"fmt"
6
+	"github.com/dotcloud/docker/execdriver"
7
+	"github.com/dotcloud/docker/execdriver/lxc"
8
+	"github.com/dotcloud/docker/pkg/cgroups"
9
+	"github.com/dotcloud/docker/pkg/libcontainer"
10
+	"github.com/dotcloud/docker/pkg/libcontainer/nsinit"
11
+	"io"
12
+	"io/ioutil"
13
+	"log"
14
+	"os"
15
+	"os/exec"
16
+	"path/filepath"
17
+	"strconv"
18
+	"strings"
19
+	"syscall"
20
+)
21
+
22
+const (
23
+	DriverName = "namespaces"
24
+	Version    = "0.1"
25
+)
26
+
27
+var (
28
+	ErrNotSupported = errors.New("not supported")
29
+	noOpLog         = log.New(ioutil.Discard, "[nsinit] ", log.LstdFlags)
30
+)
31
+
32
+func init() {
33
+	execdriver.RegisterInitFunc(DriverName, func(args *execdriver.InitArgs) error {
34
+		var container *libcontainer.Container
35
+		f, err := os.Open("container.json")
36
+		if err != nil {
37
+			return err
38
+		}
39
+		if err := json.NewDecoder(f).Decode(&container); err != nil {
40
+			f.Close()
41
+			return err
42
+		}
43
+		f.Close()
44
+
45
+		cwd, err := os.Getwd()
46
+		if err != nil {
47
+			return err
48
+		}
49
+		syncPipe, err := nsinit.NewSyncPipeFromFd(0, uintptr(args.Pipe))
50
+		if err != nil {
51
+			return err
52
+		}
53
+		ns := nsinit.NewNsInit(noOpLog, "", &nsinit.DefaultCommandFactory{}, &nsinit.DefaultStateWriter{})
54
+		if err := ns.Init(container, cwd, args.Console, syncPipe, args.Args); err != nil {
55
+			return err
56
+		}
57
+		return nil
58
+	})
59
+}
60
+
61
+type driver struct {
62
+	root string
63
+}
64
+
65
+type info struct {
66
+	ID     string
67
+	driver *driver
68
+}
69
+
70
+func (i *info) IsRunning() bool {
71
+	p := filepath.Join(i.driver.root, "containers", i.ID, "root", ".nspid")
72
+	if _, err := os.Stat(p); err == nil {
73
+		return true
74
+	}
75
+	return false
76
+}
77
+
78
+func NewDriver(root string) (*driver, error) {
79
+	return &driver{
80
+		root: root,
81
+	}, nil
82
+}
83
+
84
+func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) {
85
+	var (
86
+		term        nsinit.Terminal
87
+		container   = createContainer(c)
88
+		factory     = &dockerCommandFactory{c}
89
+		stateWriter = &dockerStateWriter{
90
+			callback: startCallback,
91
+			c:        c,
92
+			dsw:      &nsinit.DefaultStateWriter{c.Rootfs},
93
+		}
94
+	)
95
+	ns := nsinit.NewNsInit(noOpLog, "", factory, stateWriter)
96
+	if c.Tty {
97
+		term = &dockerTtyTerm{
98
+			pipes: pipes,
99
+		}
100
+	} else {
101
+		term = &dockerStdTerm{
102
+			pipes: pipes,
103
+		}
104
+	}
105
+	c.Terminal = term
106
+	if err := writeContainerFile(container, c.Rootfs); err != nil {
107
+		return -1, err
108
+	}
109
+	args := append([]string{c.Entrypoint}, c.Arguments...)
110
+	return ns.Exec(container, term, args)
111
+}
112
+
113
+func (d *driver) Kill(p *execdriver.Command, sig int) error {
114
+	return syscall.Kill(p.Process.Pid, syscall.Signal(sig))
115
+}
116
+
117
+func (d *driver) Restore(c *execdriver.Command) error {
118
+	var (
119
+		nspid int
120
+		p     = filepath.Join(d.root, "containers", c.ID, "root", ".nspid")
121
+	)
122
+	f, err := os.Open(p)
123
+	if err != nil {
124
+		return err
125
+	}
126
+	defer f.Close()
127
+	if _, err := fmt.Fscanf(f, "%d", &nspid); err != nil {
128
+		return err
129
+	}
130
+	proc, err := os.FindProcess(nspid)
131
+	if err != nil {
132
+		return err
133
+	}
134
+	_, err = proc.Wait()
135
+	return err
136
+}
137
+
138
+func (d *driver) Info(id string) execdriver.Info {
139
+	return &info{
140
+		ID:     id,
141
+		driver: d,
142
+	}
143
+}
144
+
145
+func (d *driver) Name() string {
146
+	return fmt.Sprintf("%s-%s", DriverName, Version)
147
+}
148
+
149
+func (d *driver) GetPidsForContainer(id string) ([]int, error) {
150
+	pids := []int{}
151
+
152
+	subsystem := "devices"
153
+	cgroupRoot, err := cgroups.FindCgroupMountpoint(subsystem)
154
+	if err != nil {
155
+		return pids, err
156
+	}
157
+	cgroupDir, err := cgroups.GetThisCgroupDir(subsystem)
158
+	if err != nil {
159
+		return pids, err
160
+	}
161
+
162
+	filename := filepath.Join(cgroupRoot, cgroupDir, id, "tasks")
163
+	if _, err := os.Stat(filename); os.IsNotExist(err) {
164
+		filename = filepath.Join(cgroupRoot, cgroupDir, "docker", id, "tasks")
165
+	}
166
+
167
+	output, err := ioutil.ReadFile(filename)
168
+	if err != nil {
169
+		return pids, err
170
+	}
171
+	for _, p := range strings.Split(string(output), "\n") {
172
+		if len(p) == 0 {
173
+			continue
174
+		}
175
+		pid, err := strconv.Atoi(p)
176
+		if err != nil {
177
+			return pids, fmt.Errorf("Invalid pid '%s': %s", p, err)
178
+		}
179
+		pids = append(pids, pid)
180
+	}
181
+	return pids, nil
182
+}
183
+
184
+func writeContainerFile(container *libcontainer.Container, rootfs string) error {
185
+	data, err := json.Marshal(container)
186
+	if err != nil {
187
+		return err
188
+	}
189
+	return ioutil.WriteFile(filepath.Join(rootfs, "container.json"), data, 0755)
190
+}
191
+
192
+func getEnv(key string, env []string) string {
193
+	for _, pair := range env {
194
+		parts := strings.Split(pair, "=")
195
+		if parts[0] == key {
196
+			return parts[1]
197
+		}
198
+	}
199
+	return ""
200
+}
201
+
202
+type dockerCommandFactory struct {
203
+	c *execdriver.Command
204
+}
205
+
206
+// createCommand will return an exec.Cmd with the Cloneflags set to the proper namespaces
207
+// defined on the container's configuration and use the current binary as the init with the
208
+// args provided
209
+func (d *dockerCommandFactory) Create(container *libcontainer.Container,
210
+	console, logFile string, syncFd uintptr, args []string) *exec.Cmd {
211
+	c := d.c
212
+	// we need to join the rootfs because nsinit will setup the rootfs and chroot
213
+	initPath := filepath.Join(c.Rootfs, c.InitPath)
214
+
215
+	c.Path = initPath
216
+	c.Args = append([]string{
217
+		initPath,
218
+		"-driver", DriverName,
219
+		"-console", console,
220
+		"-pipe", fmt.Sprint(syncFd),
221
+		"-log", logFile,
222
+	}, args...)
223
+	c.SysProcAttr = &syscall.SysProcAttr{
224
+		Cloneflags: uintptr(nsinit.GetNamespaceFlags(container.Namespaces)),
225
+	}
226
+	c.Env = container.Env
227
+	c.Dir = c.Rootfs
228
+
229
+	return &c.Cmd
230
+}
231
+
232
+type dockerStateWriter struct {
233
+	dsw      nsinit.StateWriter
234
+	c        *execdriver.Command
235
+	callback execdriver.StartCallback
236
+}
237
+
238
+func (d *dockerStateWriter) WritePid(pid int) error {
239
+	err := d.dsw.WritePid(pid)
240
+	if d.callback != nil {
241
+		d.callback(d.c)
242
+	}
243
+	return err
244
+}
245
+
246
+func (d *dockerStateWriter) DeletePid() error {
247
+	return d.dsw.DeletePid()
248
+}
249
+
250
+func createContainer(c *execdriver.Command) *libcontainer.Container {
251
+	container := getDefaultTemplate()
252
+
253
+	container.Hostname = getEnv("HOSTNAME", c.Env)
254
+	container.Tty = c.Tty
255
+	container.User = c.User
256
+	container.WorkingDir = c.WorkingDir
257
+	container.Env = c.Env
258
+
259
+	container.Env = append(container.Env, "container=docker")
260
+
261
+	if c.Network != nil {
262
+		container.Network = &libcontainer.Network{
263
+			Mtu:     c.Network.Mtu,
264
+			Address: fmt.Sprintf("%s/%d", c.Network.IPAddress, c.Network.IPPrefixLen),
265
+			Gateway: c.Network.Gateway,
266
+			Type:    "veth",
267
+			Context: libcontainer.Context{
268
+				"prefix": "dock",
269
+				"bridge": c.Network.Bridge,
270
+			},
271
+		}
272
+	}
273
+	container.Cgroups.Name = c.ID
274
+	if c.Privileged {
275
+		container.Capabilities = nil
276
+		container.Cgroups.DeviceAccess = true
277
+	}
278
+	if c.Resources != nil {
279
+		container.Cgroups.CpuShares = c.Resources.CpuShares
280
+		container.Cgroups.Memory = c.Resources.Memory
281
+		container.Cgroups.MemorySwap = c.Resources.MemorySwap
282
+	}
283
+	return container
284
+}
285
+
286
+type dockerStdTerm struct {
287
+	lxc.StdConsole
288
+	pipes *execdriver.Pipes
289
+}
290
+
291
+func (d *dockerStdTerm) Attach(cmd *exec.Cmd) error {
292
+	return d.AttachPipes(cmd, d.pipes)
293
+}
294
+
295
+func (d *dockerStdTerm) SetMaster(master *os.File) {
296
+	// do nothing
297
+}
298
+
299
+type dockerTtyTerm struct {
300
+	lxc.TtyConsole
301
+	pipes *execdriver.Pipes
302
+}
303
+
304
+func (t *dockerTtyTerm) Attach(cmd *exec.Cmd) error {
305
+	go io.Copy(t.pipes.Stdout, t.MasterPty)
306
+	if t.pipes.Stdin != nil {
307
+		go io.Copy(t.MasterPty, t.pipes.Stdin)
308
+	}
309
+	return nil
310
+}
311
+
312
+func (t *dockerTtyTerm) SetMaster(master *os.File) {
313
+	t.MasterPty = master
314
+}
0 315
new file mode 100644
... ...
@@ -0,0 +1,26 @@
0
+package native
1
+
2
+import (
3
+	"github.com/dotcloud/docker/execdriver"
4
+	"github.com/dotcloud/docker/pkg/term"
5
+	"os"
6
+)
7
+
8
+type NsinitTerm struct {
9
+	master *os.File
10
+}
11
+
12
+func NewTerm(pipes *execdriver.Pipes, master *os.File) *NsinitTerm {
13
+	return &NsinitTerm{master}
14
+}
15
+
16
+func (t *NsinitTerm) Close() error {
17
+	return t.master.Close()
18
+}
19
+
20
+func (t *NsinitTerm) Resize(h, w int) error {
21
+	if t.master != nil {
22
+		return term.SetWinsize(t.master.Fd(), &term.Winsize{Height: uint16(h), Width: uint16(w)})
23
+	}
24
+	return nil
25
+}
... ...
@@ -7,8 +7,8 @@ import (
7 7
 	"github.com/dotcloud/docker/dockerversion"
8 8
 	"github.com/dotcloud/docker/engine"
9 9
 	"github.com/dotcloud/docker/execdriver"
10
-	"github.com/dotcloud/docker/execdriver/docker"
11 10
 	"github.com/dotcloud/docker/execdriver/lxc"
11
+	"github.com/dotcloud/docker/execdriver/native"
12 12
 	"github.com/dotcloud/docker/graphdriver"
13 13
 	"github.com/dotcloud/docker/graphdriver/aufs"
14 14
 	_ "github.com/dotcloud/docker/graphdriver/btrfs"
... ...
@@ -702,17 +702,18 @@ func NewRuntimeFromDirectory(config *DaemonConfig, eng *engine.Engine) (*Runtime
702 702
 		sysInitPath = localCopy
703 703
 	}
704 704
 
705
-	sysInfo := sysinfo.New(false)
705
+	var (
706
+		ed      execdriver.Driver
707
+		sysInfo = sysinfo.New(false)
708
+	)
706 709
 
707
-	var ed execdriver.Driver
708
-	utils.Debugf("execDriver: provided %s", config.ExecDriver)
709
-	if config.ExecDriver == "chroot" && false {
710
-		// chroot is presently a noop driver https://github.com/dotcloud/docker/pull/4189#issuecomment-35330655
711
-		ed, err = chroot.NewDriver()
712
-		utils.Debugf("execDriver: using chroot")
713
-	} else {
710
+	switch config.ExecDriver {
711
+	case "lxc":
714 712
 		ed, err = lxc.NewDriver(config.Root, sysInfo.AppArmor)
715
-		utils.Debugf("execDriver: using lxc")
713
+	case "native":
714
+		ed, err = native.NewDriver(config.Root)
715
+	default:
716
+		return nil, fmt.Errorf("unknow exec driver %s", config.ExecDriver)
716 717
 	}
717 718
 	if err != nil {
718 719
 		return nil, err
... ...
@@ -6,6 +6,7 @@ import (
6 6
 	"fmt"
7 7
 	"github.com/dotcloud/docker/execdriver"
8 8
 	_ "github.com/dotcloud/docker/execdriver/lxc"
9
+	_ "github.com/dotcloud/docker/execdriver/native"
9 10
 	"io"
10 11
 	"io/ioutil"
11 12
 	"log"