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
}

posted on 2017-03-15 22:49  arwen_spy  阅读(793)  评论(1编辑  收藏  举报

导航