• 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
    }

  • 相关阅读:
    IM设计思考:XMPP多用户文本聊天协议(MUC:Multi User Chat)
    软件设计中的“三视图”
    [C++] 应该如何应对OOM?
    Android 上Camera分析
    android的语言切换应用程序 根据 不同的语言 加载不同的 res
    布局
    布局
    如何解决"Launching New_configuration"问题
    android的语言切换应用程序 根据 不同的语言 加载不同的 res
    如何解决"Launching New_configuration"问题
  • 原文地址:https://www.cnblogs.com/arwen-spy/p/6551265.html
Copyright © 2020-2023  润新知