mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	Fix ulimits in docker inspect when daemon default exists
				
					
				
			This fix tries to fix 26326 where `docker inspect` will not show ulimit even when daemon default ulimit has been set. This fix merge the HostConfig's ulimit with daemon default in `docker inspect`, so that when daemon is started with `default-ulimit` and HostConfig's ulimit is not set, `docker inspect` will output the daemon default. An integration test has been added to cover the changes. This fix fixes 26326. Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
This commit is contained in:
		
							parent
							
								
									5be6ccc433
								
							
						
					
					
						commit
						7d705a7355
					
				
					 5 changed files with 60 additions and 13 deletions
				
			
		| 
						 | 
				
			
			@ -110,6 +110,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{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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]")
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue