Golang Cafe #26 まとめ Dockerのソースコードを読む。その1

2014/04/20に開催された「Golang Cafe #26」についてのまとめです。
今回からはDockerソースコードを読んでいきます。
そこそこの量があるので何回かかるか分かりません。
またソースコードを読んでいくのでまとめ方も難しく、全体的な流れではなく各ポイントで気になって点た技術についてまとめておく形になるかもしれませんのであしからず。


エントリーポイントは/docker/docker.go:main()になります。

実行ファイルパスに.dockerinitが含まれている(.dockerinitとして実行された)場合は、/docker/sysinit/sysinit.go:SysInit()が呼び出されたあとにsyscall.Execで実行されます。
SysInit()では使用されるドライバによって初期化処理(環境変数の設定、ネットワークの設定、ユーザーの設定等々・・・)が行われています。


実行時引数の処理をした後、デーモンとして起動するのかそれ以外の場合かで処理が分かれます。


デーモン以外の場合は、/api/client/cli.go:NewDockerCli()でDockerCli型が作成され、
実行時の引数(runやbuildなど)をもとにリフレクションを使用して/api/client/commands.goに定義されているメソッドが実行される仕組みになっているようです。


とりあえず今回はここまでです。

学んだ実装

匿名インポート(?)と初期化処理

あるパッケージにinit関数を定義しておき、そのパッケージを"_"(アンダースコア)を付けて呼び出せばinit関数だけが実行されます。

// ./sub/sub.go
package sub

import (
    "fmt"
)

func init() {
    fmt.Println("sub.init")
}
// ./main.go
package main

import (
    "fmt"

    _ "./sub"
)

func init() {
    fmt.Println("main.init")
}

func main() {
    fmt.Println("main")
}
$ go run main.go
sub.init
main.init
main
strings.SplitN

key=valueフォーマットのような文字列を分割したい時に、以下のコードにあるように文字列中にセパレータ文字が複数個存在している場合、単純にstrings.Splitしてしまうと値まで分割されてしまいます。
strings.SplitNを使用すれば最大分割個数を指定できるので、最大分割個数を2にしておけばkeyの部分とそれ以外に分割することができます。多言語の用にインディックスを取得して・・・のような処理が不要です。

package main

import (
    "fmt"
    "strings"
)

func main() {
    s := "key=BAKO$=%$aAkoju2"

    fmt.Println(strings.Split(s, "="))
    fmt.Println(strings.SplitN(s, "=", 2))
}
$ go run main.go
[key BAKO$ %$aAkoju2]
[key BAKO$=%$aAkoju2]

まとめと参照

今回はDockerの入り口だけソースコードを読みましたが、もう少しDockerの全体像や仕組みを理解してから読み進めるほうがいいような気がしてきました。
http://2013.8-p.info/japanese/06-22-docker.html