Skip to content
This repository was archived by the owner on Dec 13, 2018. It is now read-only.

Commit 6415e8b

Browse files
committed
Initial commit of libcontainer
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
0 parents commit 6415e8b

20 files changed

Lines changed: 1531 additions & 0 deletions

‎MAINTAINERS‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Michael Crosby <michael@crosbymichael.com> (@crosbymichael)
2+
Guillaume Charmes <guillaume@dotcloud.com> (@creack)

‎README.md‎

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
## libcontainer - reference implementation for containers
2+
3+
#### playground
4+
5+
6+
Use the cli package to test out functionality
7+
8+
First setup a container configuration. You will need a root fs, better go the path to a
9+
stopped docker container and use that.
10+
11+
12+
```json
13+
{
14+
"id": "koye",
15+
"namespace_pid": 12265,
16+
"command": {
17+
"args": [
18+
"/bin/bash"
19+
],
20+
"environment": [
21+
"HOME=/",
22+
"PATH=PATH=$PATH:/bin:/usr/bin:/sbin:/usr/sbin",
23+
"container=docker",
24+
"TERM=xterm"
25+
]
26+
},
27+
"rootfs": "/root/development/gocode/src/github.com/docker/libcontainer/namespaces/ubuntu",
28+
"network": null,
29+
"user": "",
30+
"working_dir": "",
31+
"namespaces": [
32+
"NEWNET",
33+
"NEWIPC",
34+
"NEWNS",
35+
"NEWPID",
36+
"NEWUTS"
37+
],
38+
"capabilities": [
39+
"SETPCAP",
40+
"SYS_MODULE",
41+
"SYS_RAWIO",
42+
"SYS_PACCT",
43+
"SYS_ADMIN",
44+
"SYS_NICE",
45+
"SYS_RESOURCE",
46+
"SYS_TIME",
47+
"SYS_TTY_CONFIG",
48+
"MKNOD",
49+
"AUDIT_WRITE",
50+
"AUDIT_CONTROL",
51+
"MAC_OVERRIDE",
52+
"MAC_ADMIN"
53+
]
54+
}
55+
```
56+
57+
After you have a json file and a rootfs path to use just run:
58+
`./cli exec container.json`
59+
60+
61+
If you want to attach to an existing namespace just use the same json
62+
file with the container still running and do:
63+
`./cli execin container.json`

‎capabilities/capabilities.go‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package capabilities
2+
3+
import (
4+
"github.com/dotcloud/docker/pkg/libcontainer"
5+
"github.com/syndtr/gocapability/capability"
6+
"os"
7+
)
8+
9+
varcapMap=map[libcontainer.Capability]capability.Cap{
10+
libcontainer.CAP_SETPCAP: capability.CAP_SETPCAP,
11+
libcontainer.CAP_SYS_MODULE: capability.CAP_SYS_MODULE,
12+
libcontainer.CAP_SYS_RAWIO: capability.CAP_SYS_RAWIO,
13+
libcontainer.CAP_SYS_PACCT: capability.CAP_SYS_PACCT,
14+
libcontainer.CAP_SYS_ADMIN: capability.CAP_SYS_ADMIN,
15+
libcontainer.CAP_SYS_NICE: capability.CAP_SYS_NICE,
16+
libcontainer.CAP_SYS_RESOURCE: capability.CAP_SYS_RESOURCE,
17+
libcontainer.CAP_SYS_TIME: capability.CAP_SYS_TIME,
18+
libcontainer.CAP_SYS_TTY_CONFIG: capability.CAP_SYS_TTY_CONFIG,
19+
libcontainer.CAP_MKNOD: capability.CAP_MKNOD,
20+
libcontainer.CAP_AUDIT_WRITE: capability.CAP_AUDIT_WRITE,
21+
libcontainer.CAP_AUDIT_CONTROL: capability.CAP_AUDIT_CONTROL,
22+
libcontainer.CAP_MAC_OVERRIDE: capability.CAP_MAC_OVERRIDE,
23+
libcontainer.CAP_MAC_ADMIN: capability.CAP_MAC_ADMIN,
24+
}
25+
26+
// DropCapabilities drops capabilities for the current process based
27+
// on the container's configuration.
28+
funcDropCapabilities(container*libcontainer.Container) error {
29+
ifdrop:=getCapabilities(container); len(drop) >0 {
30+
c, err:=capability.NewPid(os.Getpid())
31+
iferr!=nil {
32+
returnerr
33+
}
34+
c.Unset(capability.CAPS|capability.BOUNDS, drop...)
35+
36+
iferr:=c.Apply(capability.CAPS|capability.BOUNDS); err!=nil {
37+
returnerr
38+
}
39+
}
40+
returnnil
41+
}
42+
43+
funcgetCapabilities(container*libcontainer.Container) []capability.Cap {
44+
drop:= []capability.Cap{}
45+
for_, c:=rangecontainer.Capabilities {
46+
drop=append(drop, capMap[c])
47+
}
48+
returndrop
49+
}

‎cli/main.go‎

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"flag"
6+
"fmt"
7+
"github.com/dotcloud/docker/pkg/libcontainer"
8+
"github.com/dotcloud/docker/pkg/libcontainer/namespaces"
9+
"github.com/dotcloud/docker/pkg/libcontainer/network"
10+
"github.com/dotcloud/docker/pkg/libcontainer/utils"
11+
"os"
12+
)
13+
14+
var (
15+
displayPidbool
16+
newCommandstring
17+
usrNetbool
18+
)
19+
20+
funcinit() {
21+
flag.BoolVar(&displayPid, "pid", false, "display the pid before waiting")
22+
flag.StringVar(&newCommand, "cmd", "/bin/bash", "command to run in the existing namespace")
23+
flag.BoolVar(&usrNet, "net", false, "user a net namespace")
24+
flag.Parse()
25+
}
26+
27+
funcexec(container*libcontainer.Container) error {
28+
var (
29+
netFile*os.File
30+
errerror
31+
)
32+
container.NetNsFd=0
33+
34+
ifusrNet {
35+
netFile, err=os.Open("/root/nsroot/test")
36+
iferr!=nil {
37+
returnerr
38+
}
39+
container.NetNsFd=netFile.Fd()
40+
}
41+
42+
pid, err:=namespaces.Exec(container)
43+
iferr!=nil {
44+
returnfmt.Errorf("error exec container %s", err)
45+
}
46+
47+
ifdisplayPid {
48+
fmt.Println(pid)
49+
}
50+
51+
exitcode, err:=utils.WaitOnPid(pid)
52+
iferr!=nil {
53+
returnfmt.Errorf("error waiting on child %s", err)
54+
}
55+
fmt.Println(exitcode)
56+
ifusrNet {
57+
netFile.Close()
58+
iferr:=network.DeleteNetworkNamespace("/root/nsroot/test"); err!=nil {
59+
returnerr
60+
}
61+
}
62+
os.Exit(exitcode)
63+
returnnil
64+
}
65+
66+
funcexecIn(container*libcontainer.Container) error {
67+
f, err:=os.Open("/root/nsroot/test")
68+
iferr!=nil {
69+
returnerr
70+
}
71+
container.NetNsFd=f.Fd()
72+
pid, err:=namespaces.ExecIn(container, &libcontainer.Command{
73+
Env: container.Command.Env,
74+
Args: []string{
75+
newCommand,
76+
},
77+
})
78+
iferr!=nil {
79+
returnfmt.Errorf("error exexin container %s", err)
80+
}
81+
exitcode, err:=utils.WaitOnPid(pid)
82+
iferr!=nil {
83+
returnfmt.Errorf("error waiting on child %s", err)
84+
}
85+
os.Exit(exitcode)
86+
returnnil
87+
}
88+
89+
funccreateNet(config*libcontainer.Network) error {
90+
root:="/root/nsroot"
91+
iferr:=network.SetupNamespaceMountDir(root); err!=nil {
92+
returnerr
93+
}
94+
95+
nspath:=root+"/test"
96+
iferr:=network.CreateNetworkNamespace(nspath); err!=nil {
97+
returnnil
98+
}
99+
iferr:=network.CreateVethPair("veth0", config.TempVethName); err!=nil {
100+
returnerr
101+
}
102+
iferr:=network.SetInterfaceMaster("veth0", config.Bridge); err!=nil {
103+
returnerr
104+
}
105+
iferr:=network.InterfaceUp("veth0"); err!=nil {
106+
returnerr
107+
}
108+
109+
f, err:=os.Open(nspath)
110+
iferr!=nil {
111+
returnerr
112+
}
113+
deferf.Close()
114+
115+
iferr:=network.SetInterfaceInNamespaceFd("veth1", int(f.Fd())); err!=nil {
116+
returnerr
117+
}
118+
119+
/*
120+
if err := network.SetupVethInsideNamespace(f.Fd(), config); err != nil {
121+
return err
122+
}
123+
*/
124+
returnnil
125+
}
126+
127+
funcprintErr(errerror) {
128+
fmt.Fprintln(os.Stderr, err)
129+
os.Exit(1)
130+
}
131+
132+
funcmain() {
133+
var (
134+
errerror
135+
cliCmd=flag.Arg(0)
136+
config=flag.Arg(1)
137+
)
138+
f, err:=os.Open(config)
139+
iferr!=nil {
140+
printErr(err)
141+
}
142+
143+
dec:=json.NewDecoder(f)
144+
varcontainer*libcontainer.Container
145+
146+
iferr:=dec.Decode(&container); err!=nil {
147+
printErr(err)
148+
}
149+
f.Close()
150+
151+
switchcliCmd {
152+
case"exec":
153+
err=exec(container)
154+
case"execin":
155+
err=execIn(container)
156+
case"net":
157+
err=createNet(&libcontainer.Network{
158+
TempVethName: "veth1",
159+
IP: "172.17.0.100/16",
160+
Gateway: "172.17.42.1",
161+
Mtu: 1500,
162+
Bridge: "docker0",
163+
})
164+
default:
165+
err=fmt.Errorf("command not supported: %s", cliCmd)
166+
}
167+
168+
iferr!=nil {
169+
printErr(err)
170+
}
171+
}

‎container.go‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package libcontainer
2+
3+
typeContainerstruct {
4+
IDstring`json:"id,omitempty"`
5+
NsPidint`json:"namespace_pid,omitempty"`
6+
Command*Command`json:"command,omitempty"`
7+
RootFsstring`json:"rootfs,omitempty"`
8+
ReadonlyFsbool`json:"readonly_fs,omitempty"`
9+
NetNsFduintptr`json:"network_namespace_fd,omitempty"`
10+
Userstring`json:"user,omitempty"`
11+
WorkingDirstring`json:"working_dir,omitempty"`
12+
NamespacesNamespaces`json:"namespaces,omitempty"`
13+
CapabilitiesCapabilities`json:"capabilities,omitempty"`
14+
}
15+
16+
typeCommandstruct {
17+
Args []string`json:"args,omitempty"`
18+
Env []string`json:"environment,omitempty"`
19+
}
20+
21+
typeNetworkstruct {
22+
TempVethNamestring`json:"temp_veth,omitempty"`
23+
IPstring`json:"ip,omitempty"`
24+
Gatewaystring`json:"gateway,omitempty"`
25+
Bridgestring`json:"bridge,omitempty"`
26+
Mtuint`json:"mtu,omitempty"`
27+
}

‎container.json‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"id": "koye",
3+
"namespace_pid": 3117,
4+
"command": {
5+
"args": [
6+
"/bin/bash"
7+
],
8+
"environment": [
9+
"HOME=/",
10+
"PATH=PATH=$PATH:/bin:/usr/bin:/sbin:/usr/sbin",
11+
"container=docker",
12+
"TERM=xterm"
13+
]
14+
},
15+
"rootfs": "/root/main/mycontainer",
16+
"namespaces": [
17+
"NEWIPC",
18+
"NEWNS",
19+
"NEWPID",
20+
"NEWUTS"
21+
],
22+
"capabilities": [
23+
"SETPCAP",
24+
"SYS_MODULE",
25+
"SYS_RAWIO",
26+
"SYS_PACCT",
27+
"SYS_ADMIN",
28+
"SYS_NICE",
29+
"SYS_RESOURCE",
30+
"SYS_TIME",
31+
"SYS_TTY_CONFIG",
32+
"MKNOD",
33+
"AUDIT_WRITE",
34+
"AUDIT_CONTROL",
35+
"MAC_OVERRIDE",
36+
"MAC_ADMIN"
37+
]
38+
}

‎errors.go‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package libcontainer
2+
3+
import (
4+
"errors"
5+
)
6+
7+
var (
8+
ErrInvalidPid=errors.New("no ns pid found")
9+
)

0 commit comments

Comments
 (0)