docker.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "strings"
  6. "github.com/Sirupsen/logrus"
  7. "github.com/docker/docker/cli"
  8. "github.com/docker/docker/cli/command"
  9. "github.com/docker/docker/cli/command/commands"
  10. cliflags "github.com/docker/docker/cli/flags"
  11. "github.com/docker/docker/cliconfig"
  12. "github.com/docker/docker/dockerversion"
  13. "github.com/docker/docker/pkg/term"
  14. "github.com/docker/docker/utils"
  15. "github.com/spf13/cobra"
  16. "github.com/spf13/pflag"
  17. )
  18. func newDockerCommand(dockerCli *command.DockerCli) *cobra.Command {
  19. opts := cliflags.NewClientOptions()
  20. var flags *pflag.FlagSet
  21. cmd := &cobra.Command{
  22. Use: "docker [OPTIONS] COMMAND [arg...]",
  23. Short: "A self-sufficient runtime for containers",
  24. SilenceUsage: true,
  25. SilenceErrors: true,
  26. TraverseChildren: true,
  27. Args: noArgs,
  28. RunE: func(cmd *cobra.Command, args []string) error {
  29. if opts.Version {
  30. showVersion()
  31. return nil
  32. }
  33. cmd.SetOutput(dockerCli.Err())
  34. cmd.HelpFunc()(cmd, args)
  35. return nil
  36. },
  37. PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
  38. // flags must be the top-level command flags, not cmd.Flags()
  39. opts.Common.SetDefaultOptions(flags)
  40. dockerPreRun(opts)
  41. return dockerCli.Initialize(opts)
  42. },
  43. }
  44. cli.SetupRootCommand(cmd)
  45. cmd.SetHelpFunc(func(ccmd *cobra.Command, args []string) {
  46. var err error
  47. if dockerCli.Client() == nil {
  48. // flags must be the top-level command flags, not cmd.Flags()
  49. opts.Common.SetDefaultOptions(flags)
  50. dockerPreRun(opts)
  51. err = dockerCli.Initialize(opts)
  52. }
  53. if err != nil || !dockerCli.HasExperimental() {
  54. hideExperimentalFeatures(ccmd)
  55. }
  56. if err := ccmd.Help(); err != nil {
  57. ccmd.Println(err)
  58. }
  59. })
  60. flags = cmd.Flags()
  61. flags.BoolVarP(&opts.Version, "version", "v", false, "Print version information and quit")
  62. flags.StringVar(&opts.ConfigDir, "config", cliconfig.ConfigDir(), "Location of client config files")
  63. opts.Common.InstallFlags(flags)
  64. cmd.SetOutput(dockerCli.Out())
  65. cmd.AddCommand(newDaemonCommand())
  66. commands.AddCommands(cmd, dockerCli)
  67. return cmd
  68. }
  69. func noArgs(cmd *cobra.Command, args []string) error {
  70. if len(args) == 0 {
  71. return nil
  72. }
  73. return fmt.Errorf(
  74. "docker: '%s' is not a docker command.\nSee 'docker --help'%s", args[0], ".")
  75. }
  76. func main() {
  77. // Set terminal emulation based on platform as required.
  78. stdin, stdout, stderr := term.StdStreams()
  79. logrus.SetOutput(stderr)
  80. dockerCli := command.NewDockerCli(stdin, stdout, stderr)
  81. cmd := newDockerCommand(dockerCli)
  82. if err := cmd.Execute(); err != nil {
  83. if sterr, ok := err.(cli.StatusError); ok {
  84. if sterr.Status != "" {
  85. fmt.Fprintln(stderr, sterr.Status)
  86. }
  87. // StatusError should only be used for errors, and all errors should
  88. // have a non-zero exit status, so never exit with 0
  89. if sterr.StatusCode == 0 {
  90. os.Exit(1)
  91. }
  92. os.Exit(sterr.StatusCode)
  93. }
  94. fmt.Fprintln(stderr, err)
  95. os.Exit(1)
  96. }
  97. }
  98. func showVersion() {
  99. fmt.Printf("Docker version %s, build %s\n", dockerversion.Version, dockerversion.GitCommit)
  100. }
  101. func dockerPreRun(opts *cliflags.ClientOptions) {
  102. cliflags.SetLogLevel(opts.Common.LogLevel)
  103. if opts.ConfigDir != "" {
  104. cliconfig.SetConfigDir(opts.ConfigDir)
  105. }
  106. if opts.Common.Debug {
  107. utils.EnableDebug()
  108. }
  109. }
  110. func hideExperimentalFeatures(cmd *cobra.Command) {
  111. // hide flags
  112. cmd.Flags().VisitAll(func(f *pflag.Flag) {
  113. if _, ok := f.Annotations["experimental"]; ok {
  114. f.Hidden = true
  115. }
  116. })
  117. for _, subcmd := range cmd.Commands() {
  118. // hide subcommands
  119. name := strings.Split(subcmd.Use, " ")[0]
  120. if name == "stack" || name == "deploy" || name == "checkpoint" || name == "plugin" {
  121. subcmd.Hidden = true
  122. }
  123. }
  124. }