/var/log/study

つまり雑記

git remote がhttpsでbasic認証している時の自動化方法

前提となる話

gitのリモートには git://https:// が使える。要はsshhttpsかという違いで、諸事情によりsshを利用せずhttpsを使いたい場面がある。

sshならばパスフレーズのないdeploy keyなどを用意したら、あとはキーの取り回しをどうしたら良いか?で事が済むが、httpsかつ認証が必要なリモートリポジトリを扱う際はパスワードを入力する必要が出て来る。

httpsを利用した際の認証はbasic認証なので、 git clone をする際に認証情報を埋めたら自動化できるのだが、git remote -v で認証情報が丸見えとなる。(と言うか、自分の作った環境を先輩に見せたら丸見えの状態で非常に恥ずかしかった) ので、以下のURLで示されている方法は得策ではない。

stackoverflow.com

.netrc を利用するといちいちパスワードを入力する必要も無い。しかし通常は平文、チョット気を使うと暗号化できたりするが、何れにせよユーザーとパスワードを保存した状態となるので、様々な人が触るサーバーで .netrc を使うのは得策と言えないだろう。

加えてスクリプトから扱う専用のユーザーをリモートリポジトリのサーバーに作りたくない。リモートリポジトリ側のユーザー管理が雑になる可能性があるので、極力普段使っているユーザーの認証情報で済ませたい。

ではansibleやjenkinsなどの自動化ツールを使った際に認証付きhttpsリポジトリを扱うのはどうしたら良いか?という点に話を移すと、対話が必要なときは expect コマンドなどで頑張るのが回答の候補に上がるだろう。個人的には expect とか泥臭すぎると思うのでその方法は避けたい。

ということで今回は以下の前提で話を進める

  1. httpsかつ認証付きのリモートリポジトリ
  2. 様々な人が触る環境なので、ユーザーに紐づく状態を作りたくないという
  3. 自動化用のユーザーは作らない
  4. expectは使わない

git credential helper

環境変数経由で渡せるとansibleとかjenkinsで簡単に自動化ができるなぁと思いながら、gitを調べていたら credential helper なるものが有るのを発見した。

Git - 認証情報の保存

使いかたとか設定方法は大体上記に書いてある。

git config --global credential.helper cache

と設定すると、ファイルには設定を保存せず、ある程度の時間認証情報を保持してくれるようになるとのこと。

加えて以下を実行すると認証情報が渡せるとのこと。

git credential fill

惜しい。なにが惜しいか?というと、さらっと調べる限り、標準入力等では git credential fill に情報を渡すことはできなさそう?だった。

自動化方法

Git - 認証情報の保存 には 独自の認証情報キャッシュ という項目がある。

サクッと読むと git hook と同じように、独自コマンドを利用することが可能らしい。サンプルに乗っているRubyをパクって、環境変数を渡すようにしたら良さげ。

ということで、以下のようなスクリプトを実行権限付きで、 /usr/local/bin/git-credential-env とかで設置し、 git config --global credential.helper env とかすると、環境変数経由で認証情報を渡せるようになる。

gist.github.com

あとは、ansibleのenvironmentやjenkinsのパラメーター付きビルドで GIT_PROTOCOL, GIT_REMOTE_HOST, GIT_USER, GIT_PASSWORD を指定してやるといい感じに自動化できる。

スクリプトデバッグは以下で。

GIT_PROTOCOL=https GIT_REMOTE_HOST=github.com GIT_USER=hoge GIT_PASSWORD=fuga ./git-credential-env.sh get
protocol=https
host=github.com
username=hoge
password=fuga

注意点

  • スクリプトshebangは環境によって適度に変えてください。
  • 環境によってはcredential.helperを既に設定している可能性があるので、むやみに上書きしないように。