之前看过一遍docker的代码,但比较粗略。第二遍准备详细过一遍并且用博客的方式将其 整理一下。目前为止docker的稳定版本为1.4.1,所以就以此版本的代码为基础进行阅读,分 析。

本篇内容

一个大项目的源码阅读当然是从主程序入口开始最好, 一步一步,结合实际程序进行测试分 析。 本来准备一起介绍相关环境设置以及源码中关于启动部分的,但前者内容较多,所以 单列一篇进行介绍。

源码编译 docker

构建

ubuntudocker源有 1.4.1 版本的 docker,可以直接用来与代码进行对照测试。但是能 自己手动编译一遍还是很有好处的。docker 官网上关于开发环境设置的博客 (Setting Up a Dev Environment) ,里面已经讲的很清楚了,下面仅作简要描述,详细内容请参考官方文档。

首先看一下 docker 源码的目录结构 :

下面有一个makefile文件和一个Dockerfile。直接执行make,会根据Dockerfile创 建镜像,里面包含特定版本的golang(由源码编译)以及其他编译 docker 所需的依赖,当前目录的 docker 源码也会被整个拷贝进镜像里用于编译。最后根据生成的镜像创建container用于实际的 编译并生成可执行程序。注意最后生成的可执行程序是位于container内部的,所以如果 要使用所编译的程序,应该使用如下命令 :

 sudo make binary

最终生成的程序位于./bundles/<version>-dev/binary/,如果没有看到这些文件,一般都 是因为BINDDIR环境变量有问题,此时可以执行如下命令 :

 sudo make BINDDIR=. binary

可以用生成的程序替换系统程序来方便测试 :

 sudo service docker stop ; sudo cp $(which docker) $(which docker)_ ; sudo cp ./bundles/<version>-dev/binary/docker-<version>-dev $(which docker);sudo service docker start

注意事项

  1. 第一次构建过程会很长,因为需要从源码构建golang,llvm以及 clone 一些依赖项目。后续再 次构建时会复用之前生成的中间镜像,所以会很快。

  2. 在墙内的话,一般第一次编译都会失败,因为有两个所需的网站被墙。。。第一个是 golang的下载网站,这个很好解决,因为有好多网站对它做了镜像。docker v1.4.1 所 用的 golang 版本为 1.3.3,Dockerfile 中可以看到文件名 :

     RUN     curl -sSL https://golang.org/dl/go1.3.3.src.tar.gz | tar -v -C /usr/local -xz
    

    在谷歌用 Index of 搜索此文件 :

     "Index of" go1.3.3.src.tar.gz
    

    找一个可用的网站替换 Dockerfile 中的 URL 即可,下面是一个可用的 : http://pkgs.fedoraproject.org/repo/pkgs/golang/go1.3.3.src.tar.gz/2cdbad6baefcf1007f3cf54a5bc878b7/go1.3.3.src.tar.gz

    另一个被墙的便是golang.org,解决办法是从 github 上从 github 上下载其 fork 版本,并且用软连接或者直接拷贝到相应目录即可。具体步骤是 :

    • Dockerfile 构建镜像会有好多中间镜像,找到最后成功构建的那一个,用其创建一个 container来进行操作

    • 从 github 上下载相关项目。我自己 fork 了一个,可以直接使用 https://github.com/hangyan/golang.org

    • 做 link 或者 copy :

        mkdir -p /go/src/golang.org/ && ln -sf
        /go/src/github.com/hangyan/golang.org/x /go/src/golang.org/x
      
    • 提交镜像,修改 Dockerfile,将其作为新的 baseimage。中间已经成功的很多步骤也可以删掉 了。

  3. Dockerfile 中将GOPATH 设了两个目录,如下所示 :

     ENV     GOPATH  /go:/go/src/github.com/docker/docker/vendor
    

    原因是由于 docker 依赖项目较多,所以大部分依赖都已经在 vendor目录下提供,编 译时将其设为GOPATH即可使用。

开发环境

IDE

刚开始用golang的时候,好多 IDE 还在初级阶段,缺少很多必须的功能,所以就一直用 Emacs 了。IDE 基本不用配置,上手简单,嫌麻烦的可以直接使用。下面是一个常用 IDE 的列表及链接。

  • LiteIDE : sourceforge.

    感觉界面不好看。

  • Zeus IDE : zeus

    windows 上的,没用过.

  • Go IDE : go-ide

    基于 Intellij IDEA 做的一个 IDE,功能比较简单。

  • Golang Komodo : Komodo

    是一个 Komodo 平台的插件。

Emacs

有很多关于 Golang 的插件可以使用,下面是我在使用的一些插件及配置 :

go-mode

除了基本的语法高亮及自动对齐之外,还提供了如下功能 :

  • gofmt 集成,保存时自动排版代码

  • godoc 集成,

  • import 管理

  • godef 代码跳转

    依赖code.google.com/p/rog-go/exp/cmd/godef项目,依旧被墙。可以从 github 上 fork 的项目来 build,地址为godef

  • flymake 集成,实施检查代码语法错误。

Emacs 配置示例:

 (require 'go-mode)
 (add-hook 'before-save-hook 'gofmt-before-save)

gocode

提供代码自动补全功能,依赖于autocompletecompany。这个项目在 github 上的 star 数已经超过 2000,可见其流行程度。其主页上已经有关于 Emacs 的 配置,此处不再详述。

xcscope

xcscope 可以作为godef的一个补充项,它可以将一个目录下的代码包含的 symbols 和文件 建成一个索引数据库,然后从其中查询。原生的 xcscope 并不支持 go 语言,需要修改其索引 脚本。我现在使用的脚本链接为 cscope-indexer

ecb

浏览代码神器,可以自己定制各窗口大小,内容 :

helm

Emacs 原生M-x增强工具,功能极多,还可以用来浏览当前文件的代码结构及跳转到相应函数或变量定 义。

主要的插件就这几个,如果有兴趣,可以参考我的 Emacs 配置 : Emacs