動かしながら、ということで。tutorial は以下を使ってみます。
今、手元にある docker が
$ docker --version
Docker version 0.11.1, build fb99f99
とのことなので v1.1.0 なタグを checkout しています。
とりあえず
以下なコマンドが内部でどう評価されるのかを確認してみます。
$ docker run base /bin/echo hi
これ、最初は CLI モード (?) で動くのか。とりあえず ParseCommands が呼ばれて
if err := cli.ParseCommands(flag.Args()...); err != nil {
てのは分かります。おそらく flag.Args() は run base /bin/echo hi なリストか何かだろうというのも類推ベースでアレ。ParseCommands は api/client/cli.go で
methodName := "Cmd" + strings.ToUpper(name[:1]) + strings.ToLower(name[1:])
method := reflect.ValueOf(cli).MethodByName(methodName)
みたいなことしてます。確かに api/client/commands.go に定義されてるメソドは CmdRun とかって名前になってます。なんとなくな理解で言うと
- reflect.ValueOf(cli) が cli オブジェクトの Value なオブジェクトを取り出して
- リフレクション値の共通 interface である Value interface から名前で手続きオブジェクトを取り出す
という事で良いのかどうか。しかしこのあたりのヤッツケ方はなかなかアレゲです。
CmdRun
長い。とは言えざっくり把握できてるのかどうか。ともあれ以下なあたりがアレ、
//create the container
stream, statusCode, err := cli.call("POST", "/containers/create?"+containerValues.Encode(), config, false)
call は api/client/utils.go で定義されている模様。これ、POST なリクエストを、なのはなんとなく分かるのですが、どこでこのリクエストを受ける人は動きはじめてるのか、が微妙。
とりあえず
以下な
resp, err := cli.HTTPClient().Do(req)
cli.HTTPClient() が何をしてるのか、なのかどうか。定義は同じく api/client/utils.go で以下とのこと。
func (cli *DockerCli) HTTPClient() *http.Client {
tr := &http.Transport{
TLSClientConfig: cli.tlsConfig,
Dial: func(network, addr string) (net.Conn, error) {
return net.Dial(cli.proto, cli.addr)
},
}
return &http.Client{Transport: tr}
}
サーバ起動してる風ではないですね。つうか Do って何だろ。
Do
sync パッケージの Once 型に Do というメソドがあるんですが req は func() なのかどうかがアレ。req は http.NewRequest の戻りなのか。ええと、NewRequset の定義によれば (utils/http.go) 戻りは http.Request とあります。
あら、でも戻すソレを先頭で
req, err := http.NewRequest(method, urlStr, body)
てしてるな。何だこれ。よく見てみるに net/http というソレを import してますね。Package http によると
- http.Client な client を作って
- http.NewRequest して req を作って
- client.Do(req) する
というのは golang てきに通常の HTTP request の投げ方な模様。
むむむ
結局、一発目の CLI の発行で daemon がどう起動するのかが分からん。ちょっと勘違いしてるかも、なので諸々確認入れてみます。
そもそも CLI な API を受けとってるのがどこなのか、を理解しないとアレ。