jgit で s3 にプライベートリポジトリ(IAM編)


この投稿は Git Advent Calendar 2014の 10日目の記事です。
昨日は kyanro@github さんの githubとgoogleを利用して世界征服の意図を調べる でした。
明日は @a-suenami さんです。
社内に git サーバがあったりしてデプロイするときに git pull できずに rsync を使っていたりする全国の皆様こんにちは。rsyncだとデプロイ先で緊急修正したときや試行錯誤したあとにgitリポジトリに書き戻すのが大変だったりしませんか? EC2 でリポジトリサーバたてられればいいけど EC2 のインスタンスはそれだけに使うにはちょっと高い。せめて s3 にリポジトリがおけたら……

できます。 git ではなく jgit です。git を java で実装した jgit というプロジェクトがあります*1
その中に jgit.sh という linux のシェルをくっつけて単体で実行できるようにしたファイルが有り、こいつを wget して chmod すれば*2 ./jgit.sh とコマンドラインから叩くだけで jgit を動かすことができます。

で、jgit.sh の何が嬉しいかというと AWS の S3 にリポジトリが置けることです。AWS CodeCommit を待たなくてもS3の容量価格だけでプライベートリポジトリをもてる!

詳しくは
http://www.fancybeans.com/blog/2012/08/24/how-to-use-s3-as-a-private-git-repository/
http://d.hatena.ne.jp/winebarrel/20120425/p1

jgit.sh の実装はいろいろと中途半端なのですが*3、データベースファイルは普通のgitと同じなので、 clone push fetch の時だけjgit使うようにするのもありです。

が、素の jgit だと AWS の Instance profile credential いわゆる IAM-ROLE が使えないので、使えるようにしました。副作用で STS の token も使えるようになっています。

https://github.com/team-lab/jgit/wiki

s3 の権限を ROLE で割り当てた EC2 から

wget https://github.com/team-lab/jgit/releases/download/v3.6.0.201411121045-token4-env4/jgit -O jgit
chmod oug+x jgit
git remote add s3 amazon-s3://IAM@backet-name/repo/dir.git
./jgit push s3

のようにすると s3 の backet-name バケットに push できます(jgitだと認証情報ファイル名を指定する URL のユーザ名部分に、キーワード 'IAM' を指定してください)。

ご利用ください。

とはいえ S3 はファイルロックができないので競合するときっと大変なことになると思います。s3 に push するのは管理サーバや社内 jenkins からだけにして ec2 では fetch のみがよいかと思います。EC2 側には書き込み権限をおかずに、インスタンス上で直接編集したらそれを直接社内 git サーバに push したい場合、ポートフォワードを設定しておくとできます。

# 社内http-gitサーバ git-server.syanai.local の 80 番をec2 (syagai.ec2.example.com)に持っていく 
ssh -R 10080:git-server.syanai.local:80 ec2-user@syagai.ec2.example.com
cd /opt/dir.git
# push の際のリモートを社内(=ポートフォワードのポート)に向ける
git remote set-url --push origin http://localhost:10080/git/dir.git
git commit
git push 

じゃあはじめからポートフォワードで git fetch すればよいのかというとそうでもなくてオートスケールなどしたときに困ることになるので s3 においておくのがいいんじゃないでしょうか。

OpsWorks など他のgit連携サービスから s3 においたリポジトリにアクセスさせるには、s3 の該当バケットを http website として公開して、 http プロトコルのgitリポジトリとして指定してください。

明日のこのブログでは chef から s3 のリポジトリを fetch するレシピを紹介します*4

*1:それのeclipseプラグインが EGIT

*2:あとjavaがインストールされていれば

*3:たとえば pull ができないので fetch merge する必要がある

*4:Git Advent Calendar ではなく Chef Advent Calendar になります……