Explorar el Código

Merge pull request #12161 from LK4D4/update_libcontainer

Update libcontainer
Michael Crosby hace 10 años
padre
commit
06433cf812

+ 1 - 1
hack/vendor.sh

@@ -75,7 +75,7 @@ rm -rf src/github.com/docker/distribution
 mkdir -p src/github.com/docker/distribution
 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)
 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')"

+ 29 - 0
integration-cli/docker_cli_run_test.go

@@ -3249,6 +3249,35 @@ func TestRunNetHost(t *testing.T) {
 	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) {
 	defer deleteAllContainers()
 

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

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

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

@@ -29,3 +29,5 @@ local:
 validate:
 	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
 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 
 the directory with your specified configuration. Environment, networking, 
 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
 
 import (
-	"bytes"
 	"fmt"
 	"io/ioutil"
 	"os"
@@ -247,6 +246,21 @@ func writeFile(dir, file, data string) error {
 	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 {
 	path, err := getSubsystemPath(c, "cpu")
 	if err != nil {
@@ -266,16 +280,11 @@ func joinCpu(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
 	}
 
-	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) {
@@ -303,21 +312,15 @@ func (m *Manager) Freeze(state configs.FreezerState) error {
 		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
 	}
-	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
 }
@@ -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.
 // This happens at least for v208 when any sibling unit is started.
 func joinDevices(c *configs.Cgroup, pid int) error {
-	path, err := getSubsystemPath(c, "devices")
+	path, err := join(c, "devices", pid)
 	if err != nil {
 		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
 	}
 
-	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
 }
 

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

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

+ 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.NEWNET, Path: expectedNetworkPath},
 				{Type: configs.NEWUTS},
-				{Type: configs.NEWIPC},
+				// emulate host for IPC
+				//{Type: configs.NEWIPC},
 			},
 		},
 		initProcess: &mockProcess{

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

@@ -9,6 +9,7 @@ import (
 	"testing"
 
 	"github.com/docker/libcontainer"
+	"github.com/docker/libcontainer/cgroups/systemd"
 	"github.com/docker/libcontainer/configs"
 )
 
@@ -481,6 +482,17 @@ func TestProcessCaps(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() {
 		return
 	}
@@ -497,6 +509,9 @@ func TestFreeze(t *testing.T) {
 	defer remove(rootfs)
 
 	config := newTemplateConfig(rootfs)
+	if systemd {
+		config.Cgroups.Slice = "system.slice"
+	}
 
 	factory, err := libcontainer.New(root, libcontainer.Cgroupfs)
 	if err != nil {
@@ -559,3 +574,77 @@ func TestFreeze(t *testing.T) {
 		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) {
+	cgm := libcontainer.Cgroupfs
+	if config.Cgroups != nil && config.Cgroups.Slice == "system.slice" {
+		cgm = libcontainer.SystemdCgroups
+	}
+
 	factory, err := libcontainer.New(".",
 		libcontainer.InitArgs(os.Args[0], "init", "--"),
-		libcontainer.Cgroupfs,
+		cgm,
 	)
 	if err != nil {
 		return nil, err

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

@@ -13,7 +13,7 @@ func main() {
 	app.Version = "2"
 	app.Author = "libcontainer maintainers"
 	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.BoolFlag{Name: "debug", Usage: "enable debug output in the logs"},
 	}