Forráskód Böngészése

inherit the daemon log options when creating containers

Signed-off-by: Shijiang Wei <mountkin@gmail.com>
Shijiang Wei 9 éve
szülő
commit
1790980ec6

+ 4 - 0
daemon/create.go

@@ -69,6 +69,10 @@ func (daemon *Daemon) create(params types.ContainerCreateConfig) (retC *containe
 		return nil, err
 	}
 
+	if err := daemon.mergeAndVerifyLogConfig(&params.HostConfig.LogConfig); err != nil {
+		return nil, err
+	}
+
 	if container, err = daemon.newContainer(params.Name, params.Config, imgID); err != nil {
 		return nil, err
 	}

+ 0 - 12
daemon/daemon.go

@@ -35,7 +35,6 @@ import (
 	"github.com/docker/engine-api/types/strslice"
 	// register graph drivers
 	_ "github.com/docker/docker/daemon/graphdriver/register"
-	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/daemon/network"
 	dmetadata "github.com/docker/docker/distribution/metadata"
 	"github.com/docker/docker/distribution/xfer"
@@ -669,12 +668,6 @@ func NewDaemon(config *Config, registryService *registry.Service, containerdRemo
 		return nil, fmt.Errorf("error setting default isolation mode: %v", err)
 	}
 
-	// Verify logging driver type
-	if config.LogConfig.Type != "none" {
-		if _, err := logger.GetLogDriver(config.LogConfig.Type); err != nil {
-			return nil, fmt.Errorf("error finding the logging driver: %v", err)
-		}
-	}
 	logrus.Debugf("Using default logging driver %s", config.LogConfig.Type)
 
 	if err := configureMaxThreads(config); err != nil {
@@ -1351,11 +1344,6 @@ func (daemon *Daemon) verifyContainerSettings(hostConfig *containertypes.HostCon
 		return nil, nil
 	}
 
-	logCfg := daemon.getLogConfig(hostConfig.LogConfig)
-	if err := logger.ValidateLogOpts(logCfg.Type, logCfg.Config); err != nil {
-		return nil, err
-	}
-
 	for port := range hostConfig.PortBindings {
 		_, portStr := nat.SplitProtoPort(string(port))
 		if _, err := nat.ParsePort(portStr); err != nil {

+ 22 - 7
daemon/logger/factory.go

@@ -19,16 +19,23 @@ type logdriverFactory struct {
 }
 
 func (lf *logdriverFactory) register(name string, c Creator) error {
-	lf.m.Lock()
-	defer lf.m.Unlock()
-
-	if _, ok := lf.registry[name]; ok {
+	if lf.driverRegistered(name) {
 		return fmt.Errorf("logger: log driver named '%s' is already registered", name)
 	}
+
+	lf.m.Lock()
 	lf.registry[name] = c
+	lf.m.Unlock()
 	return nil
 }
 
+func (lf *logdriverFactory) driverRegistered(name string) bool {
+	lf.m.Lock()
+	_, ok := lf.registry[name]
+	lf.m.Unlock()
+	return ok
+}
+
 func (lf *logdriverFactory) registerLogOptValidator(name string, l LogOptValidator) error {
 	lf.m.Lock()
 	defer lf.m.Unlock()
@@ -81,9 +88,17 @@ func GetLogDriver(name string) (Creator, error) {
 // ValidateLogOpts checks the options for the given log driver. The
 // options supported are specific to the LogDriver implementation.
 func ValidateLogOpts(name string, cfg map[string]string) error {
-	l := factory.getLogOptValidator(name)
-	if l != nil {
-		return l(cfg)
+	if name == "none" {
+		return nil
+	}
+
+	if !factory.driverRegistered(name) {
+		return fmt.Errorf("logger: no log driver named '%s' is registered", name)
+	}
+
+	validator := factory.getLogOptValidator(name)
+	if validator != nil {
+		return validator(cfg)
 	}
 	return nil
 }

+ 15 - 19
daemon/logs.go

@@ -107,24 +107,16 @@ func (daemon *Daemon) getLogger(container *container.Container) (logger.Logger,
 	if container.LogDriver != nil && container.IsRunning() {
 		return container.LogDriver, nil
 	}
-	cfg := daemon.getLogConfig(container.HostConfig.LogConfig)
-	if err := logger.ValidateLogOpts(cfg.Type, cfg.Config); err != nil {
-		return nil, err
-	}
-	return container.StartLogger(cfg)
+	return container.StartLogger(container.HostConfig.LogConfig)
 }
 
 // StartLogging initializes and starts the container logging stream.
 func (daemon *Daemon) StartLogging(container *container.Container) error {
-	cfg := daemon.getLogConfig(container.HostConfig.LogConfig)
-	if cfg.Type == "none" {
+	if container.HostConfig.LogConfig.Type == "none" {
 		return nil // do not start logging routines
 	}
 
-	if err := logger.ValidateLogOpts(cfg.Type, cfg.Config); err != nil {
-		return err
-	}
-	l, err := container.StartLogger(cfg)
+	l, err := container.StartLogger(container.HostConfig.LogConfig)
 	if err != nil {
 		return fmt.Errorf("Failed to initialize logging driver: %v", err)
 	}
@@ -142,15 +134,19 @@ func (daemon *Daemon) StartLogging(container *container.Container) error {
 	return nil
 }
 
-// getLogConfig returns the log configuration for the container.
-func (daemon *Daemon) getLogConfig(cfg containertypes.LogConfig) containertypes.LogConfig {
-	if cfg.Type != "" || len(cfg.Config) > 0 { // container has log driver configured
-		if cfg.Type == "" {
-			cfg.Type = jsonfilelog.Name
+// mergeLogConfig merges the daemon log config to the container's log config if the container's log driver is not specified.
+func (daemon *Daemon) mergeAndVerifyLogConfig(cfg *containertypes.LogConfig) error {
+	if cfg.Type == "" {
+		cfg.Type = daemon.defaultLogConfig.Type
+	}
+
+	if cfg.Type == daemon.defaultLogConfig.Type {
+		for k, v := range daemon.defaultLogConfig.Config {
+			if _, ok := cfg.Config[k]; !ok {
+				cfg.Config[k] = v
+			}
 		}
-		return cfg
 	}
 
-	// Use daemon's default log config for containers
-	return daemon.defaultLogConfig
+	return logger.ValidateLogOpts(cfg.Type, cfg.Config)
 }

+ 3 - 0
daemon/start.go

@@ -41,6 +41,9 @@ func (daemon *Daemon) ContainerStart(name string, hostConfig *containertypes.Hos
 			if err := daemon.setSecurityOptions(container, hostConfig); err != nil {
 				return err
 			}
+			if err := daemon.mergeAndVerifyLogConfig(&hostConfig.LogConfig); err != nil {
+				return err
+			}
 			if err := daemon.setHostConfig(container, hostConfig); err != nil {
 				return err
 			}

+ 11 - 7
integration-cli/docker_cli_daemon_test.go

@@ -1748,17 +1748,21 @@ func (s *DockerDaemonSuite) TestDaemonRestartWithContainerWithRestartPolicyAlway
 }
 
 func (s *DockerDaemonSuite) TestDaemonWideLogConfig(c *check.C) {
-	if err := s.d.StartWithBusybox("--log-driver=json-file", "--log-opt=max-size=1k"); err != nil {
+	if err := s.d.StartWithBusybox("--log-opt=max-size=1k"); err != nil {
 		c.Fatal(err)
 	}
-	out, err := s.d.Cmd("run", "-d", "--name=logtest", "busybox", "top")
+	name := "logtest"
+	out, err := s.d.Cmd("run", "-d", "--log-opt=max-file=5", "--name", name, "busybox", "top")
 	c.Assert(err, check.IsNil, check.Commentf("Output: %s, err: %v", out, err))
-	out, err = s.d.Cmd("inspect", "-f", "{{ .HostConfig.LogConfig.Config }}", "logtest")
+
+	out, err = s.d.Cmd("inspect", "-f", "{{ .HostConfig.LogConfig.Config }}", name)
 	c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
-	cfg := strings.TrimSpace(out)
-	if cfg != "map[max-size:1k]" {
-		c.Fatalf("Unexpected log-opt: %s, expected map[max-size:1k]", cfg)
-	}
+	c.Assert(out, checker.Contains, "max-size:1k")
+	c.Assert(out, checker.Contains, "max-file:5")
+
+	out, err = s.d.Cmd("inspect", "-f", "{{ .HostConfig.LogConfig.Type }}", name)
+	c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
+	c.Assert(strings.TrimSpace(out), checker.Equals, "json-file")
 }
 
 func (s *DockerDaemonSuite) TestDaemonRestartWithPausedContainer(c *check.C) {