github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/cmd/firstContainer/docker.go (about) 1 package firstContainer 2 3 import ( 4 "errors" 5 "fmt" 6 7 "github.com/docker/docker/api/types/versions" 8 "github.com/docker/docker/cli" 9 "github.com/docker/docker/cli/command" 10 "github.com/docker/docker/cli/command/commands" 11 cliflags "github.com/docker/docker/cli/flags" 12 "github.com/docker/docker/cliconfig" 13 "github.com/docker/docker/dockerversion" 14 "github.com/docker/docker/utils" 15 "github.com/spf13/cobra" 16 "github.com/spf13/pflag" 17 ) 18 19 func NewFirstDockerCommand(dockerCli *command.DockerCli) *cobra.Command { 20 fmt.Println("cmd/docker/docker.go newFirstDockerCommand()") 21 opts := cliflags.NewClientOptions() 22 var flags *pflag.FlagSet 23 24 cmd := &cobra.Command{ 25 Use: "docker [OPTIONS] COMMAND [ARG...]", 26 Short: "A self-sufficient runtime for containers", 27 SilenceUsage: true, 28 SilenceErrors: true, 29 TraverseChildren: true, 30 Args: noArgs, 31 RunE: func(cmd *cobra.Command, args []string) error { 32 if opts.Version { 33 showVersion() 34 return nil 35 } 36 return dockerCli.ShowHelp(cmd, args) 37 }, 38 PersistentPreRunE: func(cmd *cobra.Command, args []string) error { 39 // daemon command is special, we redirect directly to another binary 40 if cmd.Name() == "daemon" { 41 return nil 42 } 43 // flags must be the top-level command flags, not cmd.Flags() 44 opts.Common.SetDefaultOptions(flags) 45 dockerPreRun(opts) 46 if err := dockerCli.Initialize(opts); err != nil { 47 return err 48 } 49 return isSupported(cmd, dockerCli.Client().ClientVersion(), dockerCli.HasExperimental()) 50 }, 51 } 52 cli.SetupRootCommand(cmd) 53 54 cmd.SetHelpFunc(func(ccmd *cobra.Command, args []string) { 55 if dockerCli.Client() == nil { // when using --help, PersistenPreRun is not called, so initialization is needed. 56 // flags must be the top-level command flags, not cmd.Flags() 57 opts.Common.SetDefaultOptions(flags) 58 dockerPreRun(opts) 59 dockerCli.Initialize(opts) 60 } 61 62 if err := isSupported(ccmd, dockerCli.Client().ClientVersion(), dockerCli.HasExperimental()); err != nil { 63 ccmd.Println(err) 64 return 65 } 66 67 hideUnsupportedFeatures(ccmd, dockerCli.Client().ClientVersion(), dockerCli.HasExperimental()) 68 69 if err := ccmd.Help(); err != nil { 70 ccmd.Println(err) 71 } 72 }) 73 74 flags = cmd.Flags() 75 flags.BoolVarP(&opts.Version, "version", "v", false, "Print version information and quit") 76 flags.StringVar(&opts.ConfigDir, "config", cliconfig.ConfigDir(), "Location of client config files") 77 opts.Common.InstallFlags(flags) 78 79 cmd.SetOutput(dockerCli.Out()) 80 cmd.AddCommand(newDaemonCommand()) 81 // fmt.Println("cmd/firstContainer.go newFirstDockerCommand() not found newDaemonCommand()!!!") 82 fmt.Println("cmd/firstContainer.go newFirstDockerCommand() begin to add cmd!!!") 83 commands.AddCommands(cmd, dockerCli) 84 85 return cmd 86 } 87 88 func noArgs(cmd *cobra.Command, args []string) error { 89 fmt.Println("cmd/firstContainer/docker.go noArgs()") 90 if len(args) == 0 { 91 return nil 92 } 93 fmt.Println("cmd/firstContainer/docker.go noArgs() err : is not a docker command") 94 return fmt.Errorf( 95 "docker: '%s' is not a docker command.\nSee 'docker --help'", args[0]) 96 } 97 /* 98 func main() { 99 fmt.Println("cmd/docker/docker.go main()") 100 // Set terminal emulation based on platform as required. 101 stdin, stdout, stderr := term.StdStreams() 102 logrus.SetOutput(stderr) 103 104 dockerCli := command.NewDockerCli(stdin, stdout, stderr) 105 cmd := newDockerCommand(dockerCli) 106 fmt.Println("cmd/docker/docker.go main() cmd : ", cmd) 107 108 if err := cmd.Execute(); err != nil { 109 if sterr, ok := err.(cli.StatusError); ok { 110 if sterr.Status != "" { 111 fmt.Fprintln(stderr, sterr.Status) 112 } 113 // StatusError should only be used for errors, and all errors should 114 // have a non-zero exit status, so never exit with 0 115 if sterr.StatusCode == 0 { 116 os.Exit(1) 117 } 118 os.Exit(sterr.StatusCode) 119 } 120 fmt.Fprintln(stderr, err) 121 os.Exit(1) 122 } 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 }