Skip to content
This repository was archived by the owner on Dec 13, 2018. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
130 commits
Select commit Hold shift + click to select a range
e28b636
Add ContainerInfo instead of using a readonly state
crosbymichael Oct 22, 2014
6bf1e4d
Update container interface with process operations
crosbymichael Oct 22, 2014
6310a95
Implement linux factory and container with readonly interface
crosbymichael Oct 22, 2014
7760faa
Add stacktrace package for collection of stacktraces
crosbymichael Oct 22, 2014
926ab56
Add testing for linux factory Load
crosbymichael Oct 22, 2014
ccb83a1
Add cgroup manage for mocking of package resources
crosbymichael Oct 22, 2014
d5b8418
Remove ContainerInfo interface
crosbymichael Oct 28, 2014
47b41a6
Add logger to container and factory
crosbymichael Oct 30, 2014
66e6806
Adds ID validation.
mrunalp Oct 31, 2014
3f26e9a
Add check for ID already in use.
mrunalp Oct 31, 2014
de57f78
More error handling and fixup
mrunalp Nov 3, 2014
e563654
Switch from logrus to glog.
vmarmol Dec 6, 2014
646ca2b
Minor refactorings to fix build.
vmarmol Dec 6, 2014
b608f5d
nsinit: Add Makefile
avagin Nov 24, 2014
159db89
nsinit: use the new API for executing processes
avagin Dec 15, 2014
bce773a
linux_container: ct.Destroy() returns error if CT isn't stopped
avagin Dec 15, 2014
2441bab
linux_factory: add StartInitialization()
avagin Dec 15, 2014
8e9a6d2
linux_container: execute an init process in a new CT
avagin Dec 15, 2014
44024d0
Makefile: get the glog package
avagin Dec 17, 2014
c44e63a
Merge pull request #299 from avagin/api-linux
vmarmol Dec 18, 2014
7038ddb
libcontainer: move Config in a separate package
avagin Dec 17, 2014
ce9d633
libcontainer: move State in the configs package
avagin Dec 17, 2014
c406a6b
nsinit: clean up
avagin Dec 17, 2014
5ecd29c
linux_container: fork an init process in a new set of namespaces
avagin Dec 19, 2014
7996829
libcontainer: optimize updateStateFile()
avagin Dec 17, 2014
540f44d
process: use io.Reader instead of io.WriteCloser for standard fds
avagin Dec 17, 2014
86653c6
libcontinaer: use new API in integration tests
avagin Dec 17, 2014
c912207
namespaces: combine Process.Env and Container.Env
avagin Dec 18, 2014
e1b4ec3
Merge pull request #306 from avagin/api-linux-2
vmarmol Dec 19, 2014
1a380ac
nsinit: remove ticks around nsenter
avagin Dec 22, 2014
13841ef
new-api: return the Running state only if the init process is alive
avagin Dec 23, 2014
11ce56a
new-api: clean up startInitProcess()
avagin Dec 23, 2014
d572094
new-api: execute a process inside an existing container
avagin Dec 22, 2014
195a08e
new-api: set Cloneflags in namespace.Exec()
avagin Dec 24, 2014
a7ab930
Merge pull request #311 from avagin/api-linux
vmarmol Jan 13, 2015
6dd7552
new-api: implement fs and systemd cgroup managers
avagin Jan 12, 2015
59e66b8
nsinit: add getContainer()
avagin Jan 13, 2015
ba4257a
new-api: add the Freezer method to cgroup.Manager
avagin Jan 13, 2015
ee6e585
cgroups: replace SetPaths on LoadCgroupManager
avagin Jan 14, 2015
083d91f
cgroups: Add comments for methods of cgroup managers
avagin Jan 14, 2015
4eaff5e
cgroups: don't change a freezer state if an operation failed
avagin Jan 14, 2015
6334be0
cgroups: add TODO before NewCgroupManager()
avagin Jan 14, 2015
c1a4b31
Merge pull request #330 from avagin/api-cgroups
vmarmol Jan 14, 2015
085a8fb
Vendors glog dependency for the api branch.
mrunalp Jan 15, 2015
0f9f14c
Merge pull request #332 from mrunalp/vendor/glog
vmarmol Jan 15, 2015
76d395e
new-api: add Console to ProcessConfig
avagin Dec 26, 2014
46e62c9
nsinit: return console
avagin Dec 26, 2014
cc411c3
Merge pull request #333 from avagin/api-console
Jan 15, 2015
7b33e53
integration: check that a process can be executed in an existing CT
avagin Dec 25, 2014
9586935
Merge pull request #334 from avagin/api-test
Jan 16, 2015
9c50d81
new-api: implement Pause() and Resume()
avagin Jan 19, 2015
dcb3bca
namespaces: destroy cgroups only on error paths
avagin Jan 19, 2015
02c1de6
cgroups: set a freezer state before calling FreezerGroup.Set()
avagin Jan 19, 2015
5138417
integration: add test to check Pause and Resume operations
avagin Jan 19, 2015
c70b681
Merge pull request #339 from avagin/api-freezer
Jan 19, 2015
f0c20b5
new-api: remove DefaultCreateCommand()
avagin Dec 26, 2014
10f0ac2
new-api: remove nsenter.c
avagin Jan 15, 2015
5162e5a
integration: check container.Processes()
avagin Jan 21, 2015
6fc1dd5
integration: check a container state after resumning the CT
avagin Jan 21, 2015
e79e87e
cgroup/systemd: set config.Cgroups.Freezer
avagin Jan 21, 2015
61fef16
new-api: implement Wait, WaitProcess
avagin Jan 21, 2015
fae3abd
Merge pull request #342 from avagin/api-next
Jan 22, 2015
e77b238
namespaces: don't send a container config twice
avagin Jan 26, 2015
11b2dab
nsenter: add a macros to print errors
avagin Jan 26, 2015
8236793
nsenter: remove a proxy process
avagin Jan 26, 2015
8d8242a
nsenter: add tests
avagin Jan 26, 2015
904bae3
Merge pull request #348 from avagin/api-nsexec
crosbymichael Jan 26, 2015
ca633b2
Merge remote-tracking branch 'origin/master' into api
avagin Jan 27, 2015
e31ef02
Merge pull request #351 from avagin/api-rebase-2
Jan 30, 2015
df52d63
namespaces: send config, network state and other arguments in one packet
avagin Jan 28, 2015
c3f3db7
namespaces: don't unroll process arguments
avagin Jan 28, 2015
60f6310
Merge pull request #355 from avagin/api-next
Jan 30, 2015
77f255a
Add missing initializers
crosbymichael Jan 31, 2015
935d81f
Flatten configuration structs
crosbymichael Feb 1, 2015
8191d4d
Refactory container interface
crosbymichael Feb 1, 2015
bbeae74
Remove namespaces package
crosbymichael Feb 1, 2015
daca745
api: fix integration tests
avagin Feb 3, 2015
bcd0222
api: fix config tests
avagin Feb 3, 2015
ab76a88
Remove Wait() on container interface
crosbymichael Feb 3, 2015
5d25c72
Merge pull request #357 from crosbymichael/api
Feb 3, 2015
c6f5420
integration: check a container with userns
avagin Feb 4, 2015
e48806d
Merge pull request #360 from avagin/api-userns-test
Feb 11, 2015
5fc19e8
Rename Fs fields to fs
crosbymichael Feb 4, 2015
8850636
Refactor init actions into separate types
crosbymichael Feb 6, 2015
58023ad
Add parent death signal to the container config
crosbymichael Feb 7, 2015
21bb5cc
Move environment configuration to Process
crosbymichael Feb 7, 2015
0c1919c
Refactor parent processes into types
crosbymichael Feb 7, 2015
9dcbc4f
Implement container signaling
crosbymichael Feb 7, 2015
1edada5
Move Cwd and User to Process
crosbymichael Feb 9, 2015
20daff5
Move mount package into libcontainer root
crosbymichael Feb 9, 2015
b0e274c
Remove console package and add Console type
crosbymichael Feb 9, 2015
1c895b4
Move mount logic into root package
crosbymichael Feb 9, 2015
6a04779
Remove restrict package
crosbymichael Feb 9, 2015
ad49d71
Remove network package
crosbymichael Feb 9, 2015
758d151
Fully remove security package
crosbymichael Feb 9, 2015
2ec6b58
Add new API examples to readme
crosbymichael Feb 10, 2015
fde0b7a
Refactor network and veth creation
crosbymichael Feb 10, 2015
9f0cca1
Merge pull request #367 from crosbymichael/validation
vmarmol Feb 11, 2015
7fff136
Add state method to return container's runtime state
crosbymichael Feb 11, 2015
3132716
Rename OOM to NotifyOOM
crosbymichael Feb 11, 2015
5c246d0
Persist container state to disk
crosbymichael Feb 12, 2015
d909440
Unexport certain internal funcs and types
crosbymichael Feb 12, 2015
5df859a
Add config command to nsinit
crosbymichael Feb 12, 2015
91a3f16
Implement nsinit state command
crosbymichael Feb 12, 2015
c2403c3
Add GetPath on namespace config
crosbymichael Feb 12, 2015
e2ed997
Merge pull request #370 from crosbymichael/state
Feb 12, 2015
fe9f766
Fix compilation with golang 1.3(uid/gid mappings is unsupported)
LK4D4 Feb 12, 2015
a9a5030
Merge pull request #374 from LK4D4/go1.3_support
crosbymichael Feb 12, 2015
1a37242
Refactor system mounts to be placed on the config
crosbymichael Feb 13, 2015
031524c
Merge pull request #375 from crosbymichael/move-system-mounts
vmarmol Feb 13, 2015
7708590
Add a constant for the container console path.
mrunalp Feb 13, 2015
2990f25
Merge pull request #377 from mrunalp/console_path
crosbymichael Feb 13, 2015
a1d5097
Fixed some typos and tried to make comments read better.
mrunalp Feb 14, 2015
8002fd2
Merge pull request #378 from mrunalp/cleanup_comments
vmarmol Feb 14, 2015
cacc153
Add config generation for simple user namespace testing.
mrunalp Feb 14, 2015
2b45128
Merge pull request #379 from mrunalp/userns_config_gen
vmarmol Feb 14, 2015
4c43b0f
Add mutex around stateful container operations
crosbymichael Feb 13, 2015
b21b19e
Add factory configuration via functional api
crosbymichael Feb 13, 2015
55d61e2
Merge pull request #381 from crosbymichael/configfactory
crosbymichael Feb 16, 2015
f4cf808
Merge branch 'master' into api
crosbymichael Feb 16, 2015
cc42996
Merge pull request #382 from crosbymichael/merges
Feb 16, 2015
339edce
Update console and mount handling for user namespaces
crosbymichael Feb 18, 2015
afa8443
Remove userns sidecar process
crosbymichael Feb 18, 2015
d06a2da
Merge pull request #385 from crosbymichael/userns-updates
Feb 19, 2015
4d863b7
Fixes bug where rootfs was empty instead of pwd when not specified.
mrunalp Feb 19, 2015
f34b3b7
Validation for User Namespaces in the config.
mrunalp Feb 19, 2015
8c3b6b1
Merge pull request #387 from mrunalp/rootfs_config
rjnagal Feb 19, 2015
1b755bf
Merge pull request #386 from mrunalp/userns_check
vmarmol Feb 19, 2015
22df555
Merge branch 'master' into api
crosbymichael Feb 19, 2015
7eceabd
Merge pull request #389 from crosbymichael/mergeapi
vmarmol Feb 20, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ script:
- bash /go/src/github.com/docker/docker/hack/make/validate-dco
- bash /go/src/github.com/docker/docker/hack/make/validate-gofmt
- export GOPATH="$GOPATH:/go:$(pwd)/vendor" # Drone mucks with our GOPATH
- go get golang.org/x/tools/cmd/vet && go vet ./...
- make direct-test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nsinit/nsinit
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ direct-build:

direct-install:
go install -v $(GO_PACKAGES)
local:
go test -v
2 changes: 1 addition & 1 deletion PRINCIPLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ In the design and development of libcontainer we try to follow these principles:
* Less code is better.
* Fewer components are better. Do you really need to add one more class?
* 50 lines of straightforward, readable code is better than 10 lines of magic that nobody can understand.
* Don't do later what you can do now. "//FIXME: refactor" is not acceptable in new code.
* Don't do later what you can do now. "//TODO: refactor" is not acceptable in new code.
* When hesitating between two options, choose the one that is easier to reverse.
* "No" is temporary; "Yes" is forever. If you're not sure about a new feature, say no. You can change your mind later.
* Containers must be portable to the greatest possible number of machines. Be suspicious of any change which makes machines less interchangeable.
Expand Down
155 changes: 138 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,169 @@
## 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)

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

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.

#### Background
#### Container
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.

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.
#### Using libcontainer

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

#### Container
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.
Because containers are spawned in a two step process you will need to provide
arguments to a binary that will be executed as the init process for the container.
To use the current binary that is spawning the containers and acting as the parent
you can use `os.Args[0]` and we have a command called `init` setup.

```go
initArgs := []string{os.Args[0], "init"}

root, err := libcontainer.New("/var/lib/container", initArgs)
if err != nil {
log.Fatal(err)
}
```

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.
Once you have an instance of the factory created we can create a configuration
struct describing how the container is to be created. A sample would look similar to this:

```go
config := &configs.Config{
Rootfs: rootfs,
Capabilities: []string{
"CHOWN",
"DAC_OVERRIDE",
"FSETID",
"FOWNER",
"MKNOD",
"NET_RAW",
"SETGID",
"SETUID",
"SETFCAP",
"SETPCAP",
"NET_BIND_SERVICE",
"SYS_CHROOT",
"KILL",
"AUDIT_WRITE",
},
Namespaces: configs.Namespaces([]configs.Namespace{
{Type: configs.NEWNS},
{Type: configs.NEWUTS},
{Type: configs.NEWIPC},
{Type: configs.NEWPID},
{Type: configs.NEWNET},
}),
Cgroups: &configs.Cgroup{
Name: "test-container",
Parent: "system",
AllowAllDevices: false,
AllowedDevices: configs.DefaultAllowedDevices,
},

Devices: configs.DefaultAutoCreatedDevices,
Hostname: "testing",
Networks: []*configs.Network{
{
Type: "loopback",
Address: "127.0.0.1/0",
Gateway: "localhost",
},
},
Rlimits: []configs.Rlimit{
{
Type: syscall.RLIMIT_NOFILE,
Hard: uint64(1024),
Soft: uint64(1024),
},
},
}
```

Once you have the configuration populated you can create a container:

```go
container, err := root.Create("container-id", config)
```

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

#### Root file system
```go
process := &libcontainer.Process{
Args: []string{"/bin/bash"},
Env: []string{"PATH=/bin"},
User: "daemon",
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
}

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.
pid, err := container.Start(process)
if err != nil {
log.Fatal(err)
}


#### Configuration
// wait for the process to finish.
wait(pid)

A container is initially configured by supplying configuration data when the container is created.
// destroy the container.
container.Destroy()
```

Additional ways to interact with a running container are:

```go
// return all the pids for all processes running inside the container.
processes, err := container.Processes()

// get detailed cpu, memory, io, and network statistics for the container and
// it's processes.
stats, err := container.Stats()


// pause all processes inside the container.
container.Pause()

// resume all paused processes.
container.Resume()
```


#### nsinit

`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.
`nsinit` is a cli application which demonstrates the use of libcontainer.
It is able to spawn new containers or join existing containers. A root
filesystem must be provided for use along with a container configuration file.

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.
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.

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

To execute `/bin/bash` in the current directory as a container just run the following **as root**:
```bash
nsinit exec /bin/bash
nsinit exec --tty /bin/bash
```

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.
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.

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.
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.

You may also specify an alternate root place where the `container.json` file is read and where the `state.json` file will be saved.
You may also specify an alternate root place where
the `container.json` file is read and where the `state.json` file will be saved.

#### Future
See the [roadmap](ROADMAP.md).
Expand Down
21 changes: 0 additions & 21 deletions api_temp.go

This file was deleted.

1 change: 0 additions & 1 deletion apparmor/apparmor.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ func ApplyProfile(name string) error {
if name == "" {
return nil
}

cName := C.CString(name)
defer C.free(unsafe.Pointer(cName))

Expand Down
53 changes: 26 additions & 27 deletions cgroups/cgroups.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,35 @@ package cgroups
import (
"fmt"

"github.com/docker/libcontainer/devices"
"github.com/docker/libcontainer/configs"
)

type FreezerState string
type Manager interface {
// Apply cgroup configuration to the process with the specified pid
Apply(pid int) error

const (
Undefined FreezerState = ""
Frozen FreezerState = "FROZEN"
Thawed FreezerState = "THAWED"
)
// Returns the PIDs inside the cgroup set
GetPids() ([]int, error)

// Returns statistics for the cgroup set
GetStats() (*Stats, error)

// Toggles the freezer cgroup according with specified state
Freeze(state configs.FreezerState) error

// Destroys the cgroup set
Destroy() error

// NewCgroupManager() and LoadCgroupManager() require following attributes:
// Paths map[string]string
// Cgroups *cgroups.Cgroup
// Paths maps cgroup subsystem to path at which it is mounted.
// Cgroups specifies specific cgroup settings for the various subsystems

// Returns cgroup paths to save in a state file and to be able to
// restore the object later.
GetPaths() map[string]string
}

type NotFoundError struct {
Subsystem string
Expand All @@ -32,26 +51,6 @@ func IsNotFound(err error) bool {
if err == nil {
return false
}

_, ok := err.(*NotFoundError)
return ok
}

type Cgroup struct {
Name string `json:"name,omitempty"`
Parent string `json:"parent,omitempty"` // name of parent cgroup or slice

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.
AllowedDevices []*devices.Device `json:"allowed_devices,omitempty"`
Memory int64 `json:"memory,omitempty"` // Memory limit (in bytes)
MemoryReservation int64 `json:"memory_reservation,omitempty"` // Memory reservation or soft_limit (in bytes)
MemorySwap int64 `json:"memory_swap,omitempty"` // Total memory usage (memory + swap); set `-1' to disable swap
CpuShares int64 `json:"cpu_shares,omitempty"` // CPU shares (relative weight vs. other containers)
CpuQuota int64 `json:"cpu_quota,omitempty"` // CPU hardcap limit (in usecs). Allowed cpu time in a given period.
CpuPeriod int64 `json:"cpu_period,omitempty"` // CPU period to be used for hardcapping (in usecs). 0 to use system default.
CpusetCpus string `json:"cpuset_cpus,omitempty"` // CPU to use
CpusetMems string `json:"cpuset_mems,omitempty"` // MEM to use
BlkioWeight int64 `json:"blkio_weight,omitempty"` // Specifies per cgroup weight, range is from 10 to 1000.
Freezer FreezerState `json:"freezer,omitempty"` // set the freeze value for the process
Slice string `json:"slice,omitempty"` // Parent slice to use for systemd
}
Loading