甩祸 发表于 2017-12-6 17:40:15

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 COMMAND ",
      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
}
页: [1]
查看完整版本: docker 源码分析client1