From 0cec613de9084a3ba744d1fd66ec45536f2b45b7 Mon Sep 17 00:00:00 2001 From: Tibor Vass Date: Tue, 5 May 2015 00:18:28 -0400 Subject: [PATCH] cli: new daemon command and new cli package This patch creates a new cli package that allows to combine both client and daemon commands (there is only one daemon command: docker daemon). The `-d` and `--daemon` top-level flags are deprecated and a special message is added to prompt the user to use `docker daemon`. Providing top-level daemon-specific flags for client commands result in an error message prompting the user to use `docker daemon`. This patch does not break any old but correct usages. This also makes `-d` and `--daemon` flags, as well as the `daemon` command illegal in client-only binaries. Signed-off-by: Tibor Vass --- mflag/flag.go | 52 ++++++++++++++++++++++++++++++++++++++++++++- tlsconfig/config.go | 15 +++++++++---- 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/mflag/flag.go b/mflag/flag.go index 9626a2f..1c068df 100644 --- a/mflag/flag.go +++ b/mflag/flag.go @@ -526,7 +526,7 @@ func (f *FlagSet) PrintDefaults() { names = append(names, name) } } - if len(names) > 0 { + if len(names) > 0 && len(flag.Usage) > 0 { val := flag.DefValue if home != "" && strings.HasPrefix(val, home) { @@ -1143,3 +1143,53 @@ func (f *FlagSet) Init(name string, errorHandling ErrorHandling) { f.name = name f.errorHandling = errorHandling } + +type mergeVal struct { + Value + key string + fset *FlagSet +} + +func (v mergeVal) Set(s string) error { + return v.fset.Set(v.key, s) +} + +func (v mergeVal) IsBoolFlag() bool { + if b, ok := v.Value.(boolFlag); ok { + return b.IsBoolFlag() + } + return false +} + +func Merge(dest *FlagSet, flagsets ...*FlagSet) error { + for _, fset := range flagsets { + for k, f := range fset.formal { + if _, ok := dest.formal[k]; ok { + var err error + if fset.name == "" { + err = fmt.Errorf("flag redefined: %s", k) + } else { + err = fmt.Errorf("%s flag redefined: %s", fset.name, k) + } + fmt.Fprintln(fset.Out(), err.Error()) + // Happens only if flags are declared with identical names + switch dest.errorHandling { + case ContinueOnError: + return err + case ExitOnError: + os.Exit(2) + case PanicOnError: + panic(err) + } + } + newF := *f + newF.Value = mergeVal{f.Value, k, fset} + dest.formal[k] = &newF + } + } + return nil +} + +func (f *FlagSet) IsEmpty() bool { + return len(f.actual) == 0 +} diff --git a/tlsconfig/config.go b/tlsconfig/config.go index aee2132..88f768a 100644 --- a/tlsconfig/config.go +++ b/tlsconfig/config.go @@ -17,11 +17,18 @@ import ( // Options represents the information needed to create client and server TLS configurations. type Options struct { + CAFile string + + // If either CertFile or KeyFile is empty, Client() will not load them + // preventing the client from authenticating to the server. + // However, Server() requires them and will error out if they are empty. + CertFile string + KeyFile string + + // client-only option InsecureSkipVerify bool - ClientAuth tls.ClientAuthType - CAFile string - CertFile string - KeyFile string + // server-only option + ClientAuth tls.ClientAuthType } // Extra (server-side) accepted CBC cipher suites - will phase out in the future