... | ... |
@@ -7,6 +7,7 @@ import ( |
7 | 7 |
"github.com/dotcloud/docker/pkg/cgroups" |
8 | 8 |
"github.com/dotcloud/docker/pkg/libcontainer" |
9 | 9 |
"github.com/dotcloud/docker/pkg/libcontainer/nsinit" |
10 |
+ "github.com/dotcloud/docker/pkg/system" |
|
10 | 11 |
"io/ioutil" |
11 | 12 |
"os" |
12 | 13 |
"os/exec" |
... | ... |
@@ -215,9 +216,11 @@ func (d *dockerCommandFactory) Create(container *libcontainer.Container, console |
215 | 215 |
"-pipe", fmt.Sprint(syncFd), |
216 | 216 |
"-root", filepath.Join(d.driver.root, d.c.ID), |
217 | 217 |
}, args...) |
218 |
- d.c.SysProcAttr = &syscall.SysProcAttr{ |
|
219 |
- Cloneflags: uintptr(nsinit.GetNamespaceFlags(container.Namespaces)), |
|
220 |
- } |
|
218 |
+ |
|
219 |
+ // set this to nil so that when we set the clone flags anything else is reset |
|
220 |
+ d.c.SysProcAttr = nil |
|
221 |
+ system.SetCloneFlags(&d.c.Cmd, uintptr(nsinit.GetNamespaceFlags(container.Namespaces))) |
|
222 |
+ |
|
221 | 223 |
d.c.Env = container.Env |
222 | 224 |
d.c.Dir = d.c.Rootfs |
223 | 225 |
|
... | ... |
@@ -3,9 +3,9 @@ package nsinit |
3 | 3 |
import ( |
4 | 4 |
"fmt" |
5 | 5 |
"github.com/dotcloud/docker/pkg/libcontainer" |
6 |
+ "github.com/dotcloud/docker/pkg/system" |
|
6 | 7 |
"os" |
7 | 8 |
"os/exec" |
8 |
- "syscall" |
|
9 | 9 |
) |
10 | 10 |
|
11 | 11 |
// CommandFactory takes the container's configuration and options passed by the |
... | ... |
@@ -15,22 +15,31 @@ type CommandFactory interface { |
15 | 15 |
Create(container *libcontainer.Container, console string, syncFd uintptr, args []string) *exec.Cmd |
16 | 16 |
} |
17 | 17 |
|
18 |
-type DefaultCommandFactory struct{} |
|
18 |
+type DefaultCommandFactory struct { |
|
19 |
+ Root string |
|
20 |
+} |
|
19 | 21 |
|
20 | 22 |
// Create will return an exec.Cmd with the Cloneflags set to the proper namespaces |
21 | 23 |
// defined on the container's configuration and use the current binary as the init with the |
22 | 24 |
// args provided |
23 | 25 |
func (c *DefaultCommandFactory) Create(container *libcontainer.Container, console string, pipe uintptr, args []string) *exec.Cmd { |
24 |
- // get our binary name so we can always reexec ourself |
|
25 |
- name := os.Args[0] |
|
26 |
- command := exec.Command(name, append([]string{ |
|
26 |
+ // get our binary name from arg0 so we can always reexec ourself |
|
27 |
+ command := exec.Command(os.Args[0], append([]string{ |
|
27 | 28 |
"-console", console, |
28 | 29 |
"-pipe", fmt.Sprint(pipe), |
30 |
+ "-root", c.Root, |
|
29 | 31 |
"init"}, args...)...) |
30 | 32 |
|
31 |
- command.SysProcAttr = &syscall.SysProcAttr{ |
|
32 |
- Cloneflags: uintptr(GetNamespaceFlags(container.Namespaces)), |
|
33 |
- } |
|
33 |
+ system.SetCloneFlags(command, uintptr(GetNamespaceFlags(container.Namespaces))) |
|
34 | 34 |
command.Env = container.Env |
35 | 35 |
return command |
36 | 36 |
} |
37 |
+ |
|
38 |
+// GetNamespaceFlags parses the container's Namespaces options to set the correct |
|
39 |
+// flags on clone, unshare, and setns |
|
40 |
+func GetNamespaceFlags(namespaces libcontainer.Namespaces) (flag int) { |
|
41 |
+ for _, ns := range namespaces { |
|
42 |
+ flag |= ns.Value |
|
43 |
+ } |
|
44 |
+ return flag |
|
45 |
+} |
4 | 6 |
deleted file mode 100644 |
... | ... |
@@ -1,14 +0,0 @@ |
1 |
-package nsinit |
|
2 |
- |
|
3 |
-import ( |
|
4 |
- "github.com/dotcloud/docker/pkg/libcontainer" |
|
5 |
-) |
|
6 |
- |
|
7 |
-// getNamespaceFlags parses the container's Namespaces options to set the correct |
|
8 |
-// flags on clone, unshare, and setns |
|
9 |
-func GetNamespaceFlags(namespaces libcontainer.Namespaces) (flag int) { |
|
10 |
- for _, ns := range namespaces { |
|
11 |
- flag |= ns.Value |
|
12 |
- } |
|
13 |
- return flag |
|
14 |
-} |
... | ... |
@@ -2,7 +2,6 @@ package main |
2 | 2 |
|
3 | 3 |
import ( |
4 | 4 |
"encoding/json" |
5 |
- "errors" |
|
6 | 5 |
"flag" |
7 | 6 |
"github.com/dotcloud/docker/pkg/libcontainer" |
8 | 7 |
"github.com/dotcloud/docker/pkg/libcontainer/nsinit" |
... | ... |
@@ -18,11 +17,6 @@ var ( |
18 | 18 |
pipeFd int |
19 | 19 |
) |
20 | 20 |
|
21 |
-var ( |
|
22 |
- ErrUnsupported = errors.New("Unsupported method") |
|
23 |
- ErrWrongArguments = errors.New("Wrong argument count") |
|
24 |
-) |
|
25 |
- |
|
26 | 21 |
func registerFlags() { |
27 | 22 |
flag.StringVar(&console, "console", "", "console (pty slave) path") |
28 | 23 |
flag.IntVar(&pipeFd, "pipe", 0, "sync pipe fd") |
... | ... |
@@ -35,7 +29,7 @@ func main() { |
35 | 35 |
registerFlags() |
36 | 36 |
|
37 | 37 |
if flag.NArg() < 1 { |
38 |
- log.Fatal(ErrWrongArguments) |
|
38 |
+ log.Fatalf("wrong number of argments %d", flag.NArg()) |
|
39 | 39 |
} |
40 | 40 |
container, err := loadContainer() |
41 | 41 |
if err != nil { |
... | ... |
@@ -71,7 +65,7 @@ func main() { |
71 | 71 |
log.Fatal(err) |
72 | 72 |
} |
73 | 73 |
if flag.NArg() < 2 { |
74 |
- log.Fatal(ErrWrongArguments) |
|
74 |
+ log.Fatalf("wrong number of argments %d", flag.NArg()) |
|
75 | 75 |
} |
76 | 76 |
syncPipe, err := nsinit.NewSyncPipeFromFd(0, uintptr(pipeFd)) |
77 | 77 |
if err != nil { |
... | ... |
@@ -112,5 +106,5 @@ func readPid() (int, error) { |
112 | 112 |
} |
113 | 113 |
|
114 | 114 |
func newNsInit() (nsinit.NsInit, error) { |
115 |
- return nsinit.NewNsInit(&nsinit.DefaultCommandFactory{}, &nsinit.DefaultStateWriter{root}), nil |
|
115 |
+ return nsinit.NewNsInit(&nsinit.DefaultCommandFactory{root}, &nsinit.DefaultStateWriter{root}), nil |
|
116 | 116 |
} |
117 | 117 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,19 @@ |
0 |
+// +build !linux |
|
1 |
+ |
|
2 |
+package nsinit |
|
3 |
+ |
|
4 |
+import ( |
|
5 |
+ "github.com/dotcloud/docker/pkg/libcontainer" |
|
6 |
+) |
|
7 |
+ |
|
8 |
+func (ns *linuxNs) Exec(container *libcontainer.Container, term Terminal, args []string) (int, error) { |
|
9 |
+ return -1, libcontainer.ErrUnsupported |
|
10 |
+} |
|
11 |
+ |
|
12 |
+func (ns *linuxNs) ExecIn(container *libcontainer.Container, nspid int, args []string) (int, error) { |
|
13 |
+ return -1, libcontainer.ErrUnsupported |
|
14 |
+} |
|
15 |
+ |
|
16 |
+func (ns *linuxNs) Init(container *libcontainer.Container, uncleanRootfs, console string, syncPipe *SyncPipe, args []string) error { |
|
17 |
+ return libcontainer.ErrUnsupported |
|
18 |
+} |
... | ... |
@@ -5,25 +5,20 @@ import ( |
5 | 5 |
"errors" |
6 | 6 |
"github.com/syndtr/gocapability/capability" |
7 | 7 |
"os" |
8 |
- "syscall" |
|
9 | 8 |
) |
10 | 9 |
|
11 | 10 |
var ( |
12 |
- ErrUnkownNamespace error = errors.New("Unkown namespace") |
|
11 |
+ ErrUnkownNamespace = errors.New("Unknown namespace") |
|
12 |
+ ErrUnkownCapability = errors.New("Unknown capability") |
|
13 |
+ ErrUnsupported = errors.New("Unsupported method") |
|
13 | 14 |
) |
14 | 15 |
|
15 | 16 |
// namespaceList is used to convert the libcontainer types |
16 | 17 |
// into the names of the files located in /proc/<pid>/ns/* for |
17 | 18 |
// each namespace |
18 | 19 |
var ( |
19 |
- namespaceList = Namespaces{ |
|
20 |
- {Key: "NEWNS", Value: syscall.CLONE_NEWNS, File: "mnt"}, |
|
21 |
- {Key: "NEWUTS", Value: syscall.CLONE_NEWUTS, File: "uts"}, |
|
22 |
- {Key: "NEWIPC", Value: syscall.CLONE_NEWIPC, File: "ipc"}, |
|
23 |
- {Key: "NEWUSER", Value: syscall.CLONE_NEWUSER, File: "user"}, |
|
24 |
- {Key: "NEWPID", Value: syscall.CLONE_NEWPID, File: "pid"}, |
|
25 |
- {Key: "NEWNET", Value: syscall.CLONE_NEWNET, File: "net"}, |
|
26 |
- } |
|
20 |
+ namespaceList = Namespaces{} |
|
21 |
+ |
|
27 | 22 |
capabilityList = Capabilities{ |
28 | 23 |
{Key: "SETPCAP", Value: capability.CAP_SETPCAP}, |
29 | 24 |
{Key: "SYS_MODULE", Value: capability.CAP_SYS_MODULE}, |
... | ... |
@@ -52,6 +47,10 @@ type ( |
52 | 52 |
Namespaces []*Namespace |
53 | 53 |
) |
54 | 54 |
|
55 |
+func (ns *Namespace) String() string { |
|
56 |
+ return ns.Key |
|
57 |
+} |
|
58 |
+ |
|
55 | 59 |
func (ns *Namespace) MarshalJSON() ([]byte, error) { |
56 | 60 |
return json.Marshal(ns.Key) |
57 | 61 |
} |
... | ... |
@@ -95,20 +94,24 @@ type ( |
95 | 95 |
Capabilities []*Capability |
96 | 96 |
) |
97 | 97 |
|
98 |
-func (ns *Capability) MarshalJSON() ([]byte, error) { |
|
99 |
- return json.Marshal(ns.Key) |
|
98 |
+func (c *Capability) String() string { |
|
99 |
+ return c.Key |
|
100 | 100 |
} |
101 | 101 |
|
102 |
-func (ns *Capability) UnmarshalJSON(src []byte) error { |
|
102 |
+func (c *Capability) MarshalJSON() ([]byte, error) { |
|
103 |
+ return json.Marshal(c.Key) |
|
104 |
+} |
|
105 |
+ |
|
106 |
+func (c *Capability) UnmarshalJSON(src []byte) error { |
|
103 | 107 |
var capName string |
104 | 108 |
if err := json.Unmarshal(src, &capName); err != nil { |
105 | 109 |
return err |
106 | 110 |
} |
107 | 111 |
ret := GetCapability(capName) |
108 | 112 |
if ret == nil { |
109 |
- return ErrUnkownNamespace |
|
113 |
+ return ErrUnkownCapability |
|
110 | 114 |
} |
111 |
- *ns = *ret |
|
115 |
+ *c = *ret |
|
112 | 116 |
return nil |
113 | 117 |
} |
114 | 118 |
|
... | ... |
@@ -119,7 +122,7 @@ func GetCapability(key string) *Capability { |
119 | 119 |
} |
120 | 120 |
} |
121 | 121 |
if os.Getenv("DEBUG") != "" { |
122 |
- panic("Unreachable: Namespace not found") |
|
122 |
+ panic("Unreachable: Capability not found") |
|
123 | 123 |
} |
124 | 124 |
return nil |
125 | 125 |
} |
126 | 126 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,16 @@ |
0 |
+package libcontainer |
|
1 |
+ |
|
2 |
+import ( |
|
3 |
+ "syscall" |
|
4 |
+) |
|
5 |
+ |
|
6 |
+func init() { |
|
7 |
+ namespaceList = Namespaces{ |
|
8 |
+ {Key: "NEWNS", Value: syscall.CLONE_NEWNS, File: "mnt"}, |
|
9 |
+ {Key: "NEWUTS", Value: syscall.CLONE_NEWUTS, File: "uts"}, |
|
10 |
+ {Key: "NEWIPC", Value: syscall.CLONE_NEWIPC, File: "ipc"}, |
|
11 |
+ {Key: "NEWUSER", Value: syscall.CLONE_NEWUSER, File: "user"}, |
|
12 |
+ {Key: "NEWPID", Value: syscall.CLONE_NEWPID, File: "pid"}, |
|
13 |
+ {Key: "NEWNET", Value: syscall.CLONE_NEWNET, File: "net"}, |
|
14 |
+ } |
|
15 |
+} |
... | ... |
@@ -136,3 +136,10 @@ func Mkfifo(name string, mode uint32) error { |
136 | 136 |
func Umask(mask int) int { |
137 | 137 |
return syscall.Umask(mask) |
138 | 138 |
} |
139 |
+ |
|
140 |
+func SetCloneFlags(cmd *exec.Cmd, flag uintptr) { |
|
141 |
+ if cmd.SysProcAttr == nil { |
|
142 |
+ cmd.SysProcAttr = &syscall.SysProcAttr{} |
|
143 |
+ } |
|
144 |
+ cmd.SysProcAttr.Cloneflags = flag |
|
145 |
+} |
... | ... |
@@ -1,16 +1,11 @@ |
1 | 1 |
package system |
2 | 2 |
|
3 | 3 |
import ( |
4 |
- "errors" |
|
5 | 4 |
"fmt" |
6 | 5 |
"runtime" |
7 | 6 |
"syscall" |
8 | 7 |
) |
9 | 8 |
|
10 |
-var ( |
|
11 |
- ErrNotSupportedPlatform = errors.New("platform and architecture is not supported") |
|
12 |
-) |
|
13 |
- |
|
14 | 9 |
// Via http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=7b21fddd087678a70ad64afc0f632e0f1071b092 |
15 | 10 |
// |
16 | 11 |
// We need different setns values for the different platforms and arch |
... | ... |
@@ -709,9 +709,12 @@ func NewRuntimeFromDirectory(config *DaemonConfig, eng *engine.Engine) (*Runtime |
709 | 709 |
|
710 | 710 |
switch config.ExecDriver { |
711 | 711 |
case "lxc": |
712 |
+ // we want to five the lxc driver the full docker root because it needs |
|
713 |
+ // to access and write config and template files in /var/lib/docker/containers/* |
|
714 |
+ // to be backwards compatible |
|
712 | 715 |
ed, err = lxc.NewDriver(config.Root, sysInfo.AppArmor) |
713 | 716 |
case "native": |
714 |
- ed, err = native.NewDriver(path.Join(config.Root, "native")) |
|
717 |
+ ed, err = native.NewDriver(path.Join(config.Root, "execdriver", "native")) |
|
715 | 718 |
default: |
716 | 719 |
return nil, fmt.Errorf("unknown exec driver %s", config.ExecDriver) |
717 | 720 |
} |