1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Update libcontainer dep to v1.0.1

Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@docker.com> (github: crosbymichael)
This commit is contained in:
Michael Crosby 2014-06-19 15:23:19 -07:00
parent 98ea12ac38
commit 8d06bfc12e
11 changed files with 280 additions and 143 deletions

View file

@ -61,4 +61,4 @@ mv tmp-tar src/code.google.com/p/go/src/pkg/archive/tar
clone git github.com/godbus/dbus v1 clone git github.com/godbus/dbus v1
clone git github.com/coreos/go-systemd v2 clone git github.com/coreos/go-systemd v2
clone git github.com/docker/libcontainer 77ffd49dfedbc78a7cd4cb7a50c7446cf118725f clone git github.com/docker/libcontainer v1.0.1

View file

@ -9,3 +9,4 @@ install:
script: script:
- bash "$DOCKER_PATH/hack/make/validate-dco" - bash "$DOCKER_PATH/hack/make/validate-dco"
- bash "$DOCKER_PATH/hack/make/validate-gofmt" - bash "$DOCKER_PATH/hack/make/validate-gofmt"
- go test

View file

@ -36,7 +36,7 @@ that feature *on top of* libcontainer.
### Discuss your design on the mailing list ### Discuss your design on the mailing list
We recommend discussing your plans [on the mailing We recommend discussing your plans [on the mailing
list](https://groups.google.com/forum/?fromgroups#!forum/docker-dev) list](https://groups.google.com/forum/?fromgroups#!forum/libcontainer)
before starting to code - especially for more ambitious contributions. before starting to code - especially for more ambitious contributions.
This gives other contributors a chance to point you in the right This gives other contributors a chance to point you in the right
direction, give feedback on your design, and maybe point out if someone direction, give feedback on your design, and maybe point out if someone
@ -112,12 +112,12 @@ and that all the tests pass.
libcontainer maintainers use LGTM (looks good to me) in comments on the code review libcontainer maintainers use LGTM (looks good to me) in comments on the code review
to indicate acceptance. to indicate acceptance.
A change requires LGTMs from at lease one maintainer of each A change requires LGTMs from at lease two maintainers. One of those must come from
component affected. For example, if a change affects `netlink/` and `security/`, it a maintainer of the component affected. For example, if a change affects `netlink/`
needs at least one LGTM from the maintainers of `netlink/` AND, separately, at and `security`, it needs at least one LGTM from a maintainer of each. Maintainers
least one LGTM from the maintainers of `security/`. only need one LGTM as presumably they LGTM their own change.
For more details see [MAINTAINERS.md](hack/MAINTAINERS.md) For more details see [MAINTAINERS.md](MAINTAINERS.md)
### Sign your work ### Sign your work

View file

@ -63,7 +63,7 @@ All decisions are pull requests, and the relevant maintainers make
decisions by accepting or refusing the pull request. Review and acceptance decisions by accepting or refusing the pull request. Review and acceptance
by anyone is denoted by adding a comment in the pull request: `LGTM`. by anyone is denoted by adding a comment in the pull request: `LGTM`.
However, only currently listed `MAINTAINERS` are counted towards the required However, only currently listed `MAINTAINERS` are counted towards the required
majority. two LGTMs.
libcontainer follows the timeless, highly efficient and totally unfair system libcontainer follows the timeless, highly efficient and totally unfair system
known as [Benevolent dictator for life](http://en.wikipedia.org/wiki/Benevolent_Dictator_for_Life), with Michael Crosby in the role of BDFL. known as [Benevolent dictator for life](http://en.wikipedia.org/wiki/Benevolent_Dictator_for_Life), with Michael Crosby in the role of BDFL.

View file

@ -84,6 +84,7 @@ func (s *cpuacctGroup) GetStats(d *data, stats *cgroups.Stats) error {
if err != nil { if err != nil {
return err return err
} }
stats.CpuStats.CpuUsage.TotalUsage = lastUsage
stats.CpuStats.CpuUsage.PercpuUsage = percpuUsage stats.CpuStats.CpuUsage.PercpuUsage = percpuUsage
stats.CpuStats.CpuUsage.UsageInKernelmode = (kernelModeUsage * nanosecondsInSecond) / clockTicks stats.CpuStats.CpuUsage.UsageInKernelmode = (kernelModeUsage * nanosecondsInSecond) / clockTicks
stats.CpuStats.CpuUsage.UsageInUsermode = (userModeUsage * nanosecondsInSecond) / clockTicks stats.CpuStats.CpuUsage.UsageInUsermode = (userModeUsage * nanosecondsInSecond) / clockTicks

View file

@ -13,8 +13,10 @@ type CpuUsage struct {
// percentage of available CPUs currently being used. // percentage of available CPUs currently being used.
PercentUsage uint64 `json:"percent_usage,omitempty"` PercentUsage uint64 `json:"percent_usage,omitempty"`
// nanoseconds of cpu time consumed over the last 100 ms. // nanoseconds of cpu time consumed over the last 100 ms.
CurrentUsage uint64 `json:"current_usage,omitempty"` CurrentUsage uint64 `json:"current_usage,omitempty"`
PercpuUsage []uint64 `json:"percpu_usage,omitempty"` // total nanoseconds of cpu time consumed
TotalUsage uint64 `json:"total_usage,omitempty"`
PercpuUsage []uint64 `json:"percpu_usage,omitempty"`
// Time spent by tasks of the cgroup in kernel mode. Units: nanoseconds. // Time spent by tasks of the cgroup in kernel mode. Units: nanoseconds.
UsageInKernelmode uint64 `json:"usage_in_kernelmode"` UsageInKernelmode uint64 `json:"usage_in_kernelmode"`
// Time spent by tasks of the cgroup in user mode. Units: nanoseconds. // Time spent by tasks of the cgroup in user mode. Units: nanoseconds.

View file

@ -1,107 +1,213 @@
{ {
"namespaces": { "capabilities": [
"NEWNET": true, "CHOWN",
"NEWPID": true, "DAC_OVERRIDE",
"NEWIPC": true, "FOWNER",
"NEWUTS": true, "MKNOD",
"NEWNS": true "NET_RAW",
}, "SETGID",
"networks": [ "SETUID",
{ "SETFCAP",
"gateway": "localhost", "SETPCAP",
"type": "loopback", "NET_BIND_SERVICE",
"address": "127.0.0.1/0", "SYS_CHROOT",
"mtu": 1500 "KILL"
],
"cgroups": {
"allowed_devices": [
{
"cgroup_permissions": "m",
"major_number": -1,
"minor_number": -1,
"type": 99
},
{
"cgroup_permissions": "m",
"major_number": -1,
"minor_number": -1,
"type": 98
},
{
"cgroup_permissions": "rwm",
"major_number": 5,
"minor_number": 1,
"path": "/dev/console",
"type": 99
},
{
"cgroup_permissions": "rwm",
"major_number": 4,
"path": "/dev/tty0",
"type": 99
},
{
"cgroup_permissions": "rwm",
"major_number": 4,
"minor_number": 1,
"path": "/dev/tty1",
"type": 99
},
{
"cgroup_permissions": "rwm",
"major_number": 136,
"minor_number": -1,
"type": 99
},
{
"cgroup_permissions": "rwm",
"major_number": 5,
"minor_number": 2,
"type": 99
},
{
"cgroup_permissions": "rwm",
"major_number": 10,
"minor_number": 200,
"type": 99
},
{
"cgroup_permissions": "rwm",
"file_mode": 438,
"major_number": 1,
"minor_number": 3,
"path": "/dev/null",
"type": 99
},
{
"cgroup_permissions": "rwm",
"file_mode": 438,
"major_number": 1,
"minor_number": 5,
"path": "/dev/zero",
"type": 99
},
{
"cgroup_permissions": "rwm",
"file_mode": 438,
"major_number": 1,
"minor_number": 7,
"path": "/dev/full",
"type": 99
},
{
"cgroup_permissions": "rwm",
"file_mode": 438,
"major_number": 5,
"path": "/dev/tty",
"type": 99
},
{
"cgroup_permissions": "rwm",
"file_mode": 438,
"major_number": 1,
"minor_number": 9,
"path": "/dev/urandom",
"type": 99
},
{
"cgroup_permissions": "rwm",
"file_mode": 438,
"major_number": 1,
"minor_number": 8,
"path": "/dev/random",
"type": 99
}
],
"name": "docker-koye",
"parent": "docker"
}, },
{ "context": {
"gateway": "172.17.42.1", "mount_label": "",
"context": { "process_label": "",
"prefix": "veth", "restrictions": "true"
"bridge": "docker0"
},
"type": "veth",
"address": "172.17.42.2/16",
"mtu": 1500
}
],
"routes": [
{
"gateway": "172.17.42.1",
"interface_name": "eth0"
}, },
{ "device_nodes": [
"destination": "192.168.0.0/24", {
"interface_name": "eth0" "cgroup_permissions": "rwm",
} "major_number": 10,
], "minor_number": 229,
"capabilities": [ "path": "/dev/fuse",
"MKNOD" "type": 99
], },
"cgroups": { {
"name": "docker-koye", "cgroup_permissions": "rwm",
"parent": "docker" "file_mode": 438,
}, "major_number": 1,
"hostname": "koye", "minor_number": 3,
"environment": [ "path": "/dev/null",
"HOME=/", "type": 99
"PATH=PATH=$PATH:/bin:/usr/bin:/sbin:/usr/sbin", },
"container=docker", {
"TERM=xterm-256color" "cgroup_permissions": "rwm",
], "file_mode": 438,
"tty": true, "major_number": 1,
"mounts": [ "minor_number": 5,
{ "path": "/dev/zero",
"type": "devtmpfs" "type": 99
} },
], {
"device_nodes": [ "cgroup_permissions": "rwm",
{ "file_mode": 438,
"path": "/dev/null", "major_number": 1,
"type": 99, "minor_number": 7,
"major_number": 1, "path": "/dev/full",
"minor_number": 3, "type": 99
"cgroup_permissions": "rwm", },
"file_mode": 438 {
}, "cgroup_permissions": "rwm",
{ "file_mode": 438,
"path": "/dev/zero", "major_number": 5,
"type": 99, "path": "/dev/tty",
"major_number": 1, "type": 99
"minor_number": 5, },
"cgroup_permissions": "rwm", {
"file_mode": 438 "cgroup_permissions": "rwm",
}, "file_mode": 438,
{ "major_number": 1,
"path": "/dev/full", "minor_number": 9,
"type": 99, "path": "/dev/urandom",
"major_number": 1, "type": 99
"minor_number": 7, },
"cgroup_permissions": "rwm", {
"file_mode": 438 "cgroup_permissions": "rwm",
}, "file_mode": 438,
{ "major_number": 1,
"path": "/dev/tty", "minor_number": 8,
"type": 99, "path": "/dev/random",
"major_number": 5, "type": 99
"minor_number": 0, }
"cgroup_permissions": "rwm", ],
"file_mode": 438 "environment": [
}, "HOME=/",
{ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"path": "/dev/urandom", "HOSTNAME=2d388ea3bd92",
"type": 99, "TERM=xterm"
"major_number": 1, ],
"minor_number": 9, "hostname": "koye",
"cgroup_permissions": "rwm", "namespaces": {
"file_mode": 438 "NEWIPC": true,
}, "NEWNET": true,
{ "NEWNS": true,
"path": "/dev/random", "NEWPID": true,
"type": 99, "NEWUTS": true
"major_number": 1, },
"minor_number": 8, "networks": [
"cgroup_permissions": "rwm", {
"file_mode": 438 "address": "127.0.0.1/0",
} "gateway": "localhost",
] "mtu": 1500,
"type": "loopback"
},
{
"address": "172.17.0.101/16",
"context": {
"bridge": "docker0",
"prefix": "veth"
},
"gateway": "172.17.42.1",
"mtu": 1500,
"type": "veth"
}
],
"tty": true
} }

View file

@ -37,11 +37,6 @@ func TestContainerJsonFormat(t *testing.T) {
t.Fail() t.Fail()
} }
if len(container.Routes) != 2 {
t.Log("should have found 2 routes")
t.Fail()
}
if !container.Namespaces["NEWNET"] { if !container.Namespaces["NEWNET"] {
t.Log("namespaces should contain NEWNET") t.Log("namespaces should contain NEWNET")
t.Fail() t.Fail()
@ -62,8 +57,8 @@ func TestContainerJsonFormat(t *testing.T) {
t.Fail() t.Fail()
} }
if contains("SYS_CHROOT", container.Capabilities) { if !contains("SYS_CHROOT", container.Capabilities) {
t.Log("capabilities mask should not contain SYS_CHROOT") t.Log("capabilities mask should contain SYS_CHROOT")
t.Fail() t.Fail()
} }
} }

View file

@ -21,14 +21,8 @@ func ExecIn(container *libcontainer.Container, nspid int, args []string) error {
return err return err
} }
// TODO(vmarmol): Move this to the container JSON.
processLabel, err := label.GetPidCon(nspid)
if err != nil {
return err
}
// Enter the namespace and then finish setup // Enter the namespace and then finish setup
finalArgs := []string{os.Args[0], "nsenter", strconv.Itoa(nspid), processLabel, string(containerJson)} finalArgs := []string{os.Args[0], "nsenter", "--nspid", strconv.Itoa(nspid), "--containerjson", string(containerJson), "--"}
finalArgs = append(finalArgs, args...) finalArgs = append(finalArgs, args...)
if err := system.Execv(finalArgs[0], finalArgs[0:], os.Environ()); err != nil { if err := system.Execv(finalArgs[0], finalArgs[0:], os.Environ()); err != nil {
return err return err
@ -37,7 +31,7 @@ func ExecIn(container *libcontainer.Container, nspid int, args []string) error {
} }
// NsEnter is run after entering the namespace. // NsEnter is run after entering the namespace.
func NsEnter(container *libcontainer.Container, processLabel string, nspid int, args []string) error { func NsEnter(container *libcontainer.Container, nspid int, args []string) error {
// clear the current processes env and replace it with the environment // clear the current processes env and replace it with the environment
// defined on the container // defined on the container
if err := LoadContainerEnvironment(container); err != nil { if err := LoadContainerEnvironment(container); err != nil {
@ -46,9 +40,13 @@ func NsEnter(container *libcontainer.Container, processLabel string, nspid int,
if err := FinalizeNamespace(container); err != nil { if err := FinalizeNamespace(container); err != nil {
return err return err
} }
if err := label.SetProcessLabel(processLabel); err != nil {
return err if process_label, ok := container.Context["process_label"]; ok {
if err := label.SetProcessLabel(process_label); err != nil {
return err
}
} }
if err := system.Execv(args[0], args[0:], container.Env); err != nil { if err := system.Execv(args[0], args[0:], container.Env); err != nil {
return err return err
} }

View file

@ -15,6 +15,7 @@ package namespaces
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <getopt.h>
static const kBufSize = 256; static const kBufSize = 256;
@ -64,6 +65,10 @@ int setns(int fd, int nstype) {
#endif #endif
#endif #endif
void print_usage() {
fprintf(stderr, "<binary> nsenter --nspid <pid> --containerjson <container_json> -- cmd1 arg1 arg2...\n");
}
void nsenter() { void nsenter() {
int argc; int argc;
char **argv; char **argv;
@ -79,11 +84,40 @@ void nsenter() {
fprintf(stderr, "nsenter: Incorrect usage, not enough arguments\n"); fprintf(stderr, "nsenter: Incorrect usage, not enough arguments\n");
exit(1); exit(1);
} }
pid_t init_pid = strtol(argv[2], NULL, 10);
if (errno != 0 || init_pid <= 0) { static const struct option longopts[] = {
fprintf(stderr, "nsenter: Failed to parse PID from \"%s\" with error: \"%s\"\n", argv[2], strerror(errno)); { "nspid", required_argument, NULL, 'n' },
{ "containerjson", required_argument, NULL, 'c' },
{ NULL, 0, NULL, 0 }
};
int c;
pid_t init_pid = -1;
char *init_pid_str = NULL;
char *container_json = NULL;
while ((c = getopt_long_only(argc, argv, "n:s:c:", longopts, NULL)) != -1) {
switch (c) {
case 'n':
init_pid_str = optarg;
break;
case 'c':
container_json = optarg;
break;
}
}
if (container_json == NULL || init_pid_str == NULL) {
print_usage();
exit(1); exit(1);
} }
init_pid = strtol(init_pid_str, NULL, 10);
if (errno != 0 || init_pid <= 0) {
fprintf(stderr, "nsenter: Failed to parse PID from \"%s\" with error: \"%s\"\n", init_pid_str, strerror(errno));
print_usage();
exit(1);
}
argc -= 3; argc -= 3;
argv += 3; argv += 3;

View file

@ -2,7 +2,6 @@ package main
import ( import (
"log" "log"
"strconv"
"github.com/codegangsta/cli" "github.com/codegangsta/cli"
"github.com/docker/libcontainer/namespaces" "github.com/docker/libcontainer/namespaces"
@ -12,29 +11,30 @@ var nsenterCommand = cli.Command{
Name: "nsenter", Name: "nsenter",
Usage: "init process for entering an existing namespace", Usage: "init process for entering an existing namespace",
Action: nsenterAction, Action: nsenterAction,
Flags: []cli.Flag{
cli.IntFlag{Name: "nspid"},
cli.StringFlag{Name: "containerjson"},
},
} }
func nsenterAction(context *cli.Context) { func nsenterAction(context *cli.Context) {
args := context.Args() args := context.Args()
if len(args) < 4 {
log.Fatalf("incorrect usage: <pid> <process label> <container JSON> <cmd>...") if len(args) == 0 {
args = []string{"/bin/bash"}
} }
container, err := loadContainerFromJson(args.Get(2)) container, err := loadContainerFromJson(context.String("containerjson"))
if err != nil { if err != nil {
log.Fatalf("unable to load container: %s", err) log.Fatalf("unable to load container: %s", err)
} }
nspid, err := strconv.Atoi(args.Get(0)) nspid := context.Int("nspid")
if err != nil {
log.Fatalf("unable to read pid: %s from %q", err, args.Get(0))
}
if nspid <= 0 { if nspid <= 0 {
log.Fatalf("cannot enter into namespaces without valid pid: %q", nspid) log.Fatalf("cannot enter into namespaces without valid pid: %q", nspid)
} }
if err := namespaces.NsEnter(container, args.Get(1), nspid, args[3:]); err != nil { if err := namespaces.NsEnter(container, nspid, args); err != nil {
log.Fatalf("failed to nsenter: %s", err) log.Fatalf("failed to nsenter: %s", err)
} }
} }