詳細
execute と script と bashの違いを知るためにオープンソースのコードリーディングをする
※他の言語系リソースもbash resourceと同様です(Csh, Ruby, Python, Perl)
About Resource
Resourceの継承関係
Bash extends Script extends Execute の継承関係になっている
pry(main)> Chef::Resource::Bash.ancestors => [Chef::Resource::Bash, Chef::Resource::Script, Chef::Resource::Execute, : 略 Kernel, BasicObject] pry(main)> Chef::Resource::Script.ancestors => [Chef::Resource::Script, Chef::Resource::Execute, Chef::Resource, : 略 Kernel, BasicObject] pry(main)> Chef::Resource::Execute.ancestors => [Chef::Resource::Execute, Chef::Resource, : 略 Kernel, BasicObject]
Script Resource実装の詳細
Executeを継承して、code・interpreter・flags属性と設定用のメソッドを追加しただけ。
About Provider
Providerの継承関係
リソース同様Script extends Execute の継承関係になっている
pry(main)> Chef::Provider::Script.ancestors => [Chef::Provider::Script, Chef::Provider::Execute, Chef::Mixin::ShellOut, Chef::Provider, : 略 Kernel, BasicObject] pry(main)> Chef::Provider::Execute.ancestors => [Chef::Provider::Execute, Chef::Mixin::ShellOut, Chef::Provider, : 略 Kernel, BasicObject]
Execute Provider実装の詳細
Mixlib::ShellOutのインスタンスを取得してrun_commandメソッドを実行している。
Mixlib::ShellOutについては以下。
https://github.com/opscode/mixlib-shellout/blob/master/lib/mixlib/shellout.rb
Mixlib::ShellOut内ではプラットフォームに応じて
'mixlib/shellout/windowsをrequire
ShellOut::WindowsかShellOut::Unixをinclude
を選ぶか
'mixlib/shellout/unix'をrequire
ShellOut::Unixをinclude
を選ぶか決めている。
ShellOut::Windows、ShellOut::Unixについては以下。
https://github.com/opscode/mixlib-shellout/blob/master/lib/mixlib/shellout/unix.rb
https://github.com/opscode/mixlib-shellout/blob/master/lib/mixlib/shellout/windows.rb
unixなら最終的にRubyのexec経由でコマンドを実行している。
command.kind_of?(Array) ? exec(*command) : exec(command)
をしている。
windowsなら最終的に
cmd /c "command"
をしている。
Script Provider実装の詳細
コマンドを一時ファイルに保存。
一時ファイルを利用するコマンドを設定。
その後はexecuteの処理をそのまま呼び出し。
コードリーディングの流れ
・それっぽいキーワードでgrepして該当処理を書いてありそうなコードを探し当てる
・chef配下のソースを確認する流れで、resourceとprovider配下のexecute.rb, script.rb, bash.rbなどのファイルを発見しソースを確認
・executeのソースの中でChef::Mixin::ShellOutの呼び出しを確認。該当コードを開く。
こちらもモジュール構成とディレクトリ構成がわかりやすくすぐコードを発見。
・Chef::Mixin::ShellOutからMixlib::ShellOutを呼んでいるが内部にソースが見当たらない。
ググったらGitHubを発見。
・Mixlib::ShellOutからMixlib::ShellOut::Unix,Mixlib::ShellOut::Windowsを呼び出していることを確認。
さらにGitHub内でそれらのコードを参照する。
今回コードリーディングした関連クラス群
chef/resource/execute.rb
chef/resource/script.rb
chef/resource/bash.rb
chef/provider/script.rb
chef/provider/execute.rb
chef/mixin/shell_out.rb
https://github.com/opscode/mixlib-shellout/blob/master/lib/mixlib/shellout.rb
https://github.com/opscode/mixlib-shellout/blob/master/lib/mixlib/shellout/unix.rb
https://github.com/opscode/mixlib-shellout/blob/master/lib/mixlib/shellout/windows.rb