rbenv はインストールユーザーの環境変数をセットしないと動きません。 後々、execute Resource で rbenv コマンドを実行するときに、インストールユーザーの環境変数を適用するために sudo が必要になります。 sudo を実行するときに、そのままでは tty を要求されて sudo が失敗してしまうので、ruby_block Resource で tty 要求をしないように設定しています。 sudo の設定は /etc/sudoers の 'Defaults requiretty' という行をコメントアウトすれば OK です。 Chef ではファイルの一部を編集するライブラリ Chef::Util::FileEdit が提供されています。 search_file_replace_line メソッドを使えば、第1引数の正規表現に一致する行を第2引数の文字列に置換できるので、 これらを利用して 'Defaults requiretty' をコメントアウトしています。 最後に write_file メソッドを実行して、ファイルの編集を適用します。 次の項目で sudo を使ってインストールユーザの環境変数をロードしますが、その実行タイミングは recipe のコンパイル時です。 なので ruby_block Resource が収束する前に実行され失敗してしまいます。 そこで run_action メソッドを使って ruby_block Resource を recipe のコンパイル時に実行しています。 Resourceはクラスとして定義されていて、ruby_block Resource も Chef::Resource::RubyBlock というクラスです。 その親クラスである Chef::Resource クラスのメソッドとして run_action メソッドは定義されています。 .run_action(:run) なしの場合 ruby_block 'disable requiretty' do
block {
Chef::Util::FileEdit.new('/etc/sudoers').tap { |file|
file.write_file if file.search_file_replace_line(/^Defaults[ \t]+requiretty/, '#Defaults requiretty')
}
}
action :run
end |

Mixlib::ShellOut の run_command はコンパイル時に実行されます。 ruby_block はまだ収束されていないので、sudo は失敗します。 .run_action(:run) ありの場合 ruby_block 'disable requiretty' do
block {
Chef::Util::FileEdit.new('/etc/sudoers').tap { |file|
file.write_file if file.search_file_replace_line(/^Defaults[ \t]+requiretty/, '#Defaults requiretty')
}
}
action :nothing
end.run_action(:run)
cmd_prefix = "sudo -iu #{node[cookbook_name]['user']}" |

正確には収束時も ruby_block は評価されていますが、action Attribute が :noting なので実行はされません |
sudo を使うコマンドはこのあと何回も出てくるので、変数化しておきます |
|