【git】社内のChefリポジトリをgit subtreeで利用する
はじめに
こんにちは植木和樹です。クラスメソッドではOSやミドルウェアの設定にchef(chef-solo)を頻繁に利用しています。chefを利用するようになって約1年。その間に多くの(本当に!)プロジェクトの構築を行ってきました。
多くの構築を経験していると、ある程度のパターンというか定石がでてきます。例えばApacheをインストール/設定するにしても、
- KeepAliveはOnにする
- TimeOutは120秒(かそれ以上)にする
- ELBからのヘルスチェックはアクセスログに記録しない
- 案件ごとに異なる設定は /etc/httpd/conf.d に入れてRoleやNodeで指定できるようにする
などです。
そうなると「クラメソ社内Chefリポジトリの整備が必要だよね〜」という話が当然でてきます。そして大瀧さんや望月さんの努力の結果、いい感じにChefリポジトリが整備されてきました。
本日はクラスメソッド社内向けの資料ですが、もし社内用Chefリポジトリを運用されている方の参考になればと思い公開させていただきました。
git submodule と git subtree
submoduleとsubtreeの違い
「Atlassian Stashで管理しているクラスメソッド社内向け共用Chefリポジトリ」というのは長いので以降「共用リポジトリ」というようにします。
案件ごとのgitリポジトリに、共用リポジトリを取り込むには2つの方法があります。git submoduleを使うかgit subtreeを使うかです。submoduleとsubtreeの違いはいろいろあるようですが、一言でまとめると次のようになります。
- git submodule
- 共用リポジトリ内のファイルを案件リポジトリに取り込まない。(ポインタ管理)
- git subtree
- 共用リポジトリ内のファイルを案件リポジトリに取り込む。(実体管理)
共用リポジトリの使い方として「典型的なテンプレートは共用リポジトリから流用したいけど、案件固有の修正は自由にしたいよね」を考えています。そのためsubmoduleよりもsubtreeの方が適していると考えました。
◎参考
なぜ共用リポジトリもgitで管理したいのか
単に共用リポジトリにあるクックブックを流用するだけなら、適当な場所にcloneしてファイルだけ案件リポジトリにコピーすればいいのではという意見もあるかと思います。
しかし仕掛中の案件で共通化できそうなパターンに気づいたり、元々のテンプレートに修正を行いたい場合などは、コピー方式だとフィードバックが面倒です。改めて共用リポジトリからcloneして、仕掛中案件での差分を抽出し、手マージして、pushしなければならないためです。手順が煩雑だとフィードバックも期待できません。
ということで、効率よく過去の知見をテンプレートとして再利用しつつ、フィードバックもやりやすい git subtreeを使うことにしました。
git subtreeを使ってみる
共用リポジトリを案件リポジトリに取り込む
取り込みは簡単です。git subtree addで対象のリポジトリを、ローカルのサブディレクトリにcloneするだけです。なおgit subtreeコマンドはローカルリポジトリのトップディレクトリ(.gitがあるディレクトリ)でないと実行できませんので注意してください。
大瀧さんがAmazon EC2(Linux)のswap自動作成を行うRPMパッケージ ec2-swap を作ってみた | Developers.IOで紹介したスワップ設定作業をChef Cookbookにして共用リポジトリに入れてくれてます(感謝!)。これを取り込んでみましょう。
$ cd $WORKDIR $ git remote add ec2-swap ssh://git@stash.example.com/awschef/ec2-swap.git $ git subtree add --prefix chef/st-cookbooks/ec2-swap ec2-swap master --squash
まず最初にgit remote addでリモートリポジトリに別名(ec2-swap)をつけます。
次にgit subtree addコマンドでec2-swapリポジトリをchef/st-cookbooks/ec2-swapディレクトリに取り込みました。(--squashをつけ過去の履歴は取り込まないようにしています。)
なおChefリポジトリのディレクトリ構成は以下のようにして区別しています。
- cookbooks
- Berkshelfで取得したコミュニティクックブックの置き場。(変更不可)
- site-cookbooks
- 案件独自に作成したクックブックの置き場。
- st-cookbooks
- git subtreeで取得した共用クックブックの置き場。
knifeの設定ファイルにcookboos_pathを設定するのを忘れないようにしましょう。
.chef/knife.rb
cookbook_path ["cookbooks", "site-cookbooks", "st-cookbooks"]
共用リポジトリのクックブックをsubtreeで取り込んでしまえば、あとは自分で作成したクックブックと違いはありません。改修/改変ご自由に。
共用リポジトリへフィードバックをpushする
共用リポジトリのクックブックに手元の改修をフィードバックしたい時の手順です。クラスメソッドではgitリポジトリにStashを使っているで、別ブランチに変更をpushした後Pullリクエストをリポジトリ担当者に送りましょう。
単純にgit pushしてしまうと、subtreeで取得したディレクトリだけでなく案件リポジトリ全体をpushしてしまうので気をつけましょう。
まずgit subtree splitして、ブランチ(addMemoryUsageCrontab)を切ります。
$ git subtree split --prefix chef/st-cookbooks/hoot24 -b addMemoryUsageCrontab
次にgit subtree pushで共用リポジトリ(hoot24)にブランチを作成してローカルの変更を反映します。
$ git subtree push --prefix chef/st-cookbooks/hoot24 hoot24 addMemoryUsageCrontab
この後Stashの画面からPullリクエストを作成しましょう。
まとめ
gitを使った社内Chefリポジトリの利用方法をご紹介しました。社内の有力者のみなさんがChefクックブックをガシガシ作成してはリポジトリにあげてくれているので、環境構築がだんだんと楽になってます。大変ありがたいです。
ミドルウェアのインストールをChefで行いたい場合は、ひとまずコミュニティクックブックを探して、なければ社内共用リポジトリを探しましょう。それでもなければ自分でクックブックを作成して、共用リポジトリにあげてもらえるとみんなが幸せになれると思います。