Explorar o código

Merge pull request #26405 from yongtang/26326-inspect-ulimit-with-daemon-default

Fix Ulimits in `docker inspect` when daemon default exists
Brian Goff %!s(int64=8) %!d(string=hai) anos
pai
achega
ba07661f0d

+ 3 - 0
daemon/inspect.go

@@ -117,6 +117,9 @@ func (daemon *Daemon) getInspectData(container *container.Container, size bool)
 		hostConfig.Links = append(hostConfig.Links, fmt.Sprintf("%s:%s", child.Name, linkAlias))
 	}
 
+	// We merge the Ulimits from hostConfig with daemon default
+	daemon.mergeUlimits(&hostConfig)
+
 	var containerHealth *types.Health
 	if container.State.Health != nil {
 		containerHealth = &types.Health{

+ 21 - 13
daemon/oci_linux.go

@@ -115,19 +115,11 @@ func setDevices(s *specs.Spec, c *container.Container) error {
 func setRlimits(daemon *Daemon, s *specs.Spec, c *container.Container) error {
 	var rlimits []specs.Rlimit
 
-	ulimits := c.HostConfig.Ulimits
-	// Merge ulimits with daemon defaults
-	ulIdx := make(map[string]struct{})
-	for _, ul := range ulimits {
-		ulIdx[ul.Name] = struct{}{}
-	}
-	for name, ul := range daemon.configStore.Ulimits {
-		if _, exists := ulIdx[name]; !exists {
-			ulimits = append(ulimits, ul)
-		}
-	}
-
-	for _, ul := range ulimits {
+	// We want to leave the original HostConfig alone so make a copy here
+	hostConfig := *c.HostConfig
+	// Merge with the daemon defaults
+	daemon.mergeUlimits(&hostConfig)
+	for _, ul := range hostConfig.Ulimits {
 		rlimits = append(rlimits, specs.Rlimit{
 			Type: "RLIMIT_" + strings.ToUpper(ul.Name),
 			Soft: uint64(ul.Soft),
@@ -709,3 +701,19 @@ func clearReadOnly(m *specs.Mount) {
 	}
 	m.Options = opt
 }
+
+// mergeUlimits merge the Ulimits from HostConfig with daemon defaults, and update HostConfig
+func (daemon *Daemon) mergeUlimits(c *containertypes.HostConfig) {
+	ulimits := c.Ulimits
+	// Merge ulimits with daemon defaults
+	ulIdx := make(map[string]struct{})
+	for _, ul := range ulimits {
+		ulIdx[ul.Name] = struct{}{}
+	}
+	for name, ul := range daemon.configStore.Ulimits {
+		if _, exists := ulIdx[name]; !exists {
+			ulimits = append(ulimits, ul)
+		}
+	}
+	c.Ulimits = ulimits
+}

+ 7 - 0
daemon/oci_solaris.go

@@ -1,6 +1,7 @@
 package daemon
 
 import (
+	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/libcontainerd"
 	"github.com/docker/docker/oci"
@@ -10,3 +11,9 @@ func (daemon *Daemon) createSpec(c *container.Container) (*libcontainerd.Spec, e
 	s := oci.DefaultSpec()
 	return (*libcontainerd.Spec)(&s), nil
 }
+
+// mergeUlimits merge the Ulimits from HostConfig with daemon defaults, and update HostConfig
+// It will do nothing on non-Linux platform
+func (daemon *Daemon) mergeUlimits(c *containertypes.HostConfig) {
+	return
+}

+ 7 - 0
daemon/oci_windows.go

@@ -7,6 +7,7 @@ import (
 	"path/filepath"
 	"syscall"
 
+	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/layer"
@@ -192,3 +193,9 @@ func escapeArgs(args []string) []string {
 	}
 	return escapedArgs
 }
+
+// mergeUlimits merge the Ulimits from HostConfig with daemon defaults, and update HostConfig
+// It will do nothing on non-Linux platform
+func (daemon *Daemon) mergeUlimits(c *containertypes.HostConfig) {
+	return
+}

+ 22 - 0
integration-cli/docker_cli_run_test.go

@@ -4518,3 +4518,25 @@ exec "$@"`,
 	c.Assert(err, check.NotNil)
 	c.Assert(err.Error(), checker.Contains, "No command specified")
 }
+
+func (s *DockerDaemonSuite) TestRunWithUlimitAndDaemonDefault(c *check.C) {
+	c.Assert(s.d.StartWithBusybox("--debug", "--default-ulimit=nofile=65535"), checker.IsNil)
+
+	name := "test-A"
+	_, err := s.d.Cmd("run", "--name", name, "-d", "busybox", "top")
+	c.Assert(err, checker.IsNil)
+	c.Assert(s.d.waitRun(name), check.IsNil)
+
+	out, err := s.d.Cmd("inspect", "--format", "{{.HostConfig.Ulimits}}", name)
+	c.Assert(err, checker.IsNil)
+	c.Assert(out, checker.Contains, "[nofile=65535:65535]")
+
+	name = "test-B"
+	_, err = s.d.Cmd("run", "--name", name, "--ulimit=nofile=42", "-d", "busybox", "top")
+	c.Assert(err, checker.IsNil)
+	c.Assert(s.d.waitRun(name), check.IsNil)
+
+	out, err = s.d.Cmd("inspect", "--format", "{{.HostConfig.Ulimits}}", name)
+	c.Assert(err, checker.IsNil)
+	c.Assert(out, checker.Contains, "[nofile=42:42]")
+}