1時に寝て5時半に起きて7時半に起きた。なんか週の前半からバテている。

gitlab ci/cd の dind で mongodb のレプリカセット接続ができない

先日対応した mongodb のレプリカセット対応 で残った最後の課題。ローカルで実行すれば結合テストは動くが、gitlab ci/cd 環境では動作しないという問題が残っていた。gitlab-runner をローカルで実行できる ようにして、設定やパラメーターを変えたり、デバッグコードを埋め込んだり、コンテナに attach して振る舞いを確認したり、いろいろデバッグして原因はレプリカセット接続におけるホスト名の解決がコンテナ間でできていなかったことがわかった。

mongodb の結合テストは dockertest を使って実装している。これを gitlab ci/cd で動かすには dind を有効にする必要がある。dind 環境では2つのコンテナを使って結合テストが実行されるわけだが、テストが実行されるコンテナと mongodb コンテナが起動するコンテナの2つが生成される。このときにテストが実行されるコンテナから実際に mongodb が起動するコンテナのホスト名の解決と、mongodb が起動するコンテナ上での自分のホスト名の解決の2つが成立していないとレプリカセット接続ができない。要は1台のローカルホスト上で結合テストを実行するのと、2つのコンテナ上で実行されるのでは設定を変更する必要があるということに気付いた。

具体的には dockertest の次のパラメーターを、実行環境から解決するホスト名を考慮して設定すればよいと気付いた。

pool.RunWithOptions(&dockertest.RunOptions{
    ... 
    Hostname:   executor,
    Env: []string{
        ...
        fmt.Sprintf("MONGODB_ADVERTISED_HOSTNAME=%s", executor),
        ...
    }
})

たったこれだけの修正だし、現状の動作の振る舞いが分かればすぐに直せるものではあるけれど、このデバッグにはまた2-3時間を費やした。mongodb のレプリカセット接続はなかなか大変。