Ver código fonte

Update libcontainer to bd8ec36106086f72b66e1be85a81202b93503e44

Fix #12130

Signed-off-by: Alexander Morozov <lk4d4@docker.com>
Alexander Morozov 10 anos atrás
pai
commit
2f853b9493

+ 1 - 1
hack/vendor.sh

@@ -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')"

+ 1 - 0
vendor/src/github.com/docker/libcontainer/.gitignore

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

+ 2 - 0
vendor/src/github.com/docker/libcontainer/Makefile

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

+ 3 - 0
vendor/src/github.com/docker/libcontainer/README.md

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

+ 27 - 37
vendor/src/github.com/docker/libcontainer/cgroups/systemd/apply_systemd.go

@@ -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 != nil {
+	if _, err := join(c, "freezer", pid); err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	if err := os.MkdirAll(path, 0755); err != nil && !os.IsExist(err) {
-		return err
-	}
-
-	return ioutil.WriteFile(filepath.Join(path, "cgroup.procs"), []byte(strconv.Itoa(pid)), 0700)
+	return nil
 }
 }
 
 
 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) {
-		return err
-	}
-
-	if err := ioutil.WriteFile(filepath.Join(path, "cgroup.procs"), []byte(strconv.Itoa(pid)), 0700); err != nil {
+	devices := subsystems["devices"]
+	if err := devices.Set(path, c); err != nil {
 		return err
 		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
 }
 }
 
 

+ 11 - 0
vendor/src/github.com/docker/libcontainer/configs/namespaces.go

@@ -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 {

+ 6 - 0
vendor/src/github.com/docker/libcontainer/container_linux.go

@@ -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
 }
 }

+ 2 - 1
vendor/src/github.com/docker/libcontainer/container_linux_test.go

@@ -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{

+ 89 - 0
vendor/src/github.com/docker/libcontainer/integration/exec_test.go

@@ -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()
+}

+ 6 - 1
vendor/src/github.com/docker/libcontainer/integration/utils_test.go

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

+ 1 - 1
vendor/src/github.com/docker/libcontainer/nsinit/main.go

@@ -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"},
 	}
 	}