2014年4月29日火曜日

Golang Cafe #27を開催しました。

Golang Cafe #27を開催しました。

今回も前回に引き続き、Dockerのソースコードを読み進めました。

前回は、クライアントでのコマンド実行のところまで読んだので、今回は、docker runコマンドの実行部分を読んでみました。

該当の場所は、api/client/command.goの1776行目にある、

func (cli *DockerCli) CmdRun(args ...string) error {

からとなります。

処理の概要は

  1. コマンドの解析(ParseSubCommand)
  2. ContainerIDFileが存在しなければ、ContainerIDFileを生成する。
    1. ただし、ホストの設定(hostConfig)で指定されている場合のみ。
    2. ContainerIDFileは最後に削除する。
  3. cli.call("POST", "/containers/create?")で、デーモン側にコンテナの作成を指示。
    1. ファイルがない(httpのレスポンスが404の時)時は、コンテナImageがないので、imageを作成を指示する。(これも、cli.call())
  4. コンテナの作成の結果を受け取る。
  5. コンテナにattach(cli.hijack("/containers/"+runResult.Get("Id")+"/attach?"))
  6. コンテナの開始(cli.call("/containers/"+runResult.Get("Id")+"/start"))
  7. 結果を取得
結局クライアントからはデーモンに向かってプロセス通信しているだけで、何も処理がありませんでしたので、デーモン側の処理を読むことで、コンテナの配置とか、処理の実行の部分の理解を深めることができそうです。

デーモンはいつ起動させるのか?
Ubuntuだと、サービスとしてPC起動時に起動してしまうようです。また、Macだと、boot2dockerを使ってサービスを起動させた状態で使っています。
Windowsだとどうやら無理みたいですw(中身をみると、syscallをバリバリ使っているので、Windowsとは相性が悪そうです…。)

さて、細かい処理を(複雑で時間がかかるので)見ていないのですが、処理の概要は読めました。

今回のポイントですが、プロセス通信をする時に中身では、httpを使っています。
標準パッケージのnet/http/httputilを使って、http通信をしていました。

httputil.ClientConnを使ったリクエストを行う場合、net.Connを自分で指定させるため、Socketを自分で作ります。今回は、Unixドメインソケットだったり、tcpソケットだったりするわけです。(Macだと-Hオプションで指定したURL(私の環境だとtcp://localhost:[Port])を使ってソケットを生成されるようです)

よく考えると、これまでnet/http周りはじっくり読むということをしていなかったので、またのタイミングで読みたいと思います。

ということで、次回はデーモン側のソースコードを読む予定です。

2014年4月26日土曜日

Golang Cafe #26を開催しました。

Golang Cafe #26を開催しました。

今回からdockerソースコードを読み進めることになりましたので、”当然”main()から読み進めるのが妥当だろうということでmain()が書かれているdocker/docker.goから読み始めました。

流れとしては、最初に".dockerinit"という文字列が含まれているとinit modeでの起動ということで、sysinit.Sysinit()が呼び出されます。パスに".dockerinit"が含まれる時ということなので、docker自身が隠しディレクトリを作る事があるのだと思いますが、sysinitは少し重たそうだったので、少しだけ見て、先に進むことにしました。sysinitパッケージは後日に回します。

dockerは引数、オプションを扱うflagパッケージを自作しているようで、別名でflagパッケージを定義してありました。

flag "github.com/dotcloud/docker/pkg/mflag"

使っている所をみると、オプションを配列で指定することができるようにしてあるだけのようにも見えますが、とりあえずは最初の起動の処理をみるということにして、flagも存在だけのチェックで終わっています。

それぞれの引数がどのような意味なのかは、mflagパッケージを読む時にじっくり見たいと思います。デフォルトコメントが書かれているので、そこから判断して頂いてもいいかと思います。

処理の流れとしては、


  1. versionフラグがtrueの時、version情報を出力して終了
  2. Hosts(?)の長さが0(指定されていない時)に環境変数DOCKER_HOSTを取得
    1. DOCKER_HOSTが未定義または、Daemonとして動作する時はデフォルトのUnixSocketを保持する。
      1. ちなみに、デフォルトのUnixSocketのパスは/var/run/docker.sockなので、Macだと存在しないと怒られて動作しないので、-HオプションでSocketを指定する。
  3. -bと--bipオプションが両方指定してあるとエラーになる。
  4. -Dか--debugオプションが指定してある場合は、環境変数DEBUGを1にする。
  5. -dか--daemonオプションが指定されているとDaemonモードで動作する。
    1. ※こちらは今回読んでいないので、中身はまだわかりません。
  6. 指定されていない場合は、clientモード(docker run XXXとかで動かすモード)の処理
    1. TLSを使うかどうかのチェック
    2. client.NewDockerCli()を呼び出し、clientオブジェクトを取得
      1. TLSを使うかどうかの違いは最後の引数がnilか、configが指定してあるかの違い。
    3. ParseCommands()でコマンドの解析とサブコマンドの実行が行われる。
      1. 解析だけかと思ったら実行もされていた。
今回のポイントとして、Unused Importsを使ったパッケージの初期化処理が便利だということと、strings.SplitN()を使って、最大N個までの分割で済ませるというAPIがあることが、新たな発見でした。

特に、Unused Importsはsql/driverあたりでも使われるのですが、その時は、interfaceのみだから、interfaceを認識させるために使うと思っていましたが、init()関数が呼び出されることで、ドライバの初期化ができるというのは、初期化処理の呼び出しをいちいち書かなくても良いという点でいい発見でした。(使う時があるかどうかは別にして…)

次回はdockerのサブコマンドである、apiパッケージを読み進めたいと思います。
新たな発見が出るかな?




2014年4月19日土曜日

Golang Cafe #25を開催しました。

Golang Cafe #25を開催しました。

今回は、初めての方の参加があり、Goが初めてということだったので、+Ryuji Iwataさんにお願いして、#1の時にやった、「How to Write Go Code」の内容を説明して頂きました。
私と+Takanobu Haginoさんはずっとやっていますので、改めて話を聞く必要はありませんでしたが、無茶ぶり以外のなにものでもなかったことは確かでした。
(本来は私がやるのですが、復習というのも兼ねて別の方に頼むのもいいのかなとも思いましたので。)

で、今回のGolang Cafe #25では、私は特に成果物がありませんでしたので、少しだけ考えた、「Golang Cafeの今後」についてまとめてみたいと思います。

今回で25回開催してきたのですが、1回目から欠かさず続けているという事は、正直すごいと思うのですが、その状況での問題点がちらほらでてくるわけです。
ずっと参加して頂いている2人に関してはGoのノウハウが蓄積されてきて、それぞれの熟練度もある程度上がってきました。

ここからは恐らく…ですが、例えば、コードを書いて動かしたい人と、いろんな資料を読み、ノウハウを蓄積したい人、公式ドキュメントとか、書籍を読みたい人といういろいろ「やりたいこと」がわかれてくるのだろうと思っています。

Golang Cafe自体、「ネタ」ですから、私一人でもやるのですが、独断で決めてもいいのですが、せっかく集まってくれているので、ある程度、希望に沿ったものにしたいなーと考えたりもしました。

それから、仕事が詰まって忙しくなるとかで、参加者が変化する(入れ替わりが発生する)かと思ったのですが、入れ替わることもなく、増えることもなかったので、今の状態なったのかもしれません。

今のところのテンションだと、「終了」はまだまだ先になりそうですが、
個人的な野望としては、「Golang Cafeの並列化」が実現するとおもしろいなと思っています。ですが、今のところ、私以外にGolang Cafeを開催する人はいませんね。

あとは、いつGoがプロダクションで使われ、金に繋がるか。
それまではがんばってみようかと思ってたりしてます。

2014年4月8日火曜日

Golang Cafe #24を開催しました。

Golang Cafe #24を開催しました。今回は、Devfest Japan 2014 Springのなかの1トラックでの開催となりました。

40分しかなかったのと、参加者のGoを使っている度合いをつかむことが難しかったので、当日も参加して頂いた、+Takanobu Haginoさんに協力していただきまして、ある程度使っている人とGolang Cafeをやってもらいました。

私は、というと、初心者の方が多かったので、Goの導入と簡単なプログラムの書き方(Golang Cafe #1に至る直前までの内容)を自由に話してみました。
導入とか、実行方法などをお話してみましたので、今後ハマったら質問など投げて見て下さい。

Golang Cafe自体が、自由だったので、Devfestでやることか?とも思いましたが、「Golang Cafeへの幻想をぶち壊す!」的なノリで、好き勝手にやってみることにしましたw

中身は、「雑談」と、「質問への回答」が主なので、力をいれずやるのが良いのかなと思っています。

で、参加して頂いた方にもGolang Cafeがどんなものかは、十分わかったと思いますので、ご自由に開催して下さい。

某所で、このGolang Cafeのイベント情報を共有したいという意見(アピールしたいという意味で)も上がってきたのですが、できれば、GDG中国にあるGolang Cafeのサイトに誘導して頂く方が、私はうれしいです。
ですが、性質上たくさんの人が申し込まれると、場所の確保と内容に制限が出てくるので、難しいところです。

次回からは、また倉式珈琲店での開催となります。多分、出張はもうありませんw

Devfest Japan 2014 Spring

Devfest Japan 2014 Springに主催者側で参加してきました。

今回は、各地のGDGオーガナイザー達が集結して、いろんなプロダクトのセッションを担当するという感じでした。

全体では、セッションのトラックとハンズオンのトラックの2つに分かれての構成で、
私は、Google Apps Scriptと、Goを担当しました。

本来は、90分ぐらいかけて、しっかりやりたかったのですが、運営上の都合で、両方共40分でのハンズオンとなってしまいました。

Goの方はこの後別の記事で書くので、ここでは、Google Apps Scriptのセッションについて書いてみたいと思います。

当日の資料は、http://goo.gl/ccI5j1で、「Google Apps ScriptでYouTubeを検索する」というタイトルで、見て頂ければ分かる通り、40分で収まる内容ではありませんでした。
(当日も、言われましたがw)

ですが、チューターとして参加して頂いた、+Keisuke Oohashiさん、+Atusi Nakamuraさん、+Yoshifumi YAMAGUCHIさんの3人のすばらしいサポートと、参加者の方のポテンシャルに助けられまして、大半の方が、YouTubeの検索とメール通知ができるようになっていました。本当に大成功でした。チューターの方、ありがとうございました。
(後は、京都でGoogle Apps Scriptが流行るかどうか)

後で話を聞くと、コピペ駆動で動かしたということでしたが、ハマりポイントもうまくフォローされたようで、良かったです。

最終的にできたソースコードは20行程度ですが、Google Apps Scriptだとそれだけで、かなりのことができるようになっています。
大規模なプロジェクトには合わないと思いますが、小規模なものなら便利に使えると思います。

それから、Google Apps Scriptのハンズオンが申し込み時点では一番多いという結果になり、運が良かったなと思っています。

また、今後、Google Apps Scriptのイベントでお会いしましょう!

2014年4月6日日曜日

Golang Cafe #23を開催しました。

Golang Cafe #23を開催しました。

ソースコードは、githubにありますので、そちらを御覧ください。

今回も、「OAuthライブラリをリファクタリングする。」というテーマで、
進めました。

実際、Goに関する新しい事は特にないのですが、私が進めたのは、以下の点に留意して進めました。


  • 繰り返しをしない
  • テストコードを書く

で、最初のライブラリは、文字列の連結部分がコピペで行われているので、その処理をまとめる。ということにしました。

そこで、ファイルの分割をし、テストコードを追加している最中に時間が来てしまったので、終了となりました。

で、参考になるかどうかはわかりませんが、今回のOAuthだとNonceの生成や、Timestampの設定で、ランダムな値を生成しなければならないので、その辺りのテストを
どうしているかなどは、参考になるかもしれません。

次回は、京都でDevfestの1トラックで行いますので、奮ってご参加下さい。
(ただ、後1時間少々で始まりますが!)