Convert dockerd to use cobra and pflag

Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: fb83394714a9797f8ca5a08023a89560ce6c4aa3
Component: engine
This commit is contained in:
Daniel Nephin
2016-06-21 16:42:47 -04:00
parent 253b72c341
commit 894a7b4b95
15 changed files with 253 additions and 233 deletions

View File

@ -101,6 +101,7 @@ func initClientFlags(commonFlags *cliflags.CommonFlags) *cliflags.ClientFlags {
clientFlags.PostParse = func() {
clientFlags.Common.PostParse()
cliflags.SetDaemonLogLevel(commonOpts.LogLevel)
if clientFlags.ConfigDir != "" {
cliconfig.SetConfigDir(clientFlags.ConfigDir)

View File

@ -6,7 +6,6 @@ import (
"io"
"os"
"path/filepath"
"runtime"
"strings"
"time"
@ -31,11 +30,10 @@ import (
"github.com/docker/docker/daemon/logger"
"github.com/docker/docker/dockerversion"
"github.com/docker/docker/libcontainerd"
"github.com/docker/docker/opts"
dopts "github.com/docker/docker/opts"
"github.com/docker/docker/pkg/authorization"
"github.com/docker/docker/pkg/jsonlog"
"github.com/docker/docker/pkg/listeners"
flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/pkg/pidfile"
"github.com/docker/docker/pkg/signal"
"github.com/docker/docker/pkg/system"
@ -43,46 +41,27 @@ import (
"github.com/docker/docker/runconfig"
"github.com/docker/docker/utils"
"github.com/docker/go-connections/tlsconfig"
"github.com/spf13/pflag"
)
const (
daemonConfigFileFlag = "-config-file"
flagDaemonConfigFile = "config-file"
)
// DaemonCli represents the daemon CLI.
type DaemonCli struct {
*daemon.Config
commonFlags *cliflags.CommonFlags
configFile *string
configFile *string
flags *pflag.FlagSet
api *apiserver.Server
d *daemon.Daemon
authzMiddleware *authorization.Middleware // authzMiddleware enables to dynamically reload the authorization plugins
}
func presentInHelp(usage string) string { return usage }
func absentFromHelp(string) string { return "" }
// NewDaemonCli returns a pre-configured daemon CLI
// NewDaemonCli returns a daemon CLI
func NewDaemonCli() *DaemonCli {
// TODO(tiborvass): remove InstallFlags?
daemonConfig := new(daemon.Config)
daemonConfig.LogConfig.Config = make(map[string]string)
daemonConfig.ClusterOpts = make(map[string]string)
daemonConfig.InstallFlags(flag.CommandLine, presentInHelp)
configFile := flag.CommandLine.String([]string{daemonConfigFileFlag}, defaultDaemonConfigFile, "Daemon configuration file")
flag.CommandLine.Require(flag.Exact, 0)
if runtime.GOOS != "linux" {
daemonConfig.V2Only = true
}
return &DaemonCli{
Config: daemonConfig,
commonFlags: cliflags.InitCommonFlags(),
configFile: configFile,
}
return &DaemonCli{}
}
func migrateKey() (err error) {
@ -126,24 +105,25 @@ func migrateKey() (err error) {
return nil
}
func (cli *DaemonCli) start() (err error) {
func (cli *DaemonCli) start(opts daemonOptions) (err error) {
stopc := make(chan bool)
defer close(stopc)
// warn from uuid package when running the daemon
uuid.Loggerf = logrus.Warnf
flags := flag.CommandLine
cli.commonFlags.PostParse()
opts.common.SetDefaultOptions(opts.flags)
if cli.commonFlags.TrustKey == "" {
cli.commonFlags.TrustKey = filepath.Join(getDaemonConfDir(), cliflags.DefaultTrustKeyFile)
if opts.common.TrustKey == "" {
opts.common.TrustKey = filepath.Join(
getDaemonConfDir(),
cliflags.DefaultTrustKeyFile)
}
cliConfig, err := loadDaemonCliConfig(cli.Config, flags, cli.commonFlags, *cli.configFile)
if err != nil {
if cli.Config, err = loadDaemonCliConfig(opts); err != nil {
return err
}
cli.Config = cliConfig
cli.configFile = &opts.configFile
cli.flags = opts.flags
if cli.Config.Debug {
utils.EnableDebug()
@ -215,7 +195,7 @@ func (cli *DaemonCli) start() (err error) {
for i := 0; i < len(cli.Config.Hosts); i++ {
var err error
if cli.Config.Hosts[i], err = opts.ParseHost(cli.Config.TLS, cli.Config.Hosts[i]); err != nil {
if cli.Config.Hosts[i], err = dopts.ParseHost(cli.Config.TLS, cli.Config.Hosts[i]); err != nil {
return fmt.Errorf("error parsing -H %s : %v", cli.Config.Hosts[i], err)
}
@ -250,7 +230,8 @@ func (cli *DaemonCli) start() (err error) {
if err := migrateKey(); err != nil {
return err
}
cli.TrustKeyPath = cli.commonFlags.TrustKey
// FIXME: why is this down here instead of with the other TrustKey logic above?
cli.TrustKeyPath = opts.common.TrustKey
registryService := registry.NewService(cli.Config.ServiceOptions)
containerdRemote, err := libcontainerd.New(cli.getLibcontainerdRoot(), cli.getPlatformRemoteOptions()...)
@ -341,7 +322,7 @@ func (cli *DaemonCli) reloadConfig() {
}
}
if err := daemon.ReloadConfiguration(*cli.configFile, flag.CommandLine, reload); err != nil {
if err := daemon.ReloadConfiguration(*cli.configFile, cli.flags, reload); err != nil {
logrus.Error(err)
}
}
@ -367,25 +348,27 @@ func shutdownDaemon(d *daemon.Daemon, timeout time.Duration) {
}
}
func loadDaemonCliConfig(config *daemon.Config, flags *flag.FlagSet, commonConfig *cliflags.CommonFlags, configFile string) (*daemon.Config, error) {
config.Debug = commonConfig.Debug
config.Hosts = commonConfig.Hosts
config.LogLevel = commonConfig.LogLevel
config.TLS = commonConfig.TLS
config.TLSVerify = commonConfig.TLSVerify
func loadDaemonCliConfig(opts daemonOptions) (*daemon.Config, error) {
config := opts.daemonConfig
flags := opts.flags
config.Debug = opts.common.Debug
config.Hosts = opts.common.Hosts
config.LogLevel = opts.common.LogLevel
config.TLS = opts.common.TLS
config.TLSVerify = opts.common.TLSVerify
config.CommonTLSOptions = daemon.CommonTLSOptions{}
if commonConfig.TLSOptions != nil {
config.CommonTLSOptions.CAFile = commonConfig.TLSOptions.CAFile
config.CommonTLSOptions.CertFile = commonConfig.TLSOptions.CertFile
config.CommonTLSOptions.KeyFile = commonConfig.TLSOptions.KeyFile
if opts.common.TLSOptions != nil {
config.CommonTLSOptions.CAFile = opts.common.TLSOptions.CAFile
config.CommonTLSOptions.CertFile = opts.common.TLSOptions.CertFile
config.CommonTLSOptions.KeyFile = opts.common.TLSOptions.KeyFile
}
if configFile != "" {
c, err := daemon.MergeDaemonConfigurations(config, flags, configFile)
if opts.configFile != "" {
c, err := daemon.MergeDaemonConfigurations(config, flags, opts.configFile)
if err != nil {
if flags.IsSet(daemonConfigFileFlag) || !os.IsNotExist(err) {
return nil, fmt.Errorf("unable to configure the Docker daemon with file %s: %v\n", configFile, err)
if flags.Changed(flagDaemonConfigFile) || !os.IsNotExist(err) {
return nil, fmt.Errorf("unable to configure the Docker daemon with file %s: %v\n", opts.configFile, err)
}
}
// 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
// Regardless of whether the user sets it to true or false, if they
// specify TLSVerify at all then we need to turn on TLS
if config.IsValueSet(cliflags.TLSVerifyKey) {
if config.IsValueSet(cliflags.FlagTLSVerify) {
config.TLS = true
}

View File

@ -2,59 +2,61 @@ package main
import (
"fmt"
"os"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/cli"
cliflags "github.com/docker/docker/cli/flags"
"github.com/docker/docker/daemon"
"github.com/docker/docker/dockerversion"
flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/pkg/reexec"
"github.com/docker/docker/pkg/term"
"github.com/docker/docker/utils"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var (
daemonCli = NewDaemonCli()
flHelp = flag.Bool([]string{"h", "-help"}, false, "Print usage")
flVersion = flag.Bool([]string{"v", "-version"}, false, "Print version information and quit")
)
type daemonOptions struct {
version bool
configFile string
daemonConfig *daemon.Config
common *cliflags.CommonOptions
flags *pflag.FlagSet
}
func main() {
if reexec.Init() {
return
func newDaemonCommand() *cobra.Command {
opts := daemonOptions{
daemonConfig: daemon.NewConfig(),
common: cliflags.NewCommonOptions(),
}
// Set terminal emulation based on platform as required.
_, stdout, stderr := term.StdStreams()
logrus.SetOutput(stderr)
flag.Merge(flag.CommandLine, daemonCli.commonFlags.FlagSet)
flag.Usage = func() {
fmt.Fprint(stdout, "Usage: dockerd [OPTIONS]\n\n")
fmt.Fprint(stdout, "A self-sufficient runtime for containers.\n\nOptions:\n")
flag.CommandLine.SetOutput(stdout)
flag.PrintDefaults()
}
flag.CommandLine.ShortUsage = func() {
fmt.Fprint(stderr, "\nUsage:\tdockerd [OPTIONS]\n")
cmd := &cobra.Command{
Use: "dockerd [OPTIONS]",
Short: "A self-sufficient runtime for containers.",
SilenceUsage: true,
SilenceErrors: true,
Args: cli.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
opts.flags = cmd.Flags()
return runDaemon(opts)
},
}
// TODO: SetUsageTemplate, SetHelpTemplate, SetFlagErrorFunc
if err := flag.CommandLine.ParseFlags(os.Args[1:], false); err != nil {
os.Exit(1)
}
flags := cmd.Flags()
flags.BoolP("help", "h", false, "Print usage")
flags.MarkShorthandDeprecated("help", "please use --help")
flags.BoolVarP(&opts.version, "version", "v", false, "Print version information and quit")
flags.StringVar(&opts.configFile, flagDaemonConfigFile, defaultDaemonConfigFile, "Daemon configuration file")
opts.common.InstallFlags(flags)
opts.daemonConfig.InstallFlags(flags)
if *flVersion {
return cmd
}
func runDaemon(opts daemonOptions) error {
if opts.version {
showVersion()
return
}
if *flHelp {
// if global flag --help is present, regardless of what other options and commands there are,
// just print the usage.
flag.Usage()
return
return nil
}
// On Windows, this may be launching as a service or with an option to
@ -64,13 +66,13 @@ func main() {
logrus.Fatal(err)
}
if !stop {
err = daemonCli.start()
notifyShutdown(err)
if err != nil {
logrus.Fatal(err)
}
if stop {
return nil
}
err = NewDaemonCli().start(opts)
notifyShutdown(err)
return err
}
func showVersion() {
@ -80,3 +82,19 @@ func showVersion() {
fmt.Printf("Docker version %s, build %s\n", dockerversion.Version, dockerversion.GitCommit)
}
}
func main() {
if reexec.Init() {
return
}
// Set terminal emulation based on platform as required.
_, stdout, stderr := term.StdStreams()
logrus.SetOutput(stderr)
cmd := newDaemonCommand()
cmd.SetOutput(stdout)
if err := cmd.Execute(); err != nil {
logrus.Fatal(err)
}
}