docker.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "github.com/Sirupsen/logrus"
  6. "github.com/docker/docker/api/client"
  7. "github.com/docker/docker/api/client/command"
  8. "github.com/docker/docker/cli"
  9. cliflags "github.com/docker/docker/cli/flags"
  10. "github.com/docker/docker/cliconfig"
  11. "github.com/docker/docker/dockerversion"
  12. "github.com/docker/docker/pkg/term"
  13. "github.com/docker/docker/utils"
  14. "github.com/spf13/cobra"
  15. "github.com/spf13/pflag"
  16. )
  17. func newDockerCommand(dockerCli *client.DockerCli) *cobra.Command {
  18. opts := cliflags.NewClientOptions()
  19. var flags *pflag.FlagSet
  20. cmd := &cobra.Command{
  21. Use: "docker [OPTIONS] COMMAND [arg...]",
  22. Short: "A self-sufficient runtime for containers.",
  23. SilenceUsage: true,
  24. SilenceErrors: true,
  25. TraverseChildren: true,
  26. Args: noArgs,
  27. RunE: func(cmd *cobra.Command, args []string) error {
  28. if opts.Version {
  29. showVersion()
  30. return nil
  31. }
  32. fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())
  33. return nil
  34. },
  35. PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
  36. // flags must be the top-level command flags, not cmd.Flags()
  37. opts.Common.SetDefaultOptions(flags)
  38. dockerPreRun(opts)
  39. return dockerCli.Initialize(opts)
  40. },
  41. }
  42. cli.SetupRootCommand(cmd)
  43. flags = cmd.Flags()
  44. flags.BoolVarP(&opts.Version, "version", "v", false, "Print version information and quit")
  45. flags.StringVar(&opts.ConfigDir, "config", cliconfig.ConfigDir(), "Location of client config files")
  46. opts.Common.InstallFlags(flags)
  47. cmd.SetOutput(dockerCli.Out())
  48. cmd.AddCommand(newDaemonCommand())
  49. command.AddCommands(cmd, dockerCli)
  50. return cmd
  51. }
  52. func noArgs(cmd *cobra.Command, args []string) error {
  53. if len(args) == 0 {
  54. return nil
  55. }
  56. return fmt.Errorf(
  57. "docker: '%s' is not a docker command.\nSee 'docker --help'%s", args[0], ".")
  58. }
  59. func main() {
  60. // Set terminal emulation based on platform as required.
  61. stdin, stdout, stderr := term.StdStreams()
  62. logrus.SetOutput(stderr)
  63. dockerCli := client.NewDockerCli(stdin, stdout, stderr)
  64. cmd := newDockerCommand(dockerCli)
  65. if err := cmd.Execute(); err != nil {
  66. if sterr, ok := err.(cli.StatusError); ok {
  67. if sterr.Status != "" {
  68. fmt.Fprintln(stderr, sterr.Status)
  69. }
  70. // StatusError should only be used for errors, and all errors should
  71. // have a non-zero exit status, so never exit with 0
  72. if sterr.StatusCode == 0 {
  73. os.Exit(1)
  74. }
  75. os.Exit(sterr.StatusCode)
  76. }
  77. fmt.Fprintln(stderr, err)
  78. os.Exit(1)
  79. }
  80. }
  81. func showVersion() {
  82. if utils.ExperimentalBuild() {
  83. fmt.Printf("Docker version %s, build %s, experimental\n", dockerversion.Version, dockerversion.GitCommit)
  84. } else {
  85. fmt.Printf("Docker version %s, build %s\n", dockerversion.Version, dockerversion.GitCommit)
  86. }
  87. }
  88. func dockerPreRun(opts *cliflags.ClientOptions) {
  89. cliflags.SetDaemonLogLevel(opts.Common.LogLevel)
  90. if opts.ConfigDir != "" {
  91. cliconfig.SetConfigDir(opts.ConfigDir)
  92. }
  93. if opts.Common.Debug {
  94. utils.EnableDebug()
  95. }
  96. }