Signed-off-by: wlan0 <sidharthamn@gmail.com>
| ... | ... |
@@ -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 {
|
| ... | ... |
@@ -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{}
|