github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/cmd/docker/docker.go (about)

     1  package main
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"os"
     7  
     8  	"github.com/Sirupsen/logrus"
     9  	"github.com/docker/docker/api/types/versions"
    10  	"github.com/docker/docker/cli"
    11  	"github.com/docker/docker/cli/command"
    12  	"github.com/docker/docker/cli/command/commands"
    13  	cliflags "github.com/docker/docker/cli/flags"
    14  	"github.com/docker/docker/cliconfig"
    15  	"github.com/docker/docker/dockerversion"
    16  	"github.com/docker/docker/pkg/term"
    17  	"github.com/docker/docker/utils"
    18  	"github.com/spf13/cobra"
    19  	"github.com/spf13/pflag"
    20  )
    21  
    22  func newDockerCommand(dockerCli *command.DockerCli) *cobra.Command {
    23      fmt.Println("cmd/docker/docker.go  newDockerCommand()")
    24  	opts := cliflags.NewClientOptions()
    25  	var flags *pflag.FlagSet
    26  
    27  	cmd := &cobra.Command{
    28  		Use:              "docker [OPTIONS] COMMAND [ARG...]",
    29  		Short:            "A self-sufficient runtime for containers",
    30  		SilenceUsage:     true,
    31  		SilenceErrors:    true,
    32  		TraverseChildren: true,
    33  		Args:             noArgs,
    34  		RunE: func(cmd *cobra.Command, args []string) error {
    35  			if opts.Version {
    36  				showVersion()
    37  				return nil
    38  			}
    39  			return dockerCli.ShowHelp(cmd, args)
    40  		},
    41  		PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
    42  			// daemon command is special, we redirect directly to another binary
    43  			if cmd.Name() == "daemon" {
    44  				return nil
    45  			}
    46  			// flags must be the top-level command flags, not cmd.Flags()
    47  			opts.Common.SetDefaultOptions(flags)
    48  			dockerPreRun(opts)
    49  			if err := dockerCli.Initialize(opts); err != nil {
    50  				return err
    51  			}
    52  			return isSupported(cmd, dockerCli.Client().ClientVersion(), dockerCli.HasExperimental())
    53  		},
    54  	}
    55  	cli.SetupRootCommand(cmd)
    56  
    57  	cmd.SetHelpFunc(func(ccmd *cobra.Command, args []string) {
    58  		if dockerCli.Client() == nil { // when using --help, PersistenPreRun is not called, so initialization is needed.
    59  			// flags must be the top-level command flags, not cmd.Flags()
    60  			opts.Common.SetDefaultOptions(flags)
    61  			dockerPreRun(opts)
    62  			dockerCli.Initialize(opts)
    63  		}
    64  
    65  		if err := isSupported(ccmd, dockerCli.Client().ClientVersion(), dockerCli.HasExperimental()); err != nil {
    66  			ccmd.Println(err)
    67  			return
    68  		}
    69  
    70  		hideUnsupportedFeatures(ccmd, dockerCli.Client().ClientVersion(), dockerCli.HasExperimental())
    71  
    72  		if err := ccmd.Help(); err != nil {
    73  			ccmd.Println(err)
    74  		}
    75  	})
    76  
    77  	flags = cmd.Flags()
    78  	flags.BoolVarP(&opts.Version, "version", "v", false, "Print version information and quit")
    79  	flags.StringVar(&opts.ConfigDir, "config", cliconfig.ConfigDir(), "Location of client config files")
    80  	opts.Common.InstallFlags(flags)
    81  
    82  	cmd.SetOutput(dockerCli.Out())
    83  	cmd.AddCommand(newDaemonCommand())
    84  	commands.AddCommands(cmd, dockerCli)
    85  
    86  	return cmd
    87  }
    88  
    89  func noArgs(cmd *cobra.Command, args []string) error {
    90  	if len(args) == 0 {
    91  		return nil
    92  	}
    93  	return fmt.Errorf(
    94  		"docker: '%s' is not a docker command.\nSee 'docker --help'", args[0])
    95  }
    96  
    97  func main() {
    98      fmt.Println("cmd/docker/docker.go  main()")
    99  	// Set terminal emulation based on platform as required.
   100  	stdin, stdout, stderr := term.StdStreams()
   101  	logrus.SetOutput(stderr)
   102  
   103  	dockerCli := command.NewDockerCli(stdin, stdout, stderr)
   104  	cmd := newDockerCommand(dockerCli)
   105      fmt.Println("cmd/docker/docker.go  main() cmd : ", cmd)
   106  
   107  	if err := cmd.Execute(); err != nil {
   108  		if sterr, ok := err.(cli.StatusError); ok {
   109  			if sterr.Status != "" {
   110  				fmt.Fprintln(stderr, sterr.Status)
   111  			}
   112  			// StatusError should only be used for errors, and all errors should
   113  			// have a non-zero exit status, so never exit with 0
   114  			if sterr.StatusCode == 0 {
   115  				os.Exit(1)
   116  			}
   117  			os.Exit(sterr.StatusCode)
   118  		}
   119  		fmt.Fprintln(stderr, err)
   120  		os.Exit(1)
   121  	}
   122      fmt.Println("cmd/docker/docker.go  main() end")
   123  }
   124  
   125  func showVersion() {
   126  	fmt.Printf("Docker version %s, build %s\n", dockerversion.Version, dockerversion.GitCommit)
   127  }
   128  
   129  func dockerPreRun(opts *cliflags.ClientOptions) {
   130  	cliflags.SetLogLevel(opts.Common.LogLevel)
   131  
   132  	if opts.ConfigDir != "" {
   133  		cliconfig.SetConfigDir(opts.ConfigDir)
   134  	}
   135  
   136  	if opts.Common.Debug {
   137  		utils.EnableDebug()
   138  	}
   139  }
   140  
   141  func hideUnsupportedFeatures(cmd *cobra.Command, clientVersion string, hasExperimental bool) {
   142  	cmd.Flags().VisitAll(func(f *pflag.Flag) {
   143  		// hide experimental flags
   144  		if !hasExperimental {
   145  			if _, ok := f.Annotations["experimental"]; ok {
   146  				f.Hidden = true
   147  			}
   148  		}
   149  
   150  		// hide flags not supported by the server
   151  		if flagVersion, ok := f.Annotations["version"]; ok && len(flagVersion) == 1 && versions.LessThan(clientVersion, flagVersion[0]) {
   152  			f.Hidden = true
   153  		}
   154  
   155  	})
   156  
   157  	for _, subcmd := range cmd.Commands() {
   158  		// hide experimental subcommands
   159  		if !hasExperimental {
   160  			if _, ok := subcmd.Tags["experimental"]; ok {
   161  				subcmd.Hidden = true
   162  			}
   163  		}
   164  
   165  		// hide subcommands not supported by the server
   166  		if subcmdVersion, ok := subcmd.Tags["version"]; ok && versions.LessThan(clientVersion, subcmdVersion) {
   167  			subcmd.Hidden = true
   168  		}
   169  	}
   170  }
   171  
   172  func isSupported(cmd *cobra.Command, clientVersion string, hasExperimental bool) error {
   173  	if !hasExperimental {
   174  		if _, ok := cmd.Tags["experimental"]; ok {
   175  			return errors.New("only supported with experimental daemon")
   176  		}
   177  	}
   178  
   179  	if cmdVersion, ok := cmd.Tags["version"]; ok && versions.LessThan(clientVersion, cmdVersion) {
   180  		return fmt.Errorf("only supported with daemon version >= %s", cmdVersion)
   181  	}
   182  
   183  	return nil
   184  }