あらまし
環境構築をVagrantのchef−soloからknife-soloに変更したところ、一部のファイルが実行側の環境に転送されていないためにchefがコケる事案が発生。
chef-soloに戻すと完走するのだが、knife-soloにするとコケるということでknife-soloのソースコードを追いかけて調査してみた。
環境
- VirtualBox (4.3.10)
- Vagrant (1.6.2)
- CentOS (6.5)
- knife-solo (0.4.2)
調査
今回転送されなかったのはディレクトリで以下の様な配置になっていた。
- cookbook/templates/tmp/hoge.txt.erb
tamplatesディレクトリに中には他のテンプレートファイルもあったのだが、こちらは無事に転送されていることから、VM側にファイルを送っているまわりが怪しいということで、knife-soloのソースを適当に漁る。
ソースを眺めていると、knifeがcookbookなどをuploadするためにrsyncしている部分が見つかったので多分この辺だろうと探してみたらexcludeしている箇所を発見。
- rsyncをしている箇所のコード:lib/chef/knife/solo_cook.rb#L259
def rsync(source_path, target_path, extra_opts = '--delete-after')
if config[:ssh_gateway]
ssh_command = "ssh -TA #{config[:ssh_gateway]} ssh -T -o StrictHostKeyChecking=no #{ssh_args}"
else
ssh_command = "ssh #{ssh_args}"
end
cmd = ['rsync', '-rL', rsync_debug, rsync_permissions, %Q{--rsh=#{ssh_command}}, extra_opts]
cmd += rsync_excludes.map { |ignore| "--exclude=#{ignore}" }
cmd << adjust_rsync_path_on_client(source_path)
cmd << %Q{:#{adjust_rsync_path_on_node(target_path)}}
cmd = cmd.flatten.compact
Chef::Log.debug cmd.inspect
system!(*cmd)
end
rsync_excludesで検索してみると、該当のメソッドを発見。
コードを見るとどうやらgitとかsubversionなどのVCS関連のディレクトリと、tmpと言う名前が付けられたものはrsyncから除外されるらしい。
- 該当のコード箇所:lib/chef/knife/solo_cook.rb#L195
def rsync_excludes
(%w{revision-deploys tmp .git .hg .svn .bzr} + chefignore.ignores).uniq
end
ちなみにrsyncコマンドの--excludeオプションを調べると、excludeで指定されるものはパターンらしい。
--exclude=PATTERN
パターンに一致するファイルをコピーしない。
よって今回転送されなかった以下のディレクトリにはrsync_excludesで指定されているtmpが含まれているため転送されなかった模様。
- cookbook/templates/tmp/hoge.txt.erb
まとめ
わかったこと
- knife-soloではcookbook_pathやrole_pathなどで指定されたディレクトリがrsyncコマンドでchef-soloの実行対象サーバに転送される
- rsyncで転送される際にオプションとして"--exclude=tmp"が渡されている
- rsyncの"--exclude=pattern"はpatternにマッチするものを転送しない
- よってknife-soloで転送する対象の中でtmpと名前の付いているディレクトリ(並びにその直下のファイル)やファイルは転送されない
結論
ようするにknife-soloでrsyncする対象のディレクトリ内にtmpディレクトリを作るなということらしい。