docker 源码分析client1
网上搜到的源码分析对应版本太老,Docker的main函数不是位于./docker/docker/docker.go,之能自己研究
当前版本的client 和 deamon 的main函数虽然都是在cmd目录下但是分开的
client位于/cmd/docker/docker.go,deamon位于/cmd/dockerd/docker.go
分析client端,有几个库包需要先了解一下
"github.com/Sirupsen/logrus" 结构化的log 库
"github.com/spf13/cobra" Cobra 是命令行的库
"github.com/spf13/pflag" 用于替换go 自带的flag包
回到main函数,就是创建cli->创建cmd->执行cmd
func main() {
stdin, stdout, stderr := term.StdStreams()
dockerCli := command.NewDockerCli(stdin, stdout, stderr)
cmd := newDockerCommand(dockerCli)
err := cmd.Execute()
.....
}
最关键部分就是 newDockerCommand 函数,创建cobra.command
func newDockerCommand(dockerCli *command.DockerCli) *cobra.Command {
opts := cliflags.NewClientOptions() // cli/flags/client.go创建一个clientoption
var flags *pflag.FlagSet
cmd := &cobra.Command{ //cobra/command.go
Use: "docker [OPTIONS] COMMAND [ARG...]",
Short: "A self-sufficient runtime for containers",
SilenceUsage: true,
SilenceErrors: true,
TraverseChildren: true,
Args: noArgs,
RunE: func(cmd *cobra.Command, args []string) error { //Run but returns an error
if opts.Version {
showVersion()
return nil
}
return dockerCli.ShowHelp(cmd, args)
},
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {//children of this command will inherit and execute
// daemon command is special, we redirect directly to another binary
if cmd.Name() == "daemon" {
return nil
}
// flags must be the top-level command flags, not cmd.Flags()
opts.Common.SetDefaultOptions(flags) // cli/flags/common.go 设置一些默认参数
dockerPreRun(opts) //参数的一些设置
if err := dockerCli.Initialize(opts); err != nil { //cli/command/cli.go 设置cli的一些参数 .docker/config.json
return err
}
return isSupported(cmd, dockerCli.Client().ClientVersion(), dockerCli.HasExperimental()) //命令是否支持
},
}
cli.SetupRootCommand(cmd) //cli/cobra.go 根命令增加help和errfunc
flags = cmd.Flags() //cobra/command.go 返回FlagSet,如果commod里面没有FlagSet就创建一个
flags.BoolVarP(&opts.Version, "version", "v", false, "Print version information and quit")
flags.StringVar(&opts.ConfigDir, "config", cliconfig.Dir(), "Location of client config files")
opts.Common.InstallFlags(flags) // cli/flags/common.go 增加flags
setFlagErrorFunc(dockerCli, cmd, flags, opts) //设置这2个func
setHelpFunc(dockerCli, cmd, flags, opts)
cmd.SetOutput(dockerCli.Out())
cmd.AddCommand(newDaemonCommand()) //把daemon的cmd作为子命令增加
commands.AddCommands(cmd, dockerCli) // cli/command/commands/commands.go 增加commond目录下所有的命令
setValidateArgs(dockerCli, cmd, flags, opts)
return cmd
}