最近在看doccker的源码,最新的master分支(估计是1.12.4,因为最新的release是1.12.3)命令行解析全部都使用了第3方的包https://github.com/spf13/cobra。然后看了一下别的分支的代码,感觉结构确实清晰了很多,可读性变高了不少。先看一下如何去使用。

客户端main()在docker/docker/cmd/docker下,可以直接使用go build编译(把vendor下的依赖包移出来就可以了)。

L20-58:

func newDockerCommand(dockerCli *command.DockerCli) *cobra.Command {opts := cliflags.NewClientOptions()var flags *pflag.FlagSetcmd := &cobra.Command{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 {if opts.Version {showVersion()return nil}fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())return nil},PersistentPreRunE: func(cmd *cobra.Command, args []string) error {// flags must be the top-level command flags, not cmd.Flags()opts.Common.SetDefaultOptions(flags)dockerPreRun(opts)return dockerCli.Initialize(opts)},}cli.SetupRootCommand(cmd)flags = cmd.Flags()flags.BoolVarP(&opts.Version, "version", "v", false, "Print version information and quit")flags.StringVar(&opts.ConfigDir, "config", cliconfig.ConfigDir(), "Location of client config files")opts.Common.InstallFlags(flags)cmd.SetOutput(dockerCli.Out())cmd.AddCommand(newDaemonCommand())commands.AddCommands(cmd, dockerCli)return cmd
}

这个方法会完成所有命令行规则的添加,和相应执行的方法。RunE: func(cmd *cobra.Command, args []string) error {}是命令执行的方法,flags是参数的解析。当我们输入docker -v,执行showversion()方法,*cobra.Command结构体是一个树的结构,docker下面有很多的子命令,比如docker image,然后image下面可以添加参数 -a等,最后只要在main()中执行cmd.Execute()就可以完成所有解析,这是也是第3方包的方法。

ctrl+鼠标右键点击进入commands.AddCommands(cmd, dockerCli)

func AddCommands(cmd *cobra.Command, dockerCli *command.DockerCli) {cmd.AddCommand(node.NewNodeCommand(dockerCli),service.NewServiceCommand(dockerCli),stack.NewStackCommand(dockerCli),stack.NewTopLevelDeployCommand(dockerCli),swarm.NewSwarmCommand(dockerCli),container.NewContainerCommand(dockerCli),image.NewImageCommand(dockerCli),
。。。)
}

封装了一下cmd.AddCommand()方法,然后node.service.stack.swarm.container这些包都写了个大写new方法来创建命令,继续进入container.NewContainerCommand(dockerCli),这是所有的方法都传入了dockerCli(单例模式直视感),

func NewContainerCommand(dockerCli *command.DockerCli) *cobra.Command {cmd := &cobra.Command{Use:   "container",Short: "Manage containers",Args:  cli.NoArgs,Run: func(cmd *cobra.Command, args []string) {fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())},}cmd.AddCommand(NewAttachCommand(dockerCli),NewCommitCommand(dockerCli),NewCopyCommand(dockerCli),NewCreateCommand(dockerCli),NewDiffCommand(dockerCli),NewExecCommand(dockerCli),NewExportCommand(dockerCli),NewKillCommand(dockerCli),NewLogsCommand(dockerCli),NewPauseCommand(dockerCli),NewPortCommand(dockerCli),NewRenameCommand(dockerCli),NewRestartCommand(dockerCli),NewRmCommand(dockerCli),NewRunCommand(dockerCli),NewStartCommand(dockerCli),NewStatsCommand(dockerCli),NewStopCommand(dockerCli),NewTopCommand(dockerCli),NewUnpauseCommand(dockerCli),NewUpdateCommand(dockerCli),NewWaitCommand(dockerCli),newListCommand(dockerCli),newInspectCommand(dockerCli),NewPruneCommand(dockerCli),)return cmd
}

  docker contain下又添加了很多的命令,继续进入

func NewCreateCommand(dockerCli *command.DockerCli) *cobra.Command {var opts createOptionsvar copts *runconfigopts.ContainerOptionscmd := &cobra.Command{Use:   "create [OPTIONS] IMAGE [COMMAND] [ARG...]",Short: "Create a new container",Args:  cli.RequiresMinArgs(1),RunE: func(cmd *cobra.Command, args []string) error {copts.Image = args[0]if len(args) > 1 {copts.Args = args[1:]}return runCreate(dockerCli, cmd.Flags(), &opts, copts)},}flags := cmd.Flags()flags.SetInterspersed(false)flags.StringVar(&opts.name, "name", "", "Assign a name to the container")// Add an explicit help that doesn't have a `-h` to prevent the conflict// with hostnameflags.Bool("help", false, "Print usage")command.AddTrustedFlags(flags, true)copts = runconfigopts.AddFlags(flags)return cmd
}

  这里可以看到解析了name和help,docker run create命令就是这么来的,然后看一下RunE中是如何向服务器端发送请求的,继续进入最后可以得到一个这个方法,response, err := dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, name)

func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (types.ContainerCreateResponse, error) {var response types.ContainerCreateResponsequery := url.Values{}if containerName != "" {query.Set("name", containerName)}body := configWrapper{Config:           config,HostConfig:       hostConfig,NetworkingConfig: networkingConfig,}serverResp, err := cli.post(ctx, "/containers/create", query, body, nil)if err != nil {if serverResp != nil && serverResp.statusCode == 404 && strings.Contains(err.Error(), "No such image") {return response, imageNotFoundError{config.Image}}return response, err}err = json.NewDecoder(serverResp.body).Decode(&response)ensureReaderClosed(serverResp)return response, err
}

发送post /containers/create请求,细节的地方需要继续去看,服务器端的命令解析也是一样的,目录在docker/docker/cmd/dockerd下,go编译的包是通过包名获取的,所以deamon的命令就是dockerd,有一个很好的方法是dockerd -D,可以看到调试的信息,service api的添加,网络的初始化等。。

https://github.com/zjj2wry/httptest,这是拿那个命令行解析写的一个post请求,可以携带参数,cookies等,然后生成接口文档,对我已经完全够了(目前业务百分之90都是post),主要写个接口得给前端一个文档,偷个懒。。

转载于:https://www.cnblogs.com/52zjj/p/6029739.html

docker命令行解析以及如何向服务器端发送请求(docker源码学习一)相关推荐

  1. Docker命令行探秘

    1. Docker命令行 Docker官方为了让用户快速了解Docker,提供了一个交互式教程,旨在帮助用户掌握Docker命令行的使用方法.但是由于Docker技术的快速发展,此交互式教程已经无法满 ...

  2. 深入浅出Docker(二):Docker命令行探秘

    本文原创版权归 infoq 肖德时 所有,此处为技术收藏,如有再转,请于篇头保留原创作者及出处,以示尊重! 作者: 肖德时 原文: http://www.infoq.com/cn/articles/d ...

  3. linux c 命令行解析 getopt getopt_long optarg optind opterr optopt 简介

    目录 getopt 函数 测试代码 getopt_long函数 代码示例 getopt 函数 头文件 #include<unistd.h> 定义函数 int getopt(int argc ...

  4. python解析库_Python命令行解析库argparse

    原博文 2014-08-13 05:48 − 2.7之后python不再对optparse模块进行扩展,python标准库推荐使用argparse模块对命令行进行解析. 1.example 有一道面试 ...

  5. python:argparse命令行解析模块详解

    argparse命令行解析模块学习 import argparse parser = argparse.ArgumentParser() #类似于初始化吧 parser.parse_args() #解 ...

  6. .NET:命令行解析器介绍

    背景 经常需要开发一下小工具,之前都是自己解析命令行参数,接触过动态语言社区以后,发现命令行解析有特定的模式和框架可以利用,本文介绍一个 .NET 平台的类库. 示例 需求 拷贝文件,如:CopyFi ...

  7. python之命令行解析工具argparse

    以前写python的时候都会自己在文件开头写一个usgae函数,用来加上各种注释,给用这个脚本的人提供帮助文档. 今天才知道原来python已经有一个自带的命令行解析工具argparse,用了一下,效 ...

  8. Python命令行解析:sys.argv[]函数的简介、案例应用之详细攻略

    Python命令行解析:sys.argv[]函数的简介.案例应用之详细攻略 目录 sys.argv[]函数的简介 sys.argv[]函数的案例应用 1.基础测试 2.进阶用法 3.sys.argv[ ...

  9. TF之TF flags:TF flags(命令行解析)的简介、安装、使用方法之详细攻略

    TF之TF flags:TF flags(命令行解析)的简介.安装.使用方法之详细攻略 目录 TF flags的简介 TF flags的安装 TF flags的使用方法 TF flags的简介 1.f ...

最新文章

  1. android实现计算器功能吗,利用Android实现一个简单的计算器功能
  2. excel中日期设置星期
  3. vue 微信支付的坑_vue_模式下h5微信支付
  4. java并发编程-----深入剖析ThreadLocal
  5. Java编程学习中必须掌握的13个核心技术
  6. 基于Vitual Box建立虚拟机,虚拟机系统为Linux Ubuntu16.04
  7. java get https_JAVA – 使用SSL证书和HTTPS的简单GET请求
  8. Android Sqlite数据库操作
  9. github使用介绍
  10. UVM:factory 机制
  11. GitHub 上最火的开源项目 —— Java 篇
  12. 面向光栅薄膜光学性能探究的Rsoft建模与仿真
  13. 晚上几点睡才叫“熬夜”?给你“答案”,很多人都想错了
  14. go,go语言编辑器安装,git安装,即vscode三个插件的安装
  15. 前后端分离之图片上传服务端处理方法(亲测通过)
  16. 社群的使用---Kodu少儿编程第八天
  17. 笔记整理英语篇(二) - 日常词汇
  18. 【论文笔记】PassGAN: A Deep Learning Approach for Password Guessing
  19. python玩扫雷_Python玩转算法—扫雷
  20. android 7种网络连接方式--IT蓝豹

热门文章

  1. python处理表格数据-基于Python快速处理PDF表格数据
  2. 编程软件python中的if用法-Python编程工具pycharm的使用
  3. 电脑安装python步骤-windows10系统安装python的详细步骤
  4. python入门到精通需要学多久-Python零基础入门到精通:一个月就够了
  5. 如何自学python爬虫-怎样入门学习Python爬虫?
  6. python怎么画条形图-python使用Matplotlib画条形图
  7. python怎么安装requests库-python怎么安装requests库
  8. python的优缺点有哪些-那么多人选择Python,它的优缺点有哪些?
  9. python一般用什么编译器-Python常用编译器原理及特点解析
  10. 为什么要叫python-为什么要学 Python?