Переглянути джерело

Add log opts flag to pass in logging options

Signed-off-by: wlan0 <sidharthamn@gmail.com>
wlan0 10 роки тому
батько
коміт
dca9e02b15
6 змінених файлів з 111 додано та 1 видалено
  1. 1 0
      daemon/config.go
  2. 3 0
      docker/daemon.go
  3. 4 0
      docs/sources/reference/run.md
  4. 51 0
      opts/opts.go
  5. 35 0
      opts/opts_test.go
  6. 17 1
      runconfig/parse.go

+ 1 - 0
daemon/config.go

@@ -80,6 +80,7 @@ func (config *Config) InstallFlags() {
 	opts.UlimitMapVar(config.Ulimits, []string{"-default-ulimit"}, "Set default ulimits for containers")
 	flag.StringVar(&config.LogConfig.Type, []string{"-log-driver"}, "json-file", "Default driver for container logs")
 	flag.BoolVar(&config.Bridge.EnableUserlandProxy, []string{"-userland-proxy"}, true, "Use userland proxy for loopback traffic")
+	opts.LogOptsVar(config.LogConfig.Config, []string{"-log-opt"}, "Set log driver options")
 }
 
 func getDefaultNetworkMtu() int {

+ 3 - 0
docker/daemon.go

@@ -32,6 +32,9 @@ var (
 )
 
 func init() {
+	if daemonCfg.LogConfig.Config == nil {
+		daemonCfg.LogConfig.Config = make(map[string]string)
+	}
 	daemonCfg.InstallFlags()
 	registryCfg.InstallFlags()
 }

+ 4 - 0
docs/sources/reference/run.md

@@ -849,6 +849,10 @@ command is not available for this logging driver
 
 Journald logging driver for Docker. Writes log messages to journald; the container id will be stored in the journal's `CONTAINER_ID` field. `docker logs` command is not available for this logging driver.  For detailed information on working with this logging driver, see [the journald logging driver](reference/logging/journald) reference documentation.
 
+#### Log Opts : 
+
+Logging options for configuring a log driver. The following log options are supported: [none]
+
 ## Overriding Dockerfile image defaults
 
 When a developer builds an image from a [*Dockerfile*](/reference/builder)

+ 51 - 0
opts/opts.go

@@ -28,6 +28,14 @@ func ListVar(values *[]string, names []string, usage string) {
 	flag.Var(newListOptsRef(values, nil), names, usage)
 }
 
+func MapVar(values map[string]string, names []string, usage string) {
+	flag.Var(newMapOpt(values, nil), names, usage)
+}
+
+func LogOptsVar(values map[string]string, names []string, usage string) {
+	flag.Var(newMapOpt(values, ValidateLogOpts), names, usage)
+}
+
 func HostListVar(values *[]string, names []string, usage string) {
 	flag.Var(newListOptsRef(values, ValidateHost), names, usage)
 }
@@ -130,10 +138,53 @@ func (opts *ListOpts) Len() int {
 	return len((*opts.values))
 }
 
+//MapOpts type
+type MapOpts struct {
+	values    map[string]string
+	validator ValidatorFctType
+}
+
+func (opts *MapOpts) Set(value string) error {
+	if opts.validator != nil {
+		v, err := opts.validator(value)
+		if err != nil {
+			return err
+		}
+		value = v
+	}
+	vals := strings.SplitN(value, "=", 2)
+	if len(vals) == 1 {
+		(opts.values)[vals[0]] = ""
+	} else {
+		(opts.values)[vals[0]] = vals[1]
+	}
+	return nil
+}
+
+func (opts *MapOpts) String() string {
+	return fmt.Sprintf("%v", map[string]string((opts.values)))
+}
+
+func newMapOpt(values map[string]string, validator ValidatorFctType) *MapOpts {
+	return &MapOpts{
+		values:    values,
+		validator: validator,
+	}
+}
+
 // Validators
 type ValidatorFctType func(val string) (string, error)
 type ValidatorFctListType func(val string) ([]string, error)
 
+func ValidateLogOpts(val string) (string, error) {
+	allowedKeys := map[string]string{}
+	vals := strings.Split(val, "=")
+	if allowedKeys[vals[0]] != "" {
+		return val, nil
+	}
+	return "", fmt.Errorf("%s is not a valid log opt", vals[0])
+}
+
 func ValidateAttach(val string) (string, error) {
 	s := strings.ToLower(val)
 	for _, str := range []string{"stdin", "stdout", "stderr"} {

+ 35 - 0
opts/opts_test.go

@@ -1,6 +1,7 @@
 package opts
 
 import (
+	"fmt"
 	"strings"
 	"testing"
 )
@@ -28,6 +29,31 @@ func TestValidateIPAddress(t *testing.T) {
 
 }
 
+func TestMapOpts(t *testing.T) {
+	tmpMap := make(map[string]string)
+	o := newMapOpt(tmpMap, logOptsValidator)
+	o.Set("max-size=1")
+	if o.String() != "map[max-size:1]" {
+		t.Errorf("%s != [map[max-size:1]", o.String())
+	}
+
+	o.Set("max-file=2")
+	if len(tmpMap) != 2 {
+		t.Errorf("map length %d != 2", len(tmpMap))
+	}
+
+	if tmpMap["max-file"] != "2" {
+		t.Errorf("max-file = %s != 2", tmpMap["max-file"])
+	}
+
+	if tmpMap["max-size"] != "1" {
+		t.Errorf("max-size = %s != 1", tmpMap["max-size"])
+	}
+	if o.Set("dummy-val=3") == nil {
+		t.Errorf("validator is not being called")
+	}
+}
+
 func TestValidateMACAddress(t *testing.T) {
 	if _, err := ValidateMACAddress(`92:d0:c6:0a:29:33`); err != nil {
 		t.Fatalf("ValidateMACAddress(`92:d0:c6:0a:29:33`) got %s", err)
@@ -152,3 +178,12 @@ func TestValidateExtraHosts(t *testing.T) {
 		}
 	}
 }
+
+func logOptsValidator(val string) (string, error) {
+	allowedKeys := map[string]string{"max-size": "1", "max-file": "2"}
+	vals := strings.Split(val, "=")
+	if allowedKeys[vals[0]] != "" {
+		return val, nil
+	}
+	return "", fmt.Errorf("invalid key %s", vals[0])
+}

+ 17 - 1
runconfig/parse.go

@@ -47,6 +47,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
 		flCapDrop     = opts.NewListOpts(nil)
 		flSecurityOpt = opts.NewListOpts(nil)
 		flLabelsFile  = opts.NewListOpts(nil)
+		flLoggingOpts = opts.NewListOpts(nil)
 
 		flNetwork         = cmd.Bool([]string{"#n", "#-networking"}, true, "Enable networking for this container")
 		flPrivileged      = cmd.Bool([]string{"#privileged", "-privileged"}, false, "Give extended privileges to this container")
@@ -95,6 +96,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
 	cmd.Var(&flCapDrop, []string{"-cap-drop"}, "Drop Linux capabilities")
 	cmd.Var(&flSecurityOpt, []string{"-security-opt"}, "Security Options")
 	cmd.Var(flUlimits, []string{"-ulimit"}, "Ulimit options")
+	cmd.Var(&flLoggingOpts, []string{"-log-opt"}, "Log driver options")
 
 	cmd.Require(flag.Min, 1)
 
@@ -283,6 +285,11 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
 		return nil, nil, cmd, err
 	}
 
+	loggingOpts, err := parseLoggingOpts(*flLoggingDriver, flLoggingOpts.GetAll())
+	if err != nil {
+		return nil, nil, cmd, err
+	}
+
 	config := &Config{
 		Hostname:        hostname,
 		Domainname:      domainname,
@@ -335,7 +342,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
 		SecurityOpt:     flSecurityOpt.GetAll(),
 		ReadonlyRootfs:  *flReadonlyRootfs,
 		Ulimits:         flUlimits.GetList(),
-		LogConfig:       LogConfig{Type: *flLoggingDriver},
+		LogConfig:       LogConfig{Type: *flLoggingDriver, Config: loggingOpts},
 		CgroupParent:    *flCgroupParent,
 	}
 
@@ -377,6 +384,15 @@ func convertKVStringsToMap(values []string) map[string]string {
 	return result
 }
 
+func parseLoggingOpts(loggingDriver string, loggingOpts []string) (map[string]string, error) {
+	loggingOptsMap := convertKVStringsToMap(loggingOpts)
+	if loggingDriver == "none" && len(loggingOpts) > 0 {
+		return map[string]string{}, fmt.Errorf("Invalid logging opts for driver %s", loggingDriver)
+	}
+	//TODO - validation step
+	return loggingOptsMap, nil
+}
+
 // ParseRestartPolicy returns the parsed policy or an error indicating what is incorrect
 func ParseRestartPolicy(policy string) (RestartPolicy, error) {
 	p := RestartPolicy{}