読者です 読者をやめる 読者になる 読者になる

chef で remote_directory リソースで一気にファイルをコピーしようとしたら空ディレクトリがコピーされなくて困った件(解決策もあるよ)

仕事では vagrant + chef を使って Hermetic なテスト環境を誰でも簡単に作れるようにしようという取り組みをしています。

モバイルアプリからアクセスするバックエンドのサーバは、現時点では本番環境かテスト環境かというくらいしかないのですが、これを vagrant と chef で誰でもローカルの仮想マシン上にセットアップできるようにしちゃおうという目論見です。

バックエンドサーバのコードは自社製のレガシーなものがすでにありますので、まずはそれをデプロイしたいなと。
chef のリポジトリの site-cookbooks/<cookbook-name>/files/default/ あたりにそのバックエンドサーバの実行に必要なファイル一式を用意しておいて、まるっと仮想マシンにコピーしたいわけです。

で、chef のリソースについてのドキュメントなんかを読むと、どうやら remote_directory というリソースを使えば cookbook に入れておいたファイルたちをディレクトリごとまるっとコピーしてくれるようだということがわかります。

そこで早速使ってみたのですが、一つ問題に気づいてしまいました。

空っぽのディレクトリが仮想マシン側の環境にコピーされていないのです。

ログを出すためのディレクトリとか、ユーザからのアップロードを受け付けるためのディレクトリだとかそんな感じのディレクトリの一つや二つ、ありますよね?
そういう空のディレクトリが cookbook の files の下にあっても、仮想マシン側にはそれがコピー(作成)されないのです。

一つや二つなら、実行時にどうせ作られるし別に気にしないのですが、今回いじってるサーバはちょっとわけあって100個くらいそういう空のディレクトリがあります。
しかも、本番環境やテスト環境と差分がないことを diff とったりして確認したいので、100個も差分があると本当の差分が埋もれてしまって困ることになります。

で、解決策がここにありました。
https://github.com/higanworks-cookbooks/mongodb-10gen/issues/3

やはり同じ事で困っている人はいるみたいです。


解決策を大雑把に説明すると、コピー元の cookbook の files の下の空ディレクトリになんでもいいからダミーの空ファイルを入れておけということのようです。

私の場合は

find ${COOKBOOK_FILES_DEFAULT_DIR} -type d -empty -exec touch {}/delete.me \;

という感じで一括して delete.me という名前のファイルを空ディレクトリの中に作成しました。

で、レシピには、

execute 'delete delete.me files' do
  command "find #{dst_dir} -name 'delete.me' -exec rm {} \\;"             
end

こんな感じのコードを書いておくと knife solo cook したときに delete.me が消えてなくなります。