Browse code

Add log opts flag to pass in logging options

Signed-off-by: wlan0 <sidharthamn@gmail.com>

wlan0 authored on 2015/05/05 06:39:48
Showing 6 changed files
... ...
@@ -80,6 +80,7 @@ func (config *Config) InstallFlags() {
80 80
 	opts.UlimitMapVar(config.Ulimits, []string{"-default-ulimit"}, "Set default ulimits for containers")
81 81
 	flag.StringVar(&config.LogConfig.Type, []string{"-log-driver"}, "json-file", "Default driver for container logs")
82 82
 	flag.BoolVar(&config.Bridge.EnableUserlandProxy, []string{"-userland-proxy"}, true, "Use userland proxy for loopback traffic")
83
+	opts.LogOptsVar(config.LogConfig.Config, []string{"-log-opt"}, "Set log driver options")
83 84
 }
84 85
 
85 86
 func getDefaultNetworkMtu() int {
... ...
@@ -32,6 +32,9 @@ var (
32 32
 )
33 33
 
34 34
 func init() {
35
+	if daemonCfg.LogConfig.Config == nil {
36
+		daemonCfg.LogConfig.Config = make(map[string]string)
37
+	}
35 38
 	daemonCfg.InstallFlags()
36 39
 	registryCfg.InstallFlags()
37 40
 }
... ...
@@ -849,6 +849,10 @@ command is not available for this logging driver
849 849
 
850 850
 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.
851 851
 
852
+#### Log Opts : 
853
+
854
+Logging options for configuring a log driver. The following log options are supported: [none]
855
+
852 856
 ## Overriding Dockerfile image defaults
853 857
 
854 858
 When a developer builds an image from a [*Dockerfile*](/reference/builder)
... ...
@@ -28,6 +28,14 @@ func ListVar(values *[]string, names []string, usage string) {
28 28
 	flag.Var(newListOptsRef(values, nil), names, usage)
29 29
 }
30 30
 
31
+func MapVar(values map[string]string, names []string, usage string) {
32
+	flag.Var(newMapOpt(values, nil), names, usage)
33
+}
34
+
35
+func LogOptsVar(values map[string]string, names []string, usage string) {
36
+	flag.Var(newMapOpt(values, ValidateLogOpts), names, usage)
37
+}
38
+
31 39
 func HostListVar(values *[]string, names []string, usage string) {
32 40
 	flag.Var(newListOptsRef(values, ValidateHost), names, usage)
33 41
 }
... ...
@@ -130,10 +138,53 @@ func (opts *ListOpts) Len() int {
130 130
 	return len((*opts.values))
131 131
 }
132 132
 
133
+//MapOpts type
134
+type MapOpts struct {
135
+	values    map[string]string
136
+	validator ValidatorFctType
137
+}
138
+
139
+func (opts *MapOpts) Set(value string) error {
140
+	if opts.validator != nil {
141
+		v, err := opts.validator(value)
142
+		if err != nil {
143
+			return err
144
+		}
145
+		value = v
146
+	}
147
+	vals := strings.SplitN(value, "=", 2)
148
+	if len(vals) == 1 {
149
+		(opts.values)[vals[0]] = ""
150
+	} else {
151
+		(opts.values)[vals[0]] = vals[1]
152
+	}
153
+	return nil
154
+}
155
+
156
+func (opts *MapOpts) String() string {
157
+	return fmt.Sprintf("%v", map[string]string((opts.values)))
158
+}
159
+
160
+func newMapOpt(values map[string]string, validator ValidatorFctType) *MapOpts {
161
+	return &MapOpts{
162
+		values:    values,
163
+		validator: validator,
164
+	}
165
+}
166
+
133 167
 // Validators
134 168
 type ValidatorFctType func(val string) (string, error)
135 169
 type ValidatorFctListType func(val string) ([]string, error)
136 170
 
171
+func ValidateLogOpts(val string) (string, error) {
172
+	allowedKeys := map[string]string{}
173
+	vals := strings.Split(val, "=")
174
+	if allowedKeys[vals[0]] != "" {
175
+		return val, nil
176
+	}
177
+	return "", fmt.Errorf("%s is not a valid log opt", vals[0])
178
+}
179
+
137 180
 func ValidateAttach(val string) (string, error) {
138 181
 	s := strings.ToLower(val)
139 182
 	for _, str := range []string{"stdin", "stdout", "stderr"} {
... ...
@@ -1,6 +1,7 @@
1 1
 package opts
2 2
 
3 3
 import (
4
+	"fmt"
4 5
 	"strings"
5 6
 	"testing"
6 7
 )
... ...
@@ -28,6 +29,31 @@ func TestValidateIPAddress(t *testing.T) {
28 28
 
29 29
 }
30 30
 
31
+func TestMapOpts(t *testing.T) {
32
+	tmpMap := make(map[string]string)
33
+	o := newMapOpt(tmpMap, logOptsValidator)
34
+	o.Set("max-size=1")
35
+	if o.String() != "map[max-size:1]" {
36
+		t.Errorf("%s != [map[max-size:1]", o.String())
37
+	}
38
+
39
+	o.Set("max-file=2")
40
+	if len(tmpMap) != 2 {
41
+		t.Errorf("map length %d != 2", len(tmpMap))
42
+	}
43
+
44
+	if tmpMap["max-file"] != "2" {
45
+		t.Errorf("max-file = %s != 2", tmpMap["max-file"])
46
+	}
47
+
48
+	if tmpMap["max-size"] != "1" {
49
+		t.Errorf("max-size = %s != 1", tmpMap["max-size"])
50
+	}
51
+	if o.Set("dummy-val=3") == nil {
52
+		t.Errorf("validator is not being called")
53
+	}
54
+}
55
+
31 56
 func TestValidateMACAddress(t *testing.T) {
32 57
 	if _, err := ValidateMACAddress(`92:d0:c6:0a:29:33`); err != nil {
33 58
 		t.Fatalf("ValidateMACAddress(`92:d0:c6:0a:29:33`) got %s", err)
... ...
@@ -152,3 +178,12 @@ func TestValidateExtraHosts(t *testing.T) {
152 152
 		}
153 153
 	}
154 154
 }
155
+
156
+func logOptsValidator(val string) (string, error) {
157
+	allowedKeys := map[string]string{"max-size": "1", "max-file": "2"}
158
+	vals := strings.Split(val, "=")
159
+	if allowedKeys[vals[0]] != "" {
160
+		return val, nil
161
+	}
162
+	return "", fmt.Errorf("invalid key %s", vals[0])
163
+}
... ...
@@ -47,6 +47,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
47 47
 		flCapDrop     = opts.NewListOpts(nil)
48 48
 		flSecurityOpt = opts.NewListOpts(nil)
49 49
 		flLabelsFile  = opts.NewListOpts(nil)
50
+		flLoggingOpts = opts.NewListOpts(nil)
50 51
 
51 52
 		flNetwork         = cmd.Bool([]string{"#n", "#-networking"}, true, "Enable networking for this container")
52 53
 		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
95 95
 	cmd.Var(&flCapDrop, []string{"-cap-drop"}, "Drop Linux capabilities")
96 96
 	cmd.Var(&flSecurityOpt, []string{"-security-opt"}, "Security Options")
97 97
 	cmd.Var(flUlimits, []string{"-ulimit"}, "Ulimit options")
98
+	cmd.Var(&flLoggingOpts, []string{"-log-opt"}, "Log driver options")
98 99
 
99 100
 	cmd.Require(flag.Min, 1)
100 101
 
... ...
@@ -283,6 +285,11 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
283 283
 		return nil, nil, cmd, err
284 284
 	}
285 285
 
286
+	loggingOpts, err := parseLoggingOpts(*flLoggingDriver, flLoggingOpts.GetAll())
287
+	if err != nil {
288
+		return nil, nil, cmd, err
289
+	}
290
+
286 291
 	config := &Config{
287 292
 		Hostname:        hostname,
288 293
 		Domainname:      domainname,
... ...
@@ -335,7 +342,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
335 335
 		SecurityOpt:     flSecurityOpt.GetAll(),
336 336
 		ReadonlyRootfs:  *flReadonlyRootfs,
337 337
 		Ulimits:         flUlimits.GetList(),
338
-		LogConfig:       LogConfig{Type: *flLoggingDriver},
338
+		LogConfig:       LogConfig{Type: *flLoggingDriver, Config: loggingOpts},
339 339
 		CgroupParent:    *flCgroupParent,
340 340
 	}
341 341
 
... ...
@@ -377,6 +384,15 @@ func convertKVStringsToMap(values []string) map[string]string {
377 377
 	return result
378 378
 }
379 379
 
380
+func parseLoggingOpts(loggingDriver string, loggingOpts []string) (map[string]string, error) {
381
+	loggingOptsMap := convertKVStringsToMap(loggingOpts)
382
+	if loggingDriver == "none" && len(loggingOpts) > 0 {
383
+		return map[string]string{}, fmt.Errorf("Invalid logging opts for driver %s", loggingDriver)
384
+	}
385
+	//TODO - validation step
386
+	return loggingOptsMap, nil
387
+}
388
+
380 389
 // ParseRestartPolicy returns the parsed policy or an error indicating what is incorrect
381 390
 func ParseRestartPolicy(policy string) (RestartPolicy, error) {
382 391
 	p := RestartPolicy{}