docker命令行解析以及如何向服务器端发送请求(docker源码学习一)
最近在看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源码学习一)相关推荐
- Docker命令行探秘
1. Docker命令行 Docker官方为了让用户快速了解Docker,提供了一个交互式教程,旨在帮助用户掌握Docker命令行的使用方法.但是由于Docker技术的快速发展,此交互式教程已经无法满 ...
- 深入浅出Docker(二):Docker命令行探秘
本文原创版权归 infoq 肖德时 所有,此处为技术收藏,如有再转,请于篇头保留原创作者及出处,以示尊重! 作者: 肖德时 原文: http://www.infoq.com/cn/articles/d ...
- linux c 命令行解析 getopt getopt_long optarg optind opterr optopt 简介
目录 getopt 函数 测试代码 getopt_long函数 代码示例 getopt 函数 头文件 #include<unistd.h> 定义函数 int getopt(int argc ...
- python解析库_Python命令行解析库argparse
原博文 2014-08-13 05:48 − 2.7之后python不再对optparse模块进行扩展,python标准库推荐使用argparse模块对命令行进行解析. 1.example 有一道面试 ...
- python:argparse命令行解析模块详解
argparse命令行解析模块学习 import argparse parser = argparse.ArgumentParser() #类似于初始化吧 parser.parse_args() #解 ...
- .NET:命令行解析器介绍
背景 经常需要开发一下小工具,之前都是自己解析命令行参数,接触过动态语言社区以后,发现命令行解析有特定的模式和框架可以利用,本文介绍一个 .NET 平台的类库. 示例 需求 拷贝文件,如:CopyFi ...
- python之命令行解析工具argparse
以前写python的时候都会自己在文件开头写一个usgae函数,用来加上各种注释,给用这个脚本的人提供帮助文档. 今天才知道原来python已经有一个自带的命令行解析工具argparse,用了一下,效 ...
- Python命令行解析:sys.argv[]函数的简介、案例应用之详细攻略
Python命令行解析:sys.argv[]函数的简介.案例应用之详细攻略 目录 sys.argv[]函数的简介 sys.argv[]函数的案例应用 1.基础测试 2.进阶用法 3.sys.argv[ ...
- TF之TF flags:TF flags(命令行解析)的简介、安装、使用方法之详细攻略
TF之TF flags:TF flags(命令行解析)的简介.安装.使用方法之详细攻略 目录 TF flags的简介 TF flags的安装 TF flags的使用方法 TF flags的简介 1.f ...
最新文章
- android实现计算器功能吗,利用Android实现一个简单的计算器功能
- excel中日期设置星期
- vue 微信支付的坑_vue_模式下h5微信支付
- java并发编程-----深入剖析ThreadLocal
- Java编程学习中必须掌握的13个核心技术
- 基于Vitual Box建立虚拟机,虚拟机系统为Linux Ubuntu16.04
- java get https_JAVA – 使用SSL证书和HTTPS的简单GET请求
- Android Sqlite数据库操作
- github使用介绍
- UVM:factory 机制
- GitHub 上最火的开源项目 —— Java 篇
- 面向光栅薄膜光学性能探究的Rsoft建模与仿真
- 晚上几点睡才叫“熬夜”?给你“答案”,很多人都想错了
- go,go语言编辑器安装,git安装,即vscode三个插件的安装
- 前后端分离之图片上传服务端处理方法(亲测通过)
- 社群的使用---Kodu少儿编程第八天
- 笔记整理英语篇(二) - 日常词汇
- 【论文笔记】PassGAN: A Deep Learning Approach for Password Guessing
- python玩扫雷_Python玩转算法—扫雷
- android 7种网络连接方式--IT蓝豹
热门文章
- python处理表格数据-基于Python快速处理PDF表格数据
- 编程软件python中的if用法-Python编程工具pycharm的使用
- 电脑安装python步骤-windows10系统安装python的详细步骤
- python入门到精通需要学多久-Python零基础入门到精通:一个月就够了
- 如何自学python爬虫-怎样入门学习Python爬虫?
- python怎么画条形图-python使用Matplotlib画条形图
- python怎么安装requests库-python怎么安装requests库
- python的优缺点有哪些-那么多人选择Python,它的优缺点有哪些?
- python一般用什么编译器-Python常用编译器原理及特点解析
- 为什么要叫python-为什么要学 Python?