之前看过一遍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