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

Commit 5b73860

Browse files
committed
Merge pull request #388 from docker/api
Merge API Branch into Master
2 parents f4a4391 + 7eceabd commit 5b73860

File tree

150 files changed

+9185
-5640
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

150 files changed

+9185
-5640
lines changed

.drone.yml

-1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,4 @@ script:
66
- bash /go/src/github.com/docker/docker/hack/make/validate-dco
77
- bash /go/src/github.com/docker/docker/hack/make/validate-gofmt
88
- export GOPATH="$GOPATH:/go:$(pwd)/vendor" # Drone mucks with our GOPATH
9-
- go get golang.org/x/tools/cmd/vet && go vet ./...
109
- make direct-test

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
nsinit/nsinit

Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,5 @@ direct-build:
2222

2323
direct-install:
2424
go install -v $(GO_PACKAGES)
25+
local:
26+
go test -v

PRINCIPLES.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ In the design and development of libcontainer we try to follow these principles:
88
* Less code is better.
99
* Fewer components are better. Do you really need to add one more class?
1010
* 50 lines of straightforward, readable code is better than 10 lines of magic that nobody can understand.
11-
* Don't do later what you can do now. "//FIXME: refactor" is not acceptable in new code.
11+
* Don't do later what you can do now. "//TODO: refactor" is not acceptable in new code.
1212
* When hesitating between two options, choose the one that is easier to reverse.
1313
* "No" is temporary; "Yes" is forever. If you're not sure about a new feature, say no. You can change your mind later.
1414
* Containers must be portable to the greatest possible number of machines. Be suspicious of any change which makes machines less interchangeable.

README.md

+138-17
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,169 @@
11
## libcontainer - reference implementation for containers [![Build Status](https://ci.dockerproject.com/github.com/docker/libcontainer/status.svg?branch=master)](https://ci.dockerproject.com/github.com/docker/libcontainer)
22

3-
### Note on API changes:
3+
Libcontainer provides a native Go implementation for creating containers
4+
with namespaces, cgroups, capabilities, and filesystem access controls.
5+
It allows you to manage the lifecycle of the container performing additional operations
6+
after the container is created.
47

5-
Please bear with us while we work on making the libcontainer API stable and something that we can support long term. We are currently discussing the API with the community, therefore, if you currently depend on libcontainer please pin your dependency at a specific tag or commit id. Please join the discussion and help shape the API.
68

7-
#### Background
9+
#### Container
10+
A container is a self contained execution environment that shares the kernel of the
11+
host system and which is (optionally) isolated from other containers in the system.
812

9-
libcontainer specifies configuration options for what a container is. It provides a native Go implementation for using Linux namespaces with no external dependencies. libcontainer provides many convenience functions for working with namespaces, networking, and management.
13+
#### Using libcontainer
1014

15+
To create a container you first have to initialize an instance of a factory
16+
that will handle the creation and initialization for a container.
1117

12-
#### Container
13-
A container is a self contained execution environment that shares the kernel of the host system and which is (optionally) isolated from other containers in the system.
18+
Because containers are spawned in a two step process you will need to provide
19+
arguments to a binary that will be executed as the init process for the container.
20+
To use the current binary that is spawning the containers and acting as the parent
21+
you can use `os.Args[0]` and we have a command called `init` setup.
22+
23+
```go
24+
initArgs := []string{os.Args[0], "init"}
25+
26+
root, err := libcontainer.New("/var/lib/container", initArgs)
27+
if err != nil {
28+
log.Fatal(err)
29+
}
30+
```
1431

15-
libcontainer may be used to execute a process in a container. If a user tries to run a new process inside an existing container, the new process is added to the processes executing in the container.
32+
Once you have an instance of the factory created we can create a configuration
33+
struct describing how the container is to be created. A sample would look similar to this:
34+
35+
```go
36+
config := &configs.Config{
37+
Rootfs: rootfs,
38+
Capabilities: []string{
39+
"CHOWN",
40+
"DAC_OVERRIDE",
41+
"FSETID",
42+
"FOWNER",
43+
"MKNOD",
44+
"NET_RAW",
45+
"SETGID",
46+
"SETUID",
47+
"SETFCAP",
48+
"SETPCAP",
49+
"NET_BIND_SERVICE",
50+
"SYS_CHROOT",
51+
"KILL",
52+
"AUDIT_WRITE",
53+
},
54+
Namespaces: configs.Namespaces([]configs.Namespace{
55+
{Type: configs.NEWNS},
56+
{Type: configs.NEWUTS},
57+
{Type: configs.NEWIPC},
58+
{Type: configs.NEWPID},
59+
{Type: configs.NEWNET},
60+
}),
61+
Cgroups: &configs.Cgroup{
62+
Name: "test-container",
63+
Parent: "system",
64+
AllowAllDevices: false,
65+
AllowedDevices: configs.DefaultAllowedDevices,
66+
},
67+
68+
Devices: configs.DefaultAutoCreatedDevices,
69+
Hostname: "testing",
70+
Networks: []*configs.Network{
71+
{
72+
Type: "loopback",
73+
Address: "127.0.0.1/0",
74+
Gateway: "localhost",
75+
},
76+
},
77+
Rlimits: []configs.Rlimit{
78+
{
79+
Type: syscall.RLIMIT_NOFILE,
80+
Hard: uint64(1024),
81+
Soft: uint64(1024),
82+
},
83+
},
84+
}
85+
```
86+
87+
Once you have the configuration populated you can create a container:
88+
89+
```go
90+
container, err := root.Create("container-id", config)
91+
```
1692

93+
To spawn bash as the initial process inside the container and have the
94+
processes pid returned in order to wait, signal, or kill the process:
1795

18-
#### Root file system
96+
```go
97+
process := &libcontainer.Process{
98+
Args: []string{"/bin/bash"},
99+
Env: []string{"PATH=/bin"},
100+
User: "daemon",
101+
Stdin: os.Stdin,
102+
Stdout: os.Stdout,
103+
Stderr: os.Stderr,
104+
}
19105

20-
A container runs with a directory known as its *root file system*, or *rootfs*, mounted as the file system root. The rootfs is usually a full system tree.
106+
pid, err := container.Start(process)
107+
if err != nil {
108+
log.Fatal(err)
109+
}
21110

22111

23-
#### Configuration
112+
// wait for the process to finish.
113+
wait(pid)
24114

25-
A container is initially configured by supplying configuration data when the container is created.
115+
// destroy the container.
116+
container.Destroy()
117+
```
118+
119+
Additional ways to interact with a running container are:
120+
121+
```go
122+
// return all the pids for all processes running inside the container.
123+
processes, err := container.Processes()
124+
125+
// get detailed cpu, memory, io, and network statistics for the container and
126+
// it's processes.
127+
stats, err := container.Stats()
128+
129+
130+
// pause all processes inside the container.
131+
container.Pause()
132+
133+
// resume all paused processes.
134+
container.Resume()
135+
```
26136

27137

28138
#### nsinit
29139

30-
`nsinit` is a cli application which demonstrates the use of libcontainer. It is able to spawn new containers or join existing containers, based on the current directory.
140+
`nsinit` is a cli application which demonstrates the use of libcontainer.
141+
It is able to spawn new containers or join existing containers. A root
142+
filesystem must be provided for use along with a container configuration file.
31143

32-
To use `nsinit`, cd into a Linux rootfs and copy a `container.json` file into the directory with your specified configuration. Environment, networking, and different capabilities for the container are specified in this file. The configuration is used for each process executed inside the container.
144+
To use `nsinit`, cd into a Linux rootfs and copy a `container.json` file into
145+
the directory with your specified configuration. Environment, networking,
146+
and different capabilities for the container are specified in this file.
147+
The configuration is used for each process executed inside the container.
33148

34149
See the `sample_configs` folder for examples of what the container configuration should look like.
35150

36151
To execute `/bin/bash` in the current directory as a container just run the following **as root**:
37152
```bash
38-
nsinit exec /bin/bash
153+
nsinit exec --tty /bin/bash
39154
```
40155

41-
If you wish to spawn another process inside the container while your current bash session is running, run the same command again to get another bash shell (or change the command). If the original process (PID 1) dies, all other processes spawned inside the container will be killed and the namespace will be removed.
156+
If you wish to spawn another process inside the container while your
157+
current bash session is running, run the same command again to
158+
get another bash shell (or change the command). If the original
159+
process (PID 1) dies, all other processes spawned inside the container
160+
will be killed and the namespace will be removed.
42161

43-
You can identify if a process is running in a container by looking to see if `state.json` is in the root of the directory.
162+
You can identify if a process is running in a container by
163+
looking to see if `state.json` is in the root of the directory.
44164

45-
You may also specify an alternate root place where the `container.json` file is read and where the `state.json` file will be saved.
165+
You may also specify an alternate root place where
166+
the `container.json` file is read and where the `state.json` file will be saved.
46167

47168
#### Future
48169
See the [roadmap](ROADMAP.md).

api_temp.go

-21
This file was deleted.

apparmor/apparmor.go

-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ func ApplyProfile(name string) error {
2424
if name == "" {
2525
return nil
2626
}
27-
2827
cName := C.CString(name)
2928
defer C.free(unsafe.Pointer(cName))
3029

cgroups/cgroups.go

+26-27
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,35 @@ package cgroups
33
import (
44
"fmt"
55

6-
"github.com/docker/libcontainer/devices"
6+
"github.com/docker/libcontainer/configs"
77
)
88

9-
type FreezerState string
9+
type Manager interface {
10+
// Apply cgroup configuration to the process with the specified pid
11+
Apply(pid int) error
1012

11-
const (
12-
Undefined FreezerState = ""
13-
Frozen FreezerState = "FROZEN"
14-
Thawed FreezerState = "THAWED"
15-
)
13+
// Returns the PIDs inside the cgroup set
14+
GetPids() ([]int, error)
15+
16+
// Returns statistics for the cgroup set
17+
GetStats() (*Stats, error)
18+
19+
// Toggles the freezer cgroup according with specified state
20+
Freeze(state configs.FreezerState) error
21+
22+
// Destroys the cgroup set
23+
Destroy() error
24+
25+
// NewCgroupManager() and LoadCgroupManager() require following attributes:
26+
// Paths map[string]string
27+
// Cgroups *cgroups.Cgroup
28+
// Paths maps cgroup subsystem to path at which it is mounted.
29+
// Cgroups specifies specific cgroup settings for the various subsystems
30+
31+
// Returns cgroup paths to save in a state file and to be able to
32+
// restore the object later.
33+
GetPaths() map[string]string
34+
}
1635

1736
type NotFoundError struct {
1837
Subsystem string
@@ -32,26 +51,6 @@ func IsNotFound(err error) bool {
3251
if err == nil {
3352
return false
3453
}
35-
3654
_, ok := err.(*NotFoundError)
3755
return ok
3856
}
39-
40-
type Cgroup struct {
41-
Name string `json:"name,omitempty"`
42-
Parent string `json:"parent,omitempty"` // name of parent cgroup or slice
43-
44-
AllowAllDevices bool `json:"allow_all_devices,omitempty"` // If this is true allow access to any kind of device within the container. If false, allow access only to devices explicitly listed in the allowed_devices list.
45-
AllowedDevices []*devices.Device `json:"allowed_devices,omitempty"`
46-
Memory int64 `json:"memory,omitempty"` // Memory limit (in bytes)
47-
MemoryReservation int64 `json:"memory_reservation,omitempty"` // Memory reservation or soft_limit (in bytes)
48-
MemorySwap int64 `json:"memory_swap,omitempty"` // Total memory usage (memory + swap); set `-1' to disable swap
49-
CpuShares int64 `json:"cpu_shares,omitempty"` // CPU shares (relative weight vs. other containers)
50-
CpuQuota int64 `json:"cpu_quota,omitempty"` // CPU hardcap limit (in usecs). Allowed cpu time in a given period.
51-
CpuPeriod int64 `json:"cpu_period,omitempty"` // CPU period to be used for hardcapping (in usecs). 0 to use system default.
52-
CpusetCpus string `json:"cpuset_cpus,omitempty"` // CPU to use
53-
CpusetMems string `json:"cpuset_mems,omitempty"` // MEM to use
54-
BlkioWeight int64 `json:"blkio_weight,omitempty"` // Specifies per cgroup weight, range is from 10 to 1000.
55-
Freezer FreezerState `json:"freezer,omitempty"` // set the freeze value for the process
56-
Slice string `json:"slice,omitempty"` // Parent slice to use for systemd
57-
}

0 commit comments

Comments
 (0)