Signed-off-by: Daniel Nephin <dnephin@docker.com>
| ... | ... |
@@ -1,11 +1,13 @@ |
| 1 | 1 |
package flags |
| 2 | 2 |
|
| 3 |
-import flag "github.com/docker/docker/pkg/mflag" |
|
| 3 |
+import ( |
|
| 4 |
+ "github.com/spf13/pflag" |
|
| 5 |
+) |
|
| 4 | 6 |
|
| 5 | 7 |
// ClientFlags represents flags for the docker client. |
| 6 | 8 |
type ClientFlags struct {
|
| 7 |
- FlagSet *flag.FlagSet |
|
| 8 |
- Common *CommonFlags |
|
| 9 |
+ FlagSet *pflag.FlagSet |
|
| 10 |
+ Common *CommonOptions |
|
| 9 | 11 |
PostParse func() |
| 10 | 12 |
|
| 11 | 13 |
ConfigDir string |
| ... | ... |
@@ -8,8 +8,8 @@ import ( |
| 8 | 8 |
"github.com/Sirupsen/logrus" |
| 9 | 9 |
"github.com/docker/docker/cliconfig" |
| 10 | 10 |
"github.com/docker/docker/opts" |
| 11 |
- flag "github.com/docker/docker/pkg/mflag" |
|
| 12 | 11 |
"github.com/docker/go-connections/tlsconfig" |
| 12 |
+ "github.com/spf13/pflag" |
|
| 13 | 13 |
) |
| 14 | 14 |
|
| 15 | 15 |
const ( |
| ... | ... |
@@ -21,8 +21,8 @@ const ( |
| 21 | 21 |
DefaultKeyFile = "key.pem" |
| 22 | 22 |
// DefaultCertFile is the default filename for the cert pem file |
| 23 | 23 |
DefaultCertFile = "cert.pem" |
| 24 |
- // TLSVerifyKey is the default flag name for the tls verification option |
|
| 25 |
- TLSVerifyKey = "tlsverify" |
|
| 24 |
+ // FlagTLSVerify is the flag name for the tls verification option |
|
| 25 |
+ FlagTLSVerify = "tlsverify" |
|
| 26 | 26 |
) |
| 27 | 27 |
|
| 28 | 28 |
var ( |
| ... | ... |
@@ -30,11 +30,8 @@ var ( |
| 30 | 30 |
dockerTLSVerify = os.Getenv("DOCKER_TLS_VERIFY") != ""
|
| 31 | 31 |
) |
| 32 | 32 |
|
| 33 |
-// CommonFlags are flags common to both the client and the daemon. |
|
| 34 |
-type CommonFlags struct {
|
|
| 35 |
- FlagSet *flag.FlagSet |
|
| 36 |
- PostParse func() |
|
| 37 |
- |
|
| 33 |
+// CommonOptions are options common to both the client and the daemon. |
|
| 34 |
+type CommonOptions struct {
|
|
| 38 | 35 |
Debug bool |
| 39 | 36 |
Hosts []string |
| 40 | 37 |
LogLevel string |
| ... | ... |
@@ -44,62 +41,60 @@ type CommonFlags struct {
|
| 44 | 44 |
TrustKey string |
| 45 | 45 |
} |
| 46 | 46 |
|
| 47 |
-// InitCommonFlags initializes flags common to both client and daemon |
|
| 48 |
-func InitCommonFlags() *CommonFlags {
|
|
| 49 |
- var commonFlags = &CommonFlags{FlagSet: new(flag.FlagSet)}
|
|
| 47 |
+// NewCommonOptions returns a new CommonOptions |
|
| 48 |
+func NewCommonOptions() *CommonOptions {
|
|
| 49 |
+ return &CommonOptions{
|
|
| 50 |
+ TLSOptions: &tlsconfig.Options{},
|
|
| 51 |
+ } |
|
| 52 |
+} |
|
| 50 | 53 |
|
| 54 |
+// InstallFlags adds flags for the common options on the FlagSet |
|
| 55 |
+func (commonOpts *CommonOptions) InstallFlags(flags *pflag.FlagSet) {
|
|
| 51 | 56 |
if dockerCertPath == "" {
|
| 52 | 57 |
dockerCertPath = cliconfig.ConfigDir() |
| 53 | 58 |
} |
| 54 | 59 |
|
| 55 |
- commonFlags.PostParse = func() { postParseCommon(commonFlags) }
|
|
| 56 |
- |
|
| 57 |
- cmd := commonFlags.FlagSet |
|
| 60 |
+ flags.BoolVarP(&commonOpts.Debug, "debug", "D", false, "Enable debug mode") |
|
| 61 |
+ flags.StringVarP(&commonOpts.LogLevel, "log-level", "l", "info", "Set the logging level") |
|
| 62 |
+ flags.BoolVar(&commonOpts.TLS, "tls", false, "Use TLS; implied by --tlsverify") |
|
| 63 |
+ flags.BoolVar(&commonOpts.TLSVerify, FlagTLSVerify, dockerTLSVerify, "Use TLS and verify the remote") |
|
| 58 | 64 |
|
| 59 |
- cmd.BoolVar(&commonFlags.Debug, []string{"D", "-debug"}, false, "Enable debug mode")
|
|
| 60 |
- cmd.StringVar(&commonFlags.LogLevel, []string{"l", "-log-level"}, "info", "Set the logging level")
|
|
| 61 |
- cmd.BoolVar(&commonFlags.TLS, []string{"-tls"}, false, "Use TLS; implied by --tlsverify")
|
|
| 62 |
- cmd.BoolVar(&commonFlags.TLSVerify, []string{"-tlsverify"}, dockerTLSVerify, "Use TLS and verify the remote")
|
|
| 65 |
+ // TODO use flag flags.String("identity"}, "i", "", "Path to libtrust key file")
|
|
| 63 | 66 |
|
| 64 |
- // TODO use flag flag.String([]string{"i", "-identity"}, "", "Path to libtrust key file")
|
|
| 67 |
+ tlsOptions := commonOpts.TLSOptions |
|
| 68 |
+ flags.StringVar(&tlsOptions.CAFile, "tlscacert", filepath.Join(dockerCertPath, DefaultCaFile), "Trust certs signed only by this CA") |
|
| 69 |
+ flags.StringVar(&tlsOptions.CertFile, "tlscert", filepath.Join(dockerCertPath, DefaultCertFile), "Path to TLS certificate file") |
|
| 70 |
+ flags.StringVar(&tlsOptions.KeyFile, "tlskey", filepath.Join(dockerCertPath, DefaultKeyFile), "Path to TLS key file") |
|
| 65 | 71 |
|
| 66 |
- var tlsOptions tlsconfig.Options |
|
| 67 |
- commonFlags.TLSOptions = &tlsOptions |
|
| 68 |
- cmd.StringVar(&tlsOptions.CAFile, []string{"-tlscacert"}, filepath.Join(dockerCertPath, DefaultCaFile), "Trust certs signed only by this CA")
|
|
| 69 |
- cmd.StringVar(&tlsOptions.CertFile, []string{"-tlscert"}, filepath.Join(dockerCertPath, DefaultCertFile), "Path to TLS certificate file")
|
|
| 70 |
- cmd.StringVar(&tlsOptions.KeyFile, []string{"-tlskey"}, filepath.Join(dockerCertPath, DefaultKeyFile), "Path to TLS key file")
|
|
| 71 |
- |
|
| 72 |
- cmd.Var(opts.NewNamedListOptsRef("hosts", &commonFlags.Hosts, opts.ValidateHost), []string{"H", "-host"}, "Daemon socket(s) to connect to")
|
|
| 73 |
- return commonFlags |
|
| 72 |
+ hostOpt := opts.NewNamedListOptsRef("hosts", &commonOpts.Hosts, opts.ValidateHost)
|
|
| 73 |
+ flags.VarP(hostOpt, "-host", "H", "Daemon socket(s) to connect to") |
|
| 74 | 74 |
} |
| 75 | 75 |
|
| 76 |
-func postParseCommon(commonFlags *CommonFlags) {
|
|
| 77 |
- cmd := commonFlags.FlagSet |
|
| 78 |
- |
|
| 79 |
- SetDaemonLogLevel(commonFlags.LogLevel) |
|
| 80 |
- |
|
| 76 |
+// SetDefaultOptions sets default values for options after flag parsing is |
|
| 77 |
+// complete |
|
| 78 |
+func (commonOpts *CommonOptions) SetDefaultOptions(flags *pflag.FlagSet) {
|
|
| 81 | 79 |
// Regardless of whether the user sets it to true or false, if they |
| 82 | 80 |
// specify --tlsverify at all then we need to turn on tls |
| 83 | 81 |
// TLSVerify can be true even if not set due to DOCKER_TLS_VERIFY env var, so we need |
| 84 | 82 |
// to check that here as well |
| 85 |
- if cmd.IsSet("-"+TLSVerifyKey) || commonFlags.TLSVerify {
|
|
| 86 |
- commonFlags.TLS = true |
|
| 83 |
+ if flags.Changed(FlagTLSVerify) || commonOpts.TLSVerify {
|
|
| 84 |
+ commonOpts.TLS = true |
|
| 87 | 85 |
} |
| 88 | 86 |
|
| 89 |
- if !commonFlags.TLS {
|
|
| 90 |
- commonFlags.TLSOptions = nil |
|
| 87 |
+ if !commonOpts.TLS {
|
|
| 88 |
+ commonOpts.TLSOptions = nil |
|
| 91 | 89 |
} else {
|
| 92 |
- tlsOptions := commonFlags.TLSOptions |
|
| 93 |
- tlsOptions.InsecureSkipVerify = !commonFlags.TLSVerify |
|
| 90 |
+ tlsOptions := commonOpts.TLSOptions |
|
| 91 |
+ tlsOptions.InsecureSkipVerify = !commonOpts.TLSVerify |
|
| 94 | 92 |
|
| 95 | 93 |
// Reset CertFile and KeyFile to empty string if the user did not specify |
| 96 | 94 |
// the respective flags and the respective default files were not found. |
| 97 |
- if !cmd.IsSet("-tlscert") {
|
|
| 95 |
+ if !flags.Changed("tlscert") {
|
|
| 98 | 96 |
if _, err := os.Stat(tlsOptions.CertFile); os.IsNotExist(err) {
|
| 99 | 97 |
tlsOptions.CertFile = "" |
| 100 | 98 |
} |
| 101 | 99 |
} |
| 102 |
- if !cmd.IsSet("-tlskey") {
|
|
| 100 |
+ if !flags.Changed("tlskey") {
|
|
| 103 | 101 |
if _, err := os.Stat(tlsOptions.KeyFile); os.IsNotExist(err) {
|
| 104 | 102 |
tlsOptions.KeyFile = "" |
| 105 | 103 |
} |
| ... | ... |
@@ -101,6 +101,7 @@ func initClientFlags(commonFlags *cliflags.CommonFlags) *cliflags.ClientFlags {
|
| 101 | 101 |
|
| 102 | 102 |
clientFlags.PostParse = func() {
|
| 103 | 103 |
clientFlags.Common.PostParse() |
| 104 |
+ cliflags.SetDaemonLogLevel(commonOpts.LogLevel) |
|
| 104 | 105 |
|
| 105 | 106 |
if clientFlags.ConfigDir != "" {
|
| 106 | 107 |
cliconfig.SetConfigDir(clientFlags.ConfigDir) |
| ... | ... |
@@ -6,7 +6,6 @@ import ( |
| 6 | 6 |
"io" |
| 7 | 7 |
"os" |
| 8 | 8 |
"path/filepath" |
| 9 |
- "runtime" |
|
| 10 | 9 |
"strings" |
| 11 | 10 |
"time" |
| 12 | 11 |
|
| ... | ... |
@@ -31,11 +30,10 @@ import ( |
| 31 | 31 |
"github.com/docker/docker/daemon/logger" |
| 32 | 32 |
"github.com/docker/docker/dockerversion" |
| 33 | 33 |
"github.com/docker/docker/libcontainerd" |
| 34 |
- "github.com/docker/docker/opts" |
|
| 34 |
+ dopts "github.com/docker/docker/opts" |
|
| 35 | 35 |
"github.com/docker/docker/pkg/authorization" |
| 36 | 36 |
"github.com/docker/docker/pkg/jsonlog" |
| 37 | 37 |
"github.com/docker/docker/pkg/listeners" |
| 38 |
- flag "github.com/docker/docker/pkg/mflag" |
|
| 39 | 38 |
"github.com/docker/docker/pkg/pidfile" |
| 40 | 39 |
"github.com/docker/docker/pkg/signal" |
| 41 | 40 |
"github.com/docker/docker/pkg/system" |
| ... | ... |
@@ -43,46 +41,27 @@ import ( |
| 43 | 43 |
"github.com/docker/docker/runconfig" |
| 44 | 44 |
"github.com/docker/docker/utils" |
| 45 | 45 |
"github.com/docker/go-connections/tlsconfig" |
| 46 |
+ "github.com/spf13/pflag" |
|
| 46 | 47 |
) |
| 47 | 48 |
|
| 48 | 49 |
const ( |
| 49 |
- daemonConfigFileFlag = "-config-file" |
|
| 50 |
+ flagDaemonConfigFile = "config-file" |
|
| 50 | 51 |
) |
| 51 | 52 |
|
| 52 | 53 |
// DaemonCli represents the daemon CLI. |
| 53 | 54 |
type DaemonCli struct {
|
| 54 | 55 |
*daemon.Config |
| 55 |
- commonFlags *cliflags.CommonFlags |
|
| 56 |
- configFile *string |
|
| 56 |
+ configFile *string |
|
| 57 |
+ flags *pflag.FlagSet |
|
| 57 | 58 |
|
| 58 | 59 |
api *apiserver.Server |
| 59 | 60 |
d *daemon.Daemon |
| 60 | 61 |
authzMiddleware *authorization.Middleware // authzMiddleware enables to dynamically reload the authorization plugins |
| 61 | 62 |
} |
| 62 | 63 |
|
| 63 |
-func presentInHelp(usage string) string { return usage }
|
|
| 64 |
-func absentFromHelp(string) string { return "" }
|
|
| 65 |
- |
|
| 66 |
-// NewDaemonCli returns a pre-configured daemon CLI |
|
| 64 |
+// NewDaemonCli returns a daemon CLI |
|
| 67 | 65 |
func NewDaemonCli() *DaemonCli {
|
| 68 |
- // TODO(tiborvass): remove InstallFlags? |
|
| 69 |
- daemonConfig := new(daemon.Config) |
|
| 70 |
- daemonConfig.LogConfig.Config = make(map[string]string) |
|
| 71 |
- daemonConfig.ClusterOpts = make(map[string]string) |
|
| 72 |
- |
|
| 73 |
- daemonConfig.InstallFlags(flag.CommandLine, presentInHelp) |
|
| 74 |
- configFile := flag.CommandLine.String([]string{daemonConfigFileFlag}, defaultDaemonConfigFile, "Daemon configuration file")
|
|
| 75 |
- flag.CommandLine.Require(flag.Exact, 0) |
|
| 76 |
- |
|
| 77 |
- if runtime.GOOS != "linux" {
|
|
| 78 |
- daemonConfig.V2Only = true |
|
| 79 |
- } |
|
| 80 |
- |
|
| 81 |
- return &DaemonCli{
|
|
| 82 |
- Config: daemonConfig, |
|
| 83 |
- commonFlags: cliflags.InitCommonFlags(), |
|
| 84 |
- configFile: configFile, |
|
| 85 |
- } |
|
| 66 |
+ return &DaemonCli{}
|
|
| 86 | 67 |
} |
| 87 | 68 |
|
| 88 | 69 |
func migrateKey() (err error) {
|
| ... | ... |
@@ -126,24 +105,25 @@ func migrateKey() (err error) {
|
| 126 | 126 |
return nil |
| 127 | 127 |
} |
| 128 | 128 |
|
| 129 |
-func (cli *DaemonCli) start() (err error) {
|
|
| 129 |
+func (cli *DaemonCli) start(opts daemonOptions) (err error) {
|
|
| 130 | 130 |
stopc := make(chan bool) |
| 131 | 131 |
defer close(stopc) |
| 132 | 132 |
|
| 133 | 133 |
// warn from uuid package when running the daemon |
| 134 | 134 |
uuid.Loggerf = logrus.Warnf |
| 135 | 135 |
|
| 136 |
- flags := flag.CommandLine |
|
| 137 |
- cli.commonFlags.PostParse() |
|
| 136 |
+ opts.common.SetDefaultOptions(opts.flags) |
|
| 138 | 137 |
|
| 139 |
- if cli.commonFlags.TrustKey == "" {
|
|
| 140 |
- cli.commonFlags.TrustKey = filepath.Join(getDaemonConfDir(), cliflags.DefaultTrustKeyFile) |
|
| 138 |
+ if opts.common.TrustKey == "" {
|
|
| 139 |
+ opts.common.TrustKey = filepath.Join( |
|
| 140 |
+ getDaemonConfDir(), |
|
| 141 |
+ cliflags.DefaultTrustKeyFile) |
|
| 141 | 142 |
} |
| 142 |
- cliConfig, err := loadDaemonCliConfig(cli.Config, flags, cli.commonFlags, *cli.configFile) |
|
| 143 |
- if err != nil {
|
|
| 143 |
+ if cli.Config, err = loadDaemonCliConfig(opts); err != nil {
|
|
| 144 | 144 |
return err |
| 145 | 145 |
} |
| 146 |
- cli.Config = cliConfig |
|
| 146 |
+ cli.configFile = &opts.configFile |
|
| 147 |
+ cli.flags = opts.flags |
|
| 147 | 148 |
|
| 148 | 149 |
if cli.Config.Debug {
|
| 149 | 150 |
utils.EnableDebug() |
| ... | ... |
@@ -215,7 +195,7 @@ func (cli *DaemonCli) start() (err error) {
|
| 215 | 215 |
|
| 216 | 216 |
for i := 0; i < len(cli.Config.Hosts); i++ {
|
| 217 | 217 |
var err error |
| 218 |
- if cli.Config.Hosts[i], err = opts.ParseHost(cli.Config.TLS, cli.Config.Hosts[i]); err != nil {
|
|
| 218 |
+ if cli.Config.Hosts[i], err = dopts.ParseHost(cli.Config.TLS, cli.Config.Hosts[i]); err != nil {
|
|
| 219 | 219 |
return fmt.Errorf("error parsing -H %s : %v", cli.Config.Hosts[i], err)
|
| 220 | 220 |
} |
| 221 | 221 |
|
| ... | ... |
@@ -250,7 +230,8 @@ func (cli *DaemonCli) start() (err error) {
|
| 250 | 250 |
if err := migrateKey(); err != nil {
|
| 251 | 251 |
return err |
| 252 | 252 |
} |
| 253 |
- cli.TrustKeyPath = cli.commonFlags.TrustKey |
|
| 253 |
+ // FIXME: why is this down here instead of with the other TrustKey logic above? |
|
| 254 |
+ cli.TrustKeyPath = opts.common.TrustKey |
|
| 254 | 255 |
|
| 255 | 256 |
registryService := registry.NewService(cli.Config.ServiceOptions) |
| 256 | 257 |
containerdRemote, err := libcontainerd.New(cli.getLibcontainerdRoot(), cli.getPlatformRemoteOptions()...) |
| ... | ... |
@@ -341,7 +322,7 @@ func (cli *DaemonCli) reloadConfig() {
|
| 341 | 341 |
} |
| 342 | 342 |
} |
| 343 | 343 |
|
| 344 |
- if err := daemon.ReloadConfiguration(*cli.configFile, flag.CommandLine, reload); err != nil {
|
|
| 344 |
+ if err := daemon.ReloadConfiguration(*cli.configFile, cli.flags, reload); err != nil {
|
|
| 345 | 345 |
logrus.Error(err) |
| 346 | 346 |
} |
| 347 | 347 |
} |
| ... | ... |
@@ -367,25 +348,27 @@ func shutdownDaemon(d *daemon.Daemon, timeout time.Duration) {
|
| 367 | 367 |
} |
| 368 | 368 |
} |
| 369 | 369 |
|
| 370 |
-func loadDaemonCliConfig(config *daemon.Config, flags *flag.FlagSet, commonConfig *cliflags.CommonFlags, configFile string) (*daemon.Config, error) {
|
|
| 371 |
- config.Debug = commonConfig.Debug |
|
| 372 |
- config.Hosts = commonConfig.Hosts |
|
| 373 |
- config.LogLevel = commonConfig.LogLevel |
|
| 374 |
- config.TLS = commonConfig.TLS |
|
| 375 |
- config.TLSVerify = commonConfig.TLSVerify |
|
| 370 |
+func loadDaemonCliConfig(opts daemonOptions) (*daemon.Config, error) {
|
|
| 371 |
+ config := opts.daemonConfig |
|
| 372 |
+ flags := opts.flags |
|
| 373 |
+ config.Debug = opts.common.Debug |
|
| 374 |
+ config.Hosts = opts.common.Hosts |
|
| 375 |
+ config.LogLevel = opts.common.LogLevel |
|
| 376 |
+ config.TLS = opts.common.TLS |
|
| 377 |
+ config.TLSVerify = opts.common.TLSVerify |
|
| 376 | 378 |
config.CommonTLSOptions = daemon.CommonTLSOptions{}
|
| 377 | 379 |
|
| 378 |
- if commonConfig.TLSOptions != nil {
|
|
| 379 |
- config.CommonTLSOptions.CAFile = commonConfig.TLSOptions.CAFile |
|
| 380 |
- config.CommonTLSOptions.CertFile = commonConfig.TLSOptions.CertFile |
|
| 381 |
- config.CommonTLSOptions.KeyFile = commonConfig.TLSOptions.KeyFile |
|
| 380 |
+ if opts.common.TLSOptions != nil {
|
|
| 381 |
+ config.CommonTLSOptions.CAFile = opts.common.TLSOptions.CAFile |
|
| 382 |
+ config.CommonTLSOptions.CertFile = opts.common.TLSOptions.CertFile |
|
| 383 |
+ config.CommonTLSOptions.KeyFile = opts.common.TLSOptions.KeyFile |
|
| 382 | 384 |
} |
| 383 | 385 |
|
| 384 |
- if configFile != "" {
|
|
| 385 |
- c, err := daemon.MergeDaemonConfigurations(config, flags, configFile) |
|
| 386 |
+ if opts.configFile != "" {
|
|
| 387 |
+ c, err := daemon.MergeDaemonConfigurations(config, flags, opts.configFile) |
|
| 386 | 388 |
if err != nil {
|
| 387 |
- if flags.IsSet(daemonConfigFileFlag) || !os.IsNotExist(err) {
|
|
| 388 |
- return nil, fmt.Errorf("unable to configure the Docker daemon with file %s: %v\n", configFile, err)
|
|
| 389 |
+ if flags.Changed(flagDaemonConfigFile) || !os.IsNotExist(err) {
|
|
| 390 |
+ return nil, fmt.Errorf("unable to configure the Docker daemon with file %s: %v\n", opts.configFile, err)
|
|
| 389 | 391 |
} |
| 390 | 392 |
} |
| 391 | 393 |
// the merged configuration can be nil if the config file didn't exist. |
| ... | ... |
@@ -401,7 +384,7 @@ func loadDaemonCliConfig(config *daemon.Config, flags *flag.FlagSet, commonConfi |
| 401 | 401 |
|
| 402 | 402 |
// Regardless of whether the user sets it to true or false, if they |
| 403 | 403 |
// specify TLSVerify at all then we need to turn on TLS |
| 404 |
- if config.IsValueSet(cliflags.TLSVerifyKey) {
|
|
| 404 |
+ if config.IsValueSet(cliflags.FlagTLSVerify) {
|
|
| 405 | 405 |
config.TLS = true |
| 406 | 406 |
} |
| 407 | 407 |
|
| ... | ... |
@@ -2,59 +2,61 @@ package main |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"fmt" |
| 5 |
- "os" |
|
| 6 | 5 |
|
| 7 | 6 |
"github.com/Sirupsen/logrus" |
| 7 |
+ "github.com/docker/docker/cli" |
|
| 8 |
+ cliflags "github.com/docker/docker/cli/flags" |
|
| 9 |
+ "github.com/docker/docker/daemon" |
|
| 8 | 10 |
"github.com/docker/docker/dockerversion" |
| 9 |
- flag "github.com/docker/docker/pkg/mflag" |
|
| 10 | 11 |
"github.com/docker/docker/pkg/reexec" |
| 11 | 12 |
"github.com/docker/docker/pkg/term" |
| 12 | 13 |
"github.com/docker/docker/utils" |
| 14 |
+ "github.com/spf13/cobra" |
|
| 15 |
+ "github.com/spf13/pflag" |
|
| 13 | 16 |
) |
| 14 | 17 |
|
| 15 |
-var ( |
|
| 16 |
- daemonCli = NewDaemonCli() |
|
| 17 |
- flHelp = flag.Bool([]string{"h", "-help"}, false, "Print usage")
|
|
| 18 |
- flVersion = flag.Bool([]string{"v", "-version"}, false, "Print version information and quit")
|
|
| 19 |
-) |
|
| 18 |
+type daemonOptions struct {
|
|
| 19 |
+ version bool |
|
| 20 |
+ configFile string |
|
| 21 |
+ daemonConfig *daemon.Config |
|
| 22 |
+ common *cliflags.CommonOptions |
|
| 23 |
+ flags *pflag.FlagSet |
|
| 24 |
+} |
|
| 20 | 25 |
|
| 21 |
-func main() {
|
|
| 22 |
- if reexec.Init() {
|
|
| 23 |
- return |
|
| 26 |
+func newDaemonCommand() *cobra.Command {
|
|
| 27 |
+ opts := daemonOptions{
|
|
| 28 |
+ daemonConfig: daemon.NewConfig(), |
|
| 29 |
+ common: cliflags.NewCommonOptions(), |
|
| 24 | 30 |
} |
| 25 | 31 |
|
| 26 |
- // Set terminal emulation based on platform as required. |
|
| 27 |
- _, stdout, stderr := term.StdStreams() |
|
| 28 |
- |
|
| 29 |
- logrus.SetOutput(stderr) |
|
| 30 |
- |
|
| 31 |
- flag.Merge(flag.CommandLine, daemonCli.commonFlags.FlagSet) |
|
| 32 |
- |
|
| 33 |
- flag.Usage = func() {
|
|
| 34 |
- fmt.Fprint(stdout, "Usage: dockerd [OPTIONS]\n\n") |
|
| 35 |
- fmt.Fprint(stdout, "A self-sufficient runtime for containers.\n\nOptions:\n") |
|
| 36 |
- |
|
| 37 |
- flag.CommandLine.SetOutput(stdout) |
|
| 38 |
- flag.PrintDefaults() |
|
| 39 |
- } |
|
| 40 |
- flag.CommandLine.ShortUsage = func() {
|
|
| 41 |
- fmt.Fprint(stderr, "\nUsage:\tdockerd [OPTIONS]\n") |
|
| 32 |
+ cmd := &cobra.Command{
|
|
| 33 |
+ Use: "dockerd [OPTIONS]", |
|
| 34 |
+ Short: "A self-sufficient runtime for containers.", |
|
| 35 |
+ SilenceUsage: true, |
|
| 36 |
+ SilenceErrors: true, |
|
| 37 |
+ Args: cli.NoArgs, |
|
| 38 |
+ RunE: func(cmd *cobra.Command, args []string) error {
|
|
| 39 |
+ opts.flags = cmd.Flags() |
|
| 40 |
+ return runDaemon(opts) |
|
| 41 |
+ }, |
|
| 42 | 42 |
} |
| 43 |
+ // TODO: SetUsageTemplate, SetHelpTemplate, SetFlagErrorFunc |
|
| 43 | 44 |
|
| 44 |
- if err := flag.CommandLine.ParseFlags(os.Args[1:], false); err != nil {
|
|
| 45 |
- os.Exit(1) |
|
| 46 |
- } |
|
| 45 |
+ flags := cmd.Flags() |
|
| 46 |
+ flags.BoolP("help", "h", false, "Print usage")
|
|
| 47 |
+ flags.MarkShorthandDeprecated("help", "please use --help")
|
|
| 48 |
+ flags.BoolVarP(&opts.version, "version", "v", false, "Print version information and quit") |
|
| 49 |
+ flags.StringVar(&opts.configFile, flagDaemonConfigFile, defaultDaemonConfigFile, "Daemon configuration file") |
|
| 50 |
+ opts.common.InstallFlags(flags) |
|
| 51 |
+ opts.daemonConfig.InstallFlags(flags) |
|
| 47 | 52 |
|
| 48 |
- if *flVersion {
|
|
| 49 |
- showVersion() |
|
| 50 |
- return |
|
| 51 |
- } |
|
| 53 |
+ return cmd |
|
| 54 |
+} |
|
| 52 | 55 |
|
| 53 |
- if *flHelp {
|
|
| 54 |
- // if global flag --help is present, regardless of what other options and commands there are, |
|
| 55 |
- // just print the usage. |
|
| 56 |
- flag.Usage() |
|
| 57 |
- return |
|
| 56 |
+func runDaemon(opts daemonOptions) error {
|
|
| 57 |
+ if opts.version {
|
|
| 58 |
+ showVersion() |
|
| 59 |
+ return nil |
|
| 58 | 60 |
} |
| 59 | 61 |
|
| 60 | 62 |
// On Windows, this may be launching as a service or with an option to |
| ... | ... |
@@ -64,13 +66,13 @@ func main() {
|
| 64 | 64 |
logrus.Fatal(err) |
| 65 | 65 |
} |
| 66 | 66 |
|
| 67 |
- if !stop {
|
|
| 68 |
- err = daemonCli.start() |
|
| 69 |
- notifyShutdown(err) |
|
| 70 |
- if err != nil {
|
|
| 71 |
- logrus.Fatal(err) |
|
| 72 |
- } |
|
| 67 |
+ if stop {
|
|
| 68 |
+ return nil |
|
| 73 | 69 |
} |
| 70 |
+ |
|
| 71 |
+ err = NewDaemonCli().start(opts) |
|
| 72 |
+ notifyShutdown(err) |
|
| 73 |
+ return err |
|
| 74 | 74 |
} |
| 75 | 75 |
|
| 76 | 76 |
func showVersion() {
|
| ... | ... |
@@ -80,3 +82,19 @@ func showVersion() {
|
| 80 | 80 |
fmt.Printf("Docker version %s, build %s\n", dockerversion.Version, dockerversion.GitCommit)
|
| 81 | 81 |
} |
| 82 | 82 |
} |
| 83 |
+ |
|
| 84 |
+func main() {
|
|
| 85 |
+ if reexec.Init() {
|
|
| 86 |
+ return |
|
| 87 |
+ } |
|
| 88 |
+ |
|
| 89 |
+ // Set terminal emulation based on platform as required. |
|
| 90 |
+ _, stdout, stderr := term.StdStreams() |
|
| 91 |
+ logrus.SetOutput(stderr) |
|
| 92 |
+ |
|
| 93 |
+ cmd := newDaemonCommand() |
|
| 94 |
+ cmd.SetOutput(stdout) |
|
| 95 |
+ if err := cmd.Execute(); err != nil {
|
|
| 96 |
+ logrus.Fatal(err) |
|
| 97 |
+ } |
|
| 98 |
+} |
| ... | ... |
@@ -6,15 +6,16 @@ import ( |
| 6 | 6 |
"fmt" |
| 7 | 7 |
"io" |
| 8 | 8 |
"io/ioutil" |
| 9 |
+ "runtime" |
|
| 9 | 10 |
"strings" |
| 10 | 11 |
"sync" |
| 11 | 12 |
|
| 12 | 13 |
"github.com/Sirupsen/logrus" |
| 13 | 14 |
"github.com/docker/docker/opts" |
| 14 | 15 |
"github.com/docker/docker/pkg/discovery" |
| 15 |
- flag "github.com/docker/docker/pkg/mflag" |
|
| 16 | 16 |
"github.com/docker/docker/registry" |
| 17 | 17 |
"github.com/imdario/mergo" |
| 18 |
+ "github.com/spf13/pflag" |
|
| 18 | 19 |
) |
| 19 | 20 |
|
| 20 | 21 |
const ( |
| ... | ... |
@@ -145,37 +146,35 @@ type CommonConfig struct {
|
| 145 | 145 |
valuesSet map[string]interface{}
|
| 146 | 146 |
} |
| 147 | 147 |
|
| 148 |
-// InstallCommonFlags adds command-line options to the top-level flag parser for |
|
| 149 |
-// the current process. |
|
| 150 |
-// Subsequent calls to `flag.Parse` will populate config with values parsed |
|
| 151 |
-// from the command-line. |
|
| 152 |
-func (config *Config) InstallCommonFlags(cmd *flag.FlagSet, usageFn func(string) string) {
|
|
| 148 |
+// InstallCommonFlags adds flags to the pflag.FlagSet to configure the daemon |
|
| 149 |
+func (config *Config) InstallCommonFlags(flags *pflag.FlagSet) {
|
|
| 153 | 150 |
var maxConcurrentDownloads, maxConcurrentUploads int |
| 154 | 151 |
|
| 155 |
- config.ServiceOptions.InstallCliFlags(cmd, usageFn) |
|
| 156 |
- |
|
| 157 |
- cmd.Var(opts.NewNamedListOptsRef("storage-opts", &config.GraphOptions, nil), []string{"-storage-opt"}, usageFn("Storage driver options"))
|
|
| 158 |
- cmd.Var(opts.NewNamedListOptsRef("authorization-plugins", &config.AuthorizationPlugins, nil), []string{"-authorization-plugin"}, usageFn("Authorization plugins to load"))
|
|
| 159 |
- cmd.Var(opts.NewNamedListOptsRef("exec-opts", &config.ExecOptions, nil), []string{"-exec-opt"}, usageFn("Runtime execution options"))
|
|
| 160 |
- cmd.StringVar(&config.Pidfile, []string{"p", "-pidfile"}, defaultPidFile, usageFn("Path to use for daemon PID file"))
|
|
| 161 |
- cmd.StringVar(&config.Root, []string{"g", "-graph"}, defaultGraph, usageFn("Root of the Docker runtime"))
|
|
| 162 |
- cmd.BoolVar(&config.AutoRestart, []string{"#r", "#-restart"}, true, usageFn("--restart on the daemon has been deprecated in favor of --restart policies on docker run"))
|
|
| 163 |
- cmd.StringVar(&config.GraphDriver, []string{"s", "-storage-driver"}, "", usageFn("Storage driver to use"))
|
|
| 164 |
- cmd.IntVar(&config.Mtu, []string{"#mtu", "-mtu"}, 0, usageFn("Set the containers network MTU"))
|
|
| 165 |
- cmd.BoolVar(&config.RawLogs, []string{"-raw-logs"}, false, usageFn("Full timestamps without ANSI coloring"))
|
|
| 152 |
+ config.ServiceOptions.InstallCliFlags(flags) |
|
| 153 |
+ |
|
| 154 |
+ flags.Var(opts.NewNamedListOptsRef("storage-opts", &config.GraphOptions, nil), "storage-opt", "Storage driver options")
|
|
| 155 |
+ flags.Var(opts.NewNamedListOptsRef("authorization-plugins", &config.AuthorizationPlugins, nil), "authorization-plugin", "Authorization plugins to load")
|
|
| 156 |
+ flags.Var(opts.NewNamedListOptsRef("exec-opts", &config.ExecOptions, nil), "exec-opt", "Runtime execution options")
|
|
| 157 |
+ flags.StringVarP(&config.Pidfile, "pidfile", "p", defaultPidFile, "Path to use for daemon PID file") |
|
| 158 |
+ flags.StringVarP(&config.Root, "graph", "g", defaultGraph, "Root of the Docker runtime") |
|
| 159 |
+ flags.BoolVarP(&config.AutoRestart, "restart", "r", true, "--restart on the daemon has been deprecated in favor of --restart policies on docker run") |
|
| 160 |
+ flags.MarkDeprecated("restart", "Please use a restart policy on ducker run")
|
|
| 161 |
+ flags.StringVarP(&config.GraphDriver, "storage-driver", "s", "", "Storage driver to use") |
|
| 162 |
+ flags.IntVar(&config.Mtu, "mtu", 0, "Set the containers network MTU") |
|
| 163 |
+ flags.BoolVar(&config.RawLogs, "raw-logs", false, "Full timestamps without ANSI coloring") |
|
| 166 | 164 |
// FIXME: why the inconsistency between "hosts" and "sockets"? |
| 167 |
- cmd.Var(opts.NewListOptsRef(&config.DNS, opts.ValidateIPAddress), []string{"#dns", "-dns"}, usageFn("DNS server to use"))
|
|
| 168 |
- cmd.Var(opts.NewNamedListOptsRef("dns-opts", &config.DNSOptions, nil), []string{"-dns-opt"}, usageFn("DNS options to use"))
|
|
| 169 |
- cmd.Var(opts.NewListOptsRef(&config.DNSSearch, opts.ValidateDNSSearch), []string{"-dns-search"}, usageFn("DNS search domains to use"))
|
|
| 170 |
- cmd.Var(opts.NewNamedListOptsRef("labels", &config.Labels, opts.ValidateLabel), []string{"-label"}, usageFn("Set key=value labels to the daemon"))
|
|
| 171 |
- cmd.StringVar(&config.LogConfig.Type, []string{"-log-driver"}, "json-file", usageFn("Default driver for container logs"))
|
|
| 172 |
- cmd.Var(opts.NewNamedMapOpts("log-opts", config.LogConfig.Config, nil), []string{"-log-opt"}, usageFn("Default log driver options for containers"))
|
|
| 173 |
- cmd.StringVar(&config.ClusterAdvertise, []string{"-cluster-advertise"}, "", usageFn("Address or interface name to advertise"))
|
|
| 174 |
- cmd.StringVar(&config.ClusterStore, []string{"-cluster-store"}, "", usageFn("URL of the distributed storage backend"))
|
|
| 175 |
- cmd.Var(opts.NewNamedMapOpts("cluster-store-opts", config.ClusterOpts, nil), []string{"-cluster-store-opt"}, usageFn("Set cluster store options"))
|
|
| 176 |
- cmd.StringVar(&config.CorsHeaders, []string{"-api-cors-header"}, "", usageFn("Set CORS headers in the remote API"))
|
|
| 177 |
- cmd.IntVar(&maxConcurrentDownloads, []string{"-max-concurrent-downloads"}, defaultMaxConcurrentDownloads, usageFn("Set the max concurrent downloads for each pull"))
|
|
| 178 |
- cmd.IntVar(&maxConcurrentUploads, []string{"-max-concurrent-uploads"}, defaultMaxConcurrentUploads, usageFn("Set the max concurrent uploads for each push"))
|
|
| 165 |
+ flags.Var(opts.NewListOptsRef(&config.DNS, opts.ValidateIPAddress), "dns", "DNS server to use") |
|
| 166 |
+ flags.Var(opts.NewNamedListOptsRef("dns-opts", &config.DNSOptions, nil), "dns-opt", "DNS options to use")
|
|
| 167 |
+ flags.Var(opts.NewListOptsRef(&config.DNSSearch, opts.ValidateDNSSearch), "dns-search", "DNS search domains to use") |
|
| 168 |
+ flags.Var(opts.NewNamedListOptsRef("labels", &config.Labels, opts.ValidateLabel), "label", "Set key=value labels to the daemon")
|
|
| 169 |
+ flags.StringVar(&config.LogConfig.Type, "log-driver", "json-file", "Default driver for container logs") |
|
| 170 |
+ flags.Var(opts.NewNamedMapOpts("log-opts", config.LogConfig.Config, nil), "log-opt", "Default log driver options for containers")
|
|
| 171 |
+ flags.StringVar(&config.ClusterAdvertise, "cluster-advertise", "", "Address or interface name to advertise") |
|
| 172 |
+ flags.StringVar(&config.ClusterStore, "cluster-store", "", "URL of the distributed storage backend") |
|
| 173 |
+ flags.Var(opts.NewNamedMapOpts("cluster-store-opts", config.ClusterOpts, nil), "cluster-store-opt", "Set cluster store options")
|
|
| 174 |
+ flags.StringVar(&config.CorsHeaders, "api-cors-header", "", "Set CORS headers in the remote API") |
|
| 175 |
+ flags.IntVar(&maxConcurrentDownloads, "max-concurrent-downloads", defaultMaxConcurrentDownloads, "Set the max concurrent downloads for each pull") |
|
| 176 |
+ flags.IntVar(&maxConcurrentUploads, "max-concurrent-uploads", defaultMaxConcurrentUploads, "Set the max concurrent uploads for each push") |
|
| 179 | 177 |
|
| 180 | 178 |
cmd.StringVar(&config.SwarmDefaultAdvertiseAddr, []string{"-swarm-default-advertise-addr"}, "", usageFn("Set default address or interface for swarm advertised address"))
|
| 181 | 179 |
|
| ... | ... |
@@ -193,6 +192,18 @@ func (config *Config) IsValueSet(name string) bool {
|
| 193 | 193 |
return ok |
| 194 | 194 |
} |
| 195 | 195 |
|
| 196 |
+// NewConfig returns a new fully initialized Config struct |
|
| 197 |
+func NewConfig() *Config {
|
|
| 198 |
+ config := Config{}
|
|
| 199 |
+ config.LogConfig.Config = make(map[string]string) |
|
| 200 |
+ config.ClusterOpts = make(map[string]string) |
|
| 201 |
+ |
|
| 202 |
+ if runtime.GOOS != "linux" {
|
|
| 203 |
+ config.V2Only = true |
|
| 204 |
+ } |
|
| 205 |
+ return &config |
|
| 206 |
+} |
|
| 207 |
+ |
|
| 196 | 208 |
func parseClusterAdvertiseSettings(clusterStore, clusterAdvertise string) (string, error) {
|
| 197 | 209 |
if clusterAdvertise == "" {
|
| 198 | 210 |
return "", errDiscoveryDisabled |
| ... | ... |
@@ -209,7 +220,7 @@ func parseClusterAdvertiseSettings(clusterStore, clusterAdvertise string) (strin |
| 209 | 209 |
} |
| 210 | 210 |
|
| 211 | 211 |
// ReloadConfiguration reads the configuration in the host and reloads the daemon and server. |
| 212 |
-func ReloadConfiguration(configFile string, flags *flag.FlagSet, reload func(*Config)) error {
|
|
| 212 |
+func ReloadConfiguration(configFile string, flags *pflag.FlagSet, reload func(*Config)) error {
|
|
| 213 | 213 |
logrus.Infof("Got signal to reload configuration, reloading from: %s", configFile)
|
| 214 | 214 |
newConfig, err := getConflictFreeConfiguration(configFile, flags) |
| 215 | 215 |
if err != nil {
|
| ... | ... |
@@ -234,7 +245,7 @@ type boolValue interface {
|
| 234 | 234 |
// loads the file configuration in an isolated structure, |
| 235 | 235 |
// and merges the configuration provided from flags on top |
| 236 | 236 |
// if there are no conflicts. |
| 237 |
-func MergeDaemonConfigurations(flagsConfig *Config, flags *flag.FlagSet, configFile string) (*Config, error) {
|
|
| 237 |
+func MergeDaemonConfigurations(flagsConfig *Config, flags *pflag.FlagSet, configFile string) (*Config, error) {
|
|
| 238 | 238 |
fileConfig, err := getConflictFreeConfiguration(configFile, flags) |
| 239 | 239 |
if err != nil {
|
| 240 | 240 |
return nil, err |
| ... | ... |
@@ -261,7 +272,7 @@ func MergeDaemonConfigurations(flagsConfig *Config, flags *flag.FlagSet, configF |
| 261 | 261 |
// getConflictFreeConfiguration loads the configuration from a JSON file. |
| 262 | 262 |
// It compares that configuration with the one provided by the flags, |
| 263 | 263 |
// and returns an error if there are conflicts. |
| 264 |
-func getConflictFreeConfiguration(configFile string, flags *flag.FlagSet) (*Config, error) {
|
|
| 264 |
+func getConflictFreeConfiguration(configFile string, flags *pflag.FlagSet) (*Config, error) {
|
|
| 265 | 265 |
b, err := ioutil.ReadFile(configFile) |
| 266 | 266 |
if err != nil {
|
| 267 | 267 |
return nil, err |
| ... | ... |
@@ -301,7 +312,7 @@ func getConflictFreeConfiguration(configFile string, flags *flag.FlagSet) (*Conf |
| 301 | 301 |
} |
| 302 | 302 |
if len(namedOptions) > 0 {
|
| 303 | 303 |
// set also default for mergeVal flags that are boolValue at the same time. |
| 304 |
- flags.VisitAll(func(f *flag.Flag) {
|
|
| 304 |
+ flags.VisitAll(func(f *pflag.Flag) {
|
|
| 305 | 305 |
if opt, named := f.Value.(opts.NamedOption); named {
|
| 306 | 306 |
v, set := namedOptions[opt.Name()] |
| 307 | 307 |
_, boolean := f.Value.(boolValue) |
| ... | ... |
@@ -339,7 +350,7 @@ func configValuesSet(config map[string]interface{}) map[string]interface{} {
|
| 339 | 339 |
// findConfigurationConflicts iterates over the provided flags searching for |
| 340 | 340 |
// duplicated configurations and unknown keys. It returns an error with all the conflicts if |
| 341 | 341 |
// it finds any. |
| 342 |
-func findConfigurationConflicts(config map[string]interface{}, flags *flag.FlagSet) error {
|
|
| 342 |
+func findConfigurationConflicts(config map[string]interface{}, flags *pflag.FlagSet) error {
|
|
| 343 | 343 |
// 1. Search keys from the file that we don't recognize as flags. |
| 344 | 344 |
unknownKeys := make(map[string]interface{})
|
| 345 | 345 |
for key, value := range config {
|
| ... | ... |
@@ -352,7 +363,7 @@ func findConfigurationConflicts(config map[string]interface{}, flags *flag.FlagS
|
| 352 | 352 |
// 2. Discard values that implement NamedOption. |
| 353 | 353 |
// Their configuration name differs from their flag name, like `labels` and `label`. |
| 354 | 354 |
if len(unknownKeys) > 0 {
|
| 355 |
- unknownNamedConflicts := func(f *flag.Flag) {
|
|
| 355 |
+ unknownNamedConflicts := func(f *pflag.Flag) {
|
|
| 356 | 356 |
if namedOption, ok := f.Value.(opts.NamedOption); ok {
|
| 357 | 357 |
if _, valid := unknownKeys[namedOption.Name()]; valid {
|
| 358 | 358 |
delete(unknownKeys, namedOption.Name()) |
| ... | ... |
@@ -376,15 +387,15 @@ func findConfigurationConflicts(config map[string]interface{}, flags *flag.FlagS
|
| 376 | 376 |
} |
| 377 | 377 |
|
| 378 | 378 |
// 3. Search keys that are present as a flag and as a file option. |
| 379 |
- duplicatedConflicts := func(f *flag.Flag) {
|
|
| 379 |
+ duplicatedConflicts := func(f *pflag.Flag) {
|
|
| 380 | 380 |
// search option name in the json configuration payload if the value is a named option |
| 381 | 381 |
if namedOption, ok := f.Value.(opts.NamedOption); ok {
|
| 382 | 382 |
if optsValue, ok := config[namedOption.Name()]; ok {
|
| 383 | 383 |
conflicts = append(conflicts, printConflict(namedOption.Name(), f.Value.String(), optsValue)) |
| 384 | 384 |
} |
| 385 | 385 |
} else {
|
| 386 |
- // search flag name in the json configuration payload without trailing dashes |
|
| 387 |
- for _, name := range f.Names {
|
|
| 386 |
+ // search flag name in the json configuration payload |
|
| 387 |
+ for _, name := range []string{f.Name, f.Shorthand} {
|
|
| 388 | 388 |
name = strings.TrimLeft(name, "-") |
| 389 | 389 |
|
| 390 | 390 |
if value, ok := config[name]; ok {
|
| ... | ... |
@@ -2,7 +2,9 @@ |
| 2 | 2 |
|
| 3 | 3 |
package daemon |
| 4 | 4 |
|
| 5 |
-import flag "github.com/docker/docker/pkg/mflag" |
|
| 5 |
+import ( |
|
| 6 |
+ "github.com/spf13/pflag" |
|
| 7 |
+) |
|
| 6 | 8 |
|
| 7 |
-func (config *Config) attachExperimentalFlags(cmd *flag.FlagSet, usageFn func(string) string) {
|
|
| 9 |
+func (config *Config) attachExperimentalFlags(cmd *pflag.FlagSet) {
|
|
| 8 | 10 |
} |
| ... | ... |
@@ -1,7 +1,7 @@ |
| 1 | 1 |
package daemon |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- flag "github.com/docker/docker/pkg/mflag" |
|
| 4 |
+ "github.com/spf13/pflag" |
|
| 5 | 5 |
) |
| 6 | 6 |
|
| 7 | 7 |
var ( |
| ... | ... |
@@ -28,14 +28,12 @@ type bridgeConfig struct {
|
| 28 | 28 |
|
| 29 | 29 |
// InstallFlags adds command-line options to the top-level flag parser for |
| 30 | 30 |
// the current process. |
| 31 |
-// Subsequent calls to `flag.Parse` will populate config with values parsed |
|
| 32 |
-// from the command-line. |
|
| 33 |
-func (config *Config) InstallFlags(cmd *flag.FlagSet, usageFn func(string) string) {
|
|
| 31 |
+func (config *Config) InstallFlags(flags *pflag.FlagSet) {
|
|
| 34 | 32 |
// First handle install flags which are consistent cross-platform |
| 35 |
- config.InstallCommonFlags(cmd, usageFn) |
|
| 33 |
+ config.InstallCommonFlags(flags) |
|
| 36 | 34 |
|
| 37 | 35 |
// Then platform-specific install flags |
| 38 |
- config.attachExperimentalFlags(cmd, usageFn) |
|
| 36 |
+ config.attachExperimentalFlags(flags) |
|
| 39 | 37 |
} |
| 40 | 38 |
|
| 41 | 39 |
// GetExecRoot returns the user configured Exec-root |
| ... | ... |
@@ -2,7 +2,9 @@ |
| 2 | 2 |
|
| 3 | 3 |
package daemon |
| 4 | 4 |
|
| 5 |
-import flag "github.com/docker/docker/pkg/mflag" |
|
| 5 |
+import ( |
|
| 6 |
+ "github.com/spf13/pflag" |
|
| 7 |
+) |
|
| 6 | 8 |
|
| 7 |
-func (config *Config) attachExperimentalFlags(cmd *flag.FlagSet, usageFn func(string) string) {
|
|
| 9 |
+func (config *Config) attachExperimentalFlags(cmd *pflag.FlagSet) {
|
|
| 8 | 10 |
} |
| ... | ... |
@@ -7,10 +7,10 @@ import ( |
| 7 | 7 |
"net" |
| 8 | 8 |
|
| 9 | 9 |
"github.com/docker/docker/opts" |
| 10 |
- flag "github.com/docker/docker/pkg/mflag" |
|
| 11 | 10 |
runconfigopts "github.com/docker/docker/runconfig/opts" |
| 12 | 11 |
"github.com/docker/engine-api/types" |
| 13 |
- "github.com/docker/go-units" |
|
| 12 |
+ units "github.com/docker/go-units" |
|
| 13 |
+ "github.com/spf13/pflag" |
|
| 14 | 14 |
) |
| 15 | 15 |
|
| 16 | 16 |
var ( |
| ... | ... |
@@ -56,44 +56,42 @@ type bridgeConfig struct {
|
| 56 | 56 |
InterContainerCommunication bool `json:"icc,omitempty"` |
| 57 | 57 |
} |
| 58 | 58 |
|
| 59 |
-// InstallFlags adds command-line options to the top-level flag parser for |
|
| 60 |
-// the current process. |
|
| 61 |
-// Subsequent calls to `flag.Parse` will populate config with values parsed |
|
| 62 |
-// from the command-line. |
|
| 63 |
-func (config *Config) InstallFlags(cmd *flag.FlagSet, usageFn func(string) string) {
|
|
| 59 |
+// InstallFlags adds flags to the pflag.FlagSet to configure the daemon |
|
| 60 |
+func (config *Config) InstallFlags(flags *pflag.FlagSet) {
|
|
| 64 | 61 |
// First handle install flags which are consistent cross-platform |
| 65 |
- config.InstallCommonFlags(cmd, usageFn) |
|
| 62 |
+ config.InstallCommonFlags(flags) |
|
| 66 | 63 |
|
| 67 |
- // Then platform-specific install flags |
|
| 68 |
- cmd.BoolVar(&config.EnableSelinuxSupport, []string{"-selinux-enabled"}, false, usageFn("Enable selinux support"))
|
|
| 69 |
- cmd.StringVar(&config.SocketGroup, []string{"G", "-group"}, "docker", usageFn("Group for the unix socket"))
|
|
| 70 | 64 |
config.Ulimits = make(map[string]*units.Ulimit) |
| 71 |
- cmd.Var(runconfigopts.NewUlimitOpt(&config.Ulimits), []string{"-default-ulimit"}, usageFn("Default ulimits for containers"))
|
|
| 72 |
- cmd.BoolVar(&config.bridgeConfig.EnableIPTables, []string{"#iptables", "-iptables"}, true, usageFn("Enable addition of iptables rules"))
|
|
| 73 |
- cmd.BoolVar(&config.bridgeConfig.EnableIPForward, []string{"#ip-forward", "-ip-forward"}, true, usageFn("Enable net.ipv4.ip_forward"))
|
|
| 74 |
- cmd.BoolVar(&config.bridgeConfig.EnableIPMasq, []string{"-ip-masq"}, true, usageFn("Enable IP masquerading"))
|
|
| 75 |
- cmd.BoolVar(&config.bridgeConfig.EnableIPv6, []string{"-ipv6"}, false, usageFn("Enable IPv6 networking"))
|
|
| 76 |
- cmd.StringVar(&config.ExecRoot, []string{"-exec-root"}, defaultExecRoot, usageFn("Root directory for execution state files"))
|
|
| 77 |
- cmd.StringVar(&config.bridgeConfig.IP, []string{"#bip", "-bip"}, "", usageFn("Specify network bridge IP"))
|
|
| 78 |
- cmd.StringVar(&config.bridgeConfig.Iface, []string{"b", "-bridge"}, "", usageFn("Attach containers to a network bridge"))
|
|
| 79 |
- cmd.StringVar(&config.bridgeConfig.FixedCIDR, []string{"-fixed-cidr"}, "", usageFn("IPv4 subnet for fixed IPs"))
|
|
| 80 |
- cmd.StringVar(&config.bridgeConfig.FixedCIDRv6, []string{"-fixed-cidr-v6"}, "", usageFn("IPv6 subnet for fixed IPs"))
|
|
| 81 |
- cmd.Var(opts.NewIPOpt(&config.bridgeConfig.DefaultGatewayIPv4, ""), []string{"-default-gateway"}, usageFn("Container default gateway IPv4 address"))
|
|
| 82 |
- cmd.Var(opts.NewIPOpt(&config.bridgeConfig.DefaultGatewayIPv6, ""), []string{"-default-gateway-v6"}, usageFn("Container default gateway IPv6 address"))
|
|
| 83 |
- cmd.BoolVar(&config.bridgeConfig.InterContainerCommunication, []string{"#icc", "-icc"}, true, usageFn("Enable inter-container communication"))
|
|
| 84 |
- cmd.Var(opts.NewIPOpt(&config.bridgeConfig.DefaultIP, "0.0.0.0"), []string{"#ip", "-ip"}, usageFn("Default IP when binding container ports"))
|
|
| 85 |
- cmd.BoolVar(&config.bridgeConfig.EnableUserlandProxy, []string{"-userland-proxy"}, true, usageFn("Use userland proxy for loopback traffic"))
|
|
| 86 |
- cmd.BoolVar(&config.EnableCors, []string{"#api-enable-cors", "#-api-enable-cors"}, false, usageFn("Enable CORS headers in the remote API, this is deprecated by --api-cors-header"))
|
|
| 87 |
- cmd.StringVar(&config.CgroupParent, []string{"-cgroup-parent"}, "", usageFn("Set parent cgroup for all containers"))
|
|
| 88 |
- cmd.StringVar(&config.RemappedRoot, []string{"-userns-remap"}, "", usageFn("User/Group setting for user namespaces"))
|
|
| 89 |
- cmd.StringVar(&config.ContainerdAddr, []string{"-containerd"}, "", usageFn("Path to containerd socket"))
|
|
| 90 |
- cmd.BoolVar(&config.LiveRestoreEnabled, []string{"-live-restore"}, false, usageFn("Enable live restore of docker when containers are still running"))
|
|
| 91 | 65 |
config.Runtimes = make(map[string]types.Runtime) |
| 92 |
- cmd.Var(runconfigopts.NewNamedRuntimeOpt("runtimes", &config.Runtimes, stockRuntimeName), []string{"-add-runtime"}, usageFn("Register an additional OCI compatible runtime"))
|
|
| 93 |
- cmd.StringVar(&config.DefaultRuntime, []string{"-default-runtime"}, stockRuntimeName, usageFn("Default OCI runtime for containers"))
|
|
| 94 |
- cmd.IntVar(&config.OOMScoreAdjust, []string{"-oom-score-adjust"}, -500, usageFn("Set the oom_score_adj for the daemon"))
|
|
| 95 | 66 |
|
| 96 |
- config.attachExperimentalFlags(cmd, usageFn) |
|
| 67 |
+ // Then platform-specific install flags |
|
| 68 |
+ flags.BoolVar(&config.EnableSelinuxSupport, "selinux-enabled", false, "Enable selinux support") |
|
| 69 |
+ flags.Var(runconfigopts.NewUlimitOpt(&config.Ulimits), "default-ulimit", "Default ulimits for containers") |
|
| 70 |
+ flags.BoolVar(&config.bridgeConfig.EnableIPTables, "iptables", true, "Enable addition of iptables rules") |
|
| 71 |
+ flags.BoolVar(&config.bridgeConfig.EnableIPForward, "ip-forward", true, "Enable net.ipv4.ip_forward") |
|
| 72 |
+ flags.BoolVar(&config.bridgeConfig.EnableIPMasq, "ip-masq", true, "Enable IP masquerading") |
|
| 73 |
+ flags.BoolVar(&config.bridgeConfig.EnableIPv6, "ipv6", false, "Enable IPv6 networking") |
|
| 74 |
+ flags.StringVar(&config.ExecRoot, "exec-root", defaultExecRoot, "Root directory for execution state files") |
|
| 75 |
+ flags.StringVar(&config.bridgeConfig.IP, "bip", "", "Specify network bridge IP") |
|
| 76 |
+ flags.StringVarP(&config.bridgeConfig.Iface, "bridge", "b", "", "Attach containers to a network bridge") |
|
| 77 |
+ flags.StringVar(&config.bridgeConfig.FixedCIDR, "fixed-cidr", "", "IPv4 subnet for fixed IPs") |
|
| 78 |
+ flags.StringVar(&config.bridgeConfig.FixedCIDRv6, "fixed-cidr-v6", "", "IPv6 subnet for fixed IPs") |
|
| 79 |
+ flags.Var(opts.NewIPOpt(&config.bridgeConfig.DefaultGatewayIPv4, ""), "default-gateway", "Container default gateway IPv4 address") |
|
| 80 |
+ flags.Var(opts.NewIPOpt(&config.bridgeConfig.DefaultGatewayIPv6, ""), "default-gateway-v6", "Container default gateway IPv6 address") |
|
| 81 |
+ flags.BoolVar(&config.bridgeConfig.InterContainerCommunication, "icc", true, "Enable inter-container communication") |
|
| 82 |
+ flags.Var(opts.NewIPOpt(&config.bridgeConfig.DefaultIP, "0.0.0.0"), "ip", "Default IP when binding container ports") |
|
| 83 |
+ flags.BoolVar(&config.bridgeConfig.EnableUserlandProxy, "userland-proxy", true, "Use userland proxy for loopback traffic") |
|
| 84 |
+ flags.BoolVar(&config.EnableCors, "api-enable-cors", false, "Enable CORS headers in the remote API, this is deprecated by --api-cors-header") |
|
| 85 |
+ flags.MarkDeprecated("api-enable-cors", "Please use --api-cors-header")
|
|
| 86 |
+ flags.StringVar(&config.CgroupParent, "cgroup-parent", "", "Set parent cgroup for all containers") |
|
| 87 |
+ flags.StringVar(&config.RemappedRoot, "userns-remap", "", "User/Group setting for user namespaces") |
|
| 88 |
+ flags.StringVar(&config.ContainerdAddr, "containerd", "", "Path to containerd socket") |
|
| 89 |
+ flags.BoolVar(&config.LiveRestoreEnabled, "live-restore", false, "Enable live restore of docker when containers are still running") |
|
| 90 |
+ flags.Var(runconfigopts.NewNamedRuntimeOpt("runtimes", &config.Runtimes, stockRuntimeName), "add-runtime", "Register an additional OCI compatible runtime")
|
|
| 91 |
+ flags.StringVar(&config.DefaultRuntime, "default-runtime", stockRuntimeName, "Default OCI runtime for containers") |
|
| 92 |
+ flags.IntVar(&config.OOMScoreAdjust, "oom-score-adjust", -500, "Set the oom_score_adj for the daemon") |
|
| 93 |
+ |
|
| 94 |
+ config.attachExperimentalFlags(flags) |
|
| 97 | 95 |
} |
| 98 | 96 |
|
| 99 | 97 |
// GetRuntime returns the runtime path and arguments for a given |
| ... | ... |
@@ -8,9 +8,9 @@ import ( |
| 8 | 8 |
"strings" |
| 9 | 9 |
|
| 10 | 10 |
"github.com/docker/docker/opts" |
| 11 |
- flag "github.com/docker/docker/pkg/mflag" |
|
| 12 | 11 |
"github.com/docker/docker/reference" |
| 13 | 12 |
registrytypes "github.com/docker/engine-api/types/registry" |
| 13 |
+ "github.com/spf13/pflag" |
|
| 14 | 14 |
) |
| 15 | 15 |
|
| 16 | 16 |
// ServiceOptions holds command line options. |
| ... | ... |
@@ -70,14 +70,14 @@ var lookupIP = net.LookupIP |
| 70 | 70 |
|
| 71 | 71 |
// InstallCliFlags adds command-line options to the top-level flag parser for |
| 72 | 72 |
// the current process. |
| 73 |
-func (options *ServiceOptions) InstallCliFlags(cmd *flag.FlagSet, usageFn func(string) string) {
|
|
| 73 |
+func (options *ServiceOptions) InstallCliFlags(flags *pflag.FlagSet) {
|
|
| 74 | 74 |
mirrors := opts.NewNamedListOptsRef("registry-mirrors", &options.Mirrors, ValidateMirror)
|
| 75 |
- cmd.Var(mirrors, []string{"-registry-mirror"}, usageFn("Preferred Docker registry mirror"))
|
|
| 76 |
- |
|
| 77 | 75 |
insecureRegistries := opts.NewNamedListOptsRef("insecure-registries", &options.InsecureRegistries, ValidateIndexName)
|
| 78 |
- cmd.Var(insecureRegistries, []string{"-insecure-registry"}, usageFn("Enable insecure registry communication"))
|
|
| 79 | 76 |
|
| 80 |
- options.installCliPlatformFlags(cmd, usageFn) |
|
| 77 |
+ flags.Var(mirrors, "registry-mirror", "Preferred Docker registry mirror") |
|
| 78 |
+ flags.Var(insecureRegistries, "insecure-registry", "Enable insecure registry communication") |
|
| 79 |
+ |
|
| 80 |
+ options.installCliPlatformFlags(flags) |
|
| 81 | 81 |
} |
| 82 | 82 |
|
| 83 | 83 |
// newServiceConfig returns a new instance of ServiceConfig |
| ... | ... |
@@ -20,6 +20,6 @@ func cleanPath(s string) string {
|
| 20 | 20 |
} |
| 21 | 21 |
|
| 22 | 22 |
// installCliPlatformFlags handles any platform specific flags for the service. |
| 23 |
-func (options *ServiceOptions) installCliPlatformFlags(cmd *flag.FlagSet, usageFn func(string) string) {
|
|
| 24 |
- cmd.BoolVar(&options.V2Only, []string{"-disable-legacy-registry"}, false, usageFn("Disable contacting legacy registries"))
|
|
| 23 |
+func (options *ServiceOptions) installCliPlatformFlags(flags *flag.FlagSet) string) {
|
|
| 24 |
+ flags.BoolVar(&options.V2Only, "disable-legacy-registry", false, "Disable contacting legacy registries") |
|
| 25 | 25 |
} |
| ... | ... |
@@ -20,6 +20,6 @@ func cleanPath(s string) string {
|
| 20 | 20 |
} |
| 21 | 21 |
|
| 22 | 22 |
// installCliPlatformFlags handles any platform specific flags for the service. |
| 23 |
-func (options *ServiceOptions) installCliPlatformFlags(cmd *flag.FlagSet, usageFn func(string) string) {
|
|
| 23 |
+func (options *ServiceOptions) installCliPlatformFlags(flags *flag.FlagSet) string) {
|
|
| 24 | 24 |
// No Windows specific flags. |
| 25 | 25 |
} |