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

Merge pull request #12161 from LK4D4/update_libcontainer

Update libcontainer
This commit is contained in:
Michael Crosby 2015-04-07 16:18:33 -07:00
commit 06433cf812
12 changed files with 178 additions and 41 deletions

View file

@ -75,7 +75,7 @@ rm -rf src/github.com/docker/distribution
mkdir -p src/github.com/docker/distribution mkdir -p src/github.com/docker/distribution
mv tmp-digest src/github.com/docker/distribution/digest mv tmp-digest src/github.com/docker/distribution/digest
clone git github.com/docker/libcontainer d00b8369852285d6a830a8d3b966608b2ed89705 clone git github.com/docker/libcontainer bd8ec36106086f72b66e1be85a81202b93503e44
# see src/github.com/docker/libcontainer/update-vendor.sh which is the "source of truth" for libcontainer deps (just like this file) # see src/github.com/docker/libcontainer/update-vendor.sh which is the "source of truth" for libcontainer deps (just like this file)
rm -rf src/github.com/docker/libcontainer/vendor rm -rf src/github.com/docker/libcontainer/vendor
eval "$(grep '^clone ' src/github.com/docker/libcontainer/update-vendor.sh | grep -v 'github.com/codegangsta/cli' | grep -v 'github.com/Sirupsen/logrus')" eval "$(grep '^clone ' src/github.com/docker/libcontainer/update-vendor.sh | grep -v 'github.com/codegangsta/cli' | grep -v 'github.com/Sirupsen/logrus')"

View file

@ -3249,6 +3249,35 @@ func TestRunNetHost(t *testing.T) {
logDone("run - net host mode") logDone("run - net host mode")
} }
func TestRunNetContainerWhichHost(t *testing.T) {
testRequires(t, SameHostDaemon)
defer deleteAllContainers()
hostNet, err := os.Readlink("/proc/1/ns/net")
if err != nil {
t.Fatal(err)
}
cmd := exec.Command(dockerBinary, "run", "-d", "--net=host", "--name=test", "busybox", "top")
out, _, err := runCommandWithOutput(cmd)
if err != nil {
t.Fatal(err, out)
}
cmd = exec.Command(dockerBinary, "run", "--net=container:test", "busybox", "readlink", "/proc/self/ns/net")
out, _, err = runCommandWithOutput(cmd)
if err != nil {
t.Fatal(err, out)
}
out = strings.Trim(out, "\n")
if hostNet != out {
t.Fatalf("Container should have host network namespace")
}
logDone("run - net container mode, where container in host mode")
}
func TestRunAllowPortRangeThroughPublish(t *testing.T) { func TestRunAllowPortRangeThroughPublish(t *testing.T) {
defer deleteAllContainers() defer deleteAllContainers()

View file

@ -1 +1,2 @@
bundles
nsinit/nsinit nsinit/nsinit

View file

@ -29,3 +29,5 @@ local:
validate: validate:
hack/validate.sh hack/validate.sh
binary: all
docker run --rm --privileged -v $(CURDIR)/bundles:/go/bin dockercore/libcontainer make direct-install

View file

@ -141,6 +141,9 @@ container.Resume()
It is able to spawn new containers or join existing containers. A root 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. filesystem must be provided for use along with a container configuration file.
To build `nsinit`, run `make binary`. It will save the binary into
`bundles/nsinit`.
To use `nsinit`, cd into a Linux rootfs and copy a `container.json` file into To use `nsinit`, cd into a Linux rootfs and copy a `container.json` file into
the directory with your specified configuration. Environment, networking, the directory with your specified configuration. Environment, networking,
and different capabilities for the container are specified in this file. and different capabilities for the container are specified in this file.

View file

@ -3,7 +3,6 @@
package systemd package systemd
import ( import (
"bytes"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
@ -247,6 +246,21 @@ func writeFile(dir, file, data string) error {
return ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700) return ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700)
} }
func join(c *configs.Cgroup, subsystem string, pid int) (string, error) {
path, err := getSubsystemPath(c, subsystem)
if err != nil {
return "", err
}
if err := os.MkdirAll(path, 0755); err != nil && !os.IsExist(err) {
return "", err
}
if err := writeFile(path, "cgroup.procs", strconv.Itoa(pid)); err != nil {
return "", err
}
return path, nil
}
func joinCpu(c *configs.Cgroup, pid int) error { func joinCpu(c *configs.Cgroup, pid int) error {
path, err := getSubsystemPath(c, "cpu") path, err := getSubsystemPath(c, "cpu")
if err != nil { if err != nil {
@ -266,16 +280,11 @@ func joinCpu(c *configs.Cgroup, pid int) error {
} }
func joinFreezer(c *configs.Cgroup, pid int) error { func joinFreezer(c *configs.Cgroup, pid int) error {
path, err := getSubsystemPath(c, "freezer") if _, err := join(c, "freezer", pid); err != nil {
if err != nil {
return err return err
} }
if err := os.MkdirAll(path, 0755); err != nil && !os.IsExist(err) { return nil
return err
}
return ioutil.WriteFile(filepath.Join(path, "cgroup.procs"), []byte(strconv.Itoa(pid)), 0700)
} }
func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) { func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) {
@ -303,21 +312,15 @@ func (m *Manager) Freeze(state configs.FreezerState) error {
return err return err
} }
if err := ioutil.WriteFile(filepath.Join(path, "freezer.state"), []byte(state), 0); err != nil { prevState := m.Cgroups.Freezer
m.Cgroups.Freezer = state
freezer := subsystems["freezer"]
err = freezer.Set(path, m.Cgroups)
if err != nil {
m.Cgroups.Freezer = prevState
return err return err
} }
for {
state_, err := ioutil.ReadFile(filepath.Join(path, "freezer.state"))
if err != nil {
return err
}
if string(state) == string(bytes.TrimSpace(state_)) {
break
}
time.Sleep(1 * time.Millisecond)
}
m.Cgroups.Freezer = state
return nil return nil
} }
@ -366,29 +369,16 @@ func getUnitName(c *configs.Cgroup) string {
// because systemd will re-write the device settings if it needs to re-apply the cgroup context. // because systemd will re-write the device settings if it needs to re-apply the cgroup context.
// This happens at least for v208 when any sibling unit is started. // This happens at least for v208 when any sibling unit is started.
func joinDevices(c *configs.Cgroup, pid int) error { func joinDevices(c *configs.Cgroup, pid int) error {
path, err := getSubsystemPath(c, "devices") path, err := join(c, "devices", pid)
if err != nil { if err != nil {
return err return err
} }
if err := os.MkdirAll(path, 0755); err != nil && !os.IsExist(err) { devices := subsystems["devices"]
if err := devices.Set(path, c); err != nil {
return err return err
} }
if err := ioutil.WriteFile(filepath.Join(path, "cgroup.procs"), []byte(strconv.Itoa(pid)), 0700); err != nil {
return err
}
if !c.AllowAllDevices {
if err := writeFile(path, "devices.deny", "a"); err != nil {
return err
}
}
for _, dev := range c.AllowedDevices {
if err := writeFile(path, "devices.allow", dev.CgroupString()); err != nil {
return err
}
}
return nil return nil
} }

View file

@ -16,6 +16,17 @@ const (
NEWUSER NamespaceType = "NEWUSER" NEWUSER NamespaceType = "NEWUSER"
) )
func NamespaceTypes() []NamespaceType {
return []NamespaceType{
NEWNET,
NEWPID,
NEWNS,
NEWUTS,
NEWIPC,
NEWUSER,
}
}
// Namespace defines configuration for each namespace. It specifies an // Namespace defines configuration for each namespace. It specifies an
// alternate path that is able to be joined via setns. // alternate path that is able to be joined via setns.
type Namespace struct { type Namespace struct {

View file

@ -306,5 +306,11 @@ func (c *linuxContainer) currentState() (*State, error) {
for _, ns := range c.config.Namespaces { for _, ns := range c.config.Namespaces {
state.NamespacePaths[ns.Type] = ns.GetPath(c.initProcess.pid()) state.NamespacePaths[ns.Type] = ns.GetPath(c.initProcess.pid())
} }
for _, nsType := range configs.NamespaceTypes() {
if _, ok := state.NamespacePaths[nsType]; !ok {
ns := configs.Namespace{Type: nsType}
state.NamespacePaths[ns.Type] = ns.GetPath(c.initProcess.pid())
}
}
return state, nil return state, nil
} }

View file

@ -130,7 +130,8 @@ func TestGetContainerState(t *testing.T) {
{Type: configs.NEWNS}, {Type: configs.NEWNS},
{Type: configs.NEWNET, Path: expectedNetworkPath}, {Type: configs.NEWNET, Path: expectedNetworkPath},
{Type: configs.NEWUTS}, {Type: configs.NEWUTS},
{Type: configs.NEWIPC}, // emulate host for IPC
//{Type: configs.NEWIPC},
}, },
}, },
initProcess: &mockProcess{ initProcess: &mockProcess{

View file

@ -9,6 +9,7 @@ import (
"testing" "testing"
"github.com/docker/libcontainer" "github.com/docker/libcontainer"
"github.com/docker/libcontainer/cgroups/systemd"
"github.com/docker/libcontainer/configs" "github.com/docker/libcontainer/configs"
) )
@ -481,6 +482,17 @@ func TestProcessCaps(t *testing.T) {
} }
func TestFreeze(t *testing.T) { func TestFreeze(t *testing.T) {
testFreeze(t, false)
}
func TestSystemdFreeze(t *testing.T) {
if !systemd.UseSystemd() {
t.Skip("Systemd is unsupported")
}
testFreeze(t, true)
}
func testFreeze(t *testing.T, systemd bool) {
if testing.Short() { if testing.Short() {
return return
} }
@ -497,6 +509,9 @@ func TestFreeze(t *testing.T) {
defer remove(rootfs) defer remove(rootfs)
config := newTemplateConfig(rootfs) config := newTemplateConfig(rootfs)
if systemd {
config.Cgroups.Slice = "system.slice"
}
factory, err := libcontainer.New(root, libcontainer.Cgroupfs) factory, err := libcontainer.New(root, libcontainer.Cgroupfs)
if err != nil { if err != nil {
@ -559,3 +574,77 @@ func TestFreeze(t *testing.T) {
t.Fatal(s.String()) t.Fatal(s.String())
} }
} }
func TestContainerState(t *testing.T) {
if testing.Short() {
return
}
root, err := newTestRoot()
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(root)
rootfs, err := newRootfs()
if err != nil {
t.Fatal(err)
}
defer remove(rootfs)
l, err := os.Readlink("/proc/1/ns/ipc")
if err != nil {
t.Fatal(err)
}
config := newTemplateConfig(rootfs)
config.Namespaces = configs.Namespaces([]configs.Namespace{
{Type: configs.NEWNS},
{Type: configs.NEWUTS},
// host for IPC
//{Type: configs.NEWIPC},
{Type: configs.NEWPID},
{Type: configs.NEWNET},
})
factory, err := libcontainer.New(root, libcontainer.Cgroupfs)
if err != nil {
t.Fatal(err)
}
container, err := factory.Create("test", config)
if err != nil {
t.Fatal(err)
}
defer container.Destroy()
stdinR, stdinW, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
p := &libcontainer.Process{
Args: []string{"cat"},
Env: standardEnvironment,
Stdin: stdinR,
}
err = container.Start(p)
if err != nil {
t.Fatal(err)
}
stdinR.Close()
defer p.Signal(os.Kill)
st, err := container.State()
if err != nil {
t.Fatal(err)
}
l1, err := os.Readlink(st.NamespacePaths[configs.NEWIPC])
if err != nil {
t.Fatal(err)
}
if l1 != l {
t.Fatal("Container using non-host ipc namespace")
}
stdinW.Close()
p.Wait()
}

View file

@ -68,9 +68,14 @@ func copyBusybox(dest string) error {
} }
func newContainer(config *configs.Config) (libcontainer.Container, error) { func newContainer(config *configs.Config) (libcontainer.Container, error) {
cgm := libcontainer.Cgroupfs
if config.Cgroups != nil && config.Cgroups.Slice == "system.slice" {
cgm = libcontainer.SystemdCgroups
}
factory, err := libcontainer.New(".", factory, err := libcontainer.New(".",
libcontainer.InitArgs(os.Args[0], "init", "--"), libcontainer.InitArgs(os.Args[0], "init", "--"),
libcontainer.Cgroupfs, cgm,
) )
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -13,7 +13,7 @@ func main() {
app.Version = "2" app.Version = "2"
app.Author = "libcontainer maintainers" app.Author = "libcontainer maintainers"
app.Flags = []cli.Flag{ app.Flags = []cli.Flag{
cli.StringFlag{Name: "root", Value: ".", Usage: "root directory for containers"}, cli.StringFlag{Name: "root", Value: "/var/run/nsinit", Usage: "root directory for containers"},
cli.StringFlag{Name: "log-file", Value: "", Usage: "set the log file to output logs to"}, cli.StringFlag{Name: "log-file", Value: "", Usage: "set the log file to output logs to"},
cli.BoolFlag{Name: "debug", Usage: "enable debug output in the logs"}, cli.BoolFlag{Name: "debug", Usage: "enable debug output in the logs"},
} }