diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/chef/mixin/windows_architecture_helper.rb | 48 | ||||
| -rw-r--r-- | lib/chef/provider/script.rb | 9 | ||||
| -rw-r--r-- | lib/chef/provider/windows_script.rb | 41 | ||||
| -rw-r--r-- | lib/chef/resource/batch.rb | 5 | ||||
| -rw-r--r-- | lib/chef/resource/powershell.rb | 7 | ||||
| -rw-r--r-- | lib/chef/resource/windows_script.rb (renamed from lib/chef/resource/windows_system_script.rb) | 40 |
6 files changed, 103 insertions, 47 deletions
diff --git a/lib/chef/mixin/windows_architecture_helper.rb b/lib/chef/mixin/windows_architecture_helper.rb index 7744c20b5f..38c08e236d 100644 --- a/lib/chef/mixin/windows_architecture_helper.rb +++ b/lib/chef/mixin/windows_architecture_helper.rb @@ -16,7 +16,9 @@ # limitations under the License. # -require 'chef/exceptions' + +require 'chef/exceptions' +require 'win32/api' if Chef::Platform.windows? class Chef module Mixin @@ -26,9 +28,16 @@ class Chef node[:kernel][:machine].to_sym end + def wow64_architecture_override_required?(node, desired_architecture) + is_i386_windows_process? && + node_windows_architecture(node) == :x86_64 && + desired_architecture == :x86_64 + end + def node_supports_windows_architecture?(node, desired_architecture) assert_valid_windows_architecture!(desired_architecture) - return (node_windows_architecture(node) == :x86_64 || desired_architecture == :i386) ? true : false + return (node_windows_architecture(node) == :x86_64 || + desired_architecture == :i386) ? true : false end def valid_windows_architecture?(architecture) @@ -41,6 +50,41 @@ class Chef "The specified architecture was not valid. It must be one of :i386 or :x86_64" end end + + def is_i386_windows_process? + Chef::Platform.windows? && 'X86'.casecmp(ENV['PROCESSOR_ARCHITECTURE']) == 0 + end + + def disable_wow64_file_redirection( node ) + original_redirection_state = ['0'].pack('P') + + if ( ( node_windows_architecture(node) == :x86_64) && ::Chef::Platform.windows?) + win32_wow_64_disable_wow_64_fs_redirection = + ::Win32::API.new('Wow64DisableWow64FsRedirection', 'P', 'L', 'kernel32') + + succeeded = win32_wow_64_disable_wow_64_fs_redirection.call(original_redirection_state) + + if succeeded == 0 + raise Win32APIError "Failed to disable Wow64 file redirection" + end + + end + + original_redirection_state + end + + def restore_wow64_file_redirection( node, original_redirection_state ) + if ( (node_windows_architecture(node) == :x86_64) && ::Chef::Platform.windows?) + win32_wow_64_revert_wow_64_fs_redirection = + ::Win32::API.new('Wow64RevertWow64FsRedirection', 'P', 'L', 'kernel32') + + succeeded = win32_wow_64_revert_wow_64_fs_redirection.call(original_redirection_state) + + if succeeded == 0 + raise Win32APIError "Failed to revert Wow64 file redirection" + end + end + end end end diff --git a/lib/chef/provider/script.rb b/lib/chef/provider/script.rb index 4d405e59f1..f1b765d52a 100644 --- a/lib/chef/provider/script.rb +++ b/lib/chef/provider/script.rb @@ -29,7 +29,7 @@ class Chef set_owner_and_group - @new_resource.command("\"#{interpreter}\" #{flags} \"#{interpreter_script_path}\"") + @new_resource.command("\"#{interpreter}\" #{flags} \"#{script_file.path}\"") super converge_by(nil) do # ensure script is unlinked at end of converge! @@ -59,13 +59,6 @@ class Chef def flags @new_resource.flags end - - protected - - def interpreter_script_path - script_file.path - end - end end end diff --git a/lib/chef/provider/windows_script.rb b/lib/chef/provider/windows_script.rb index 94ffa1d3be..398e1aee6e 100644 --- a/lib/chef/provider/windows_script.rb +++ b/lib/chef/provider/windows_script.rb @@ -17,21 +17,50 @@ # require 'chef/provider/script' +require 'chef/mixin/windows_architecture_helper' class Chef class Provider class WindowsScript < Chef::Provider::Script + protected + + include Chef::Mixin::WindowsArchitectureHelper + def initialize( new_resource, run_context, script_extension='') super( new_resource, run_context ) @script_extension = script_extension + + target_architecture = new_resource.architecture.nil? ? + node_windows_architecture(run_context.node) : new_resource.architecture + + @is_wow64 = wow64_architecture_override_required?(run_context.node, target_architecture) + + if ( target_architecture == :i386 ) && ! is_i386_windows_process? + raise Chef::Exceptions::Win32ArchitectureIncorrect, + "Support for the i386 architecture from a 64-bit Ruby runtime is not yet implemented" + end end - def flags - @new_resource.flags - end + public + + def action_run + wow64_redirection_state = nil - protected + if @is_wow64 + wow64_redirection_state = disable_wow64_file_redirection(@run_context.node) + end + + begin + super + rescue + raise + ensure + if ! wow64_redirection_state.nil? + restore_wow64_file_redirection(@run_context.node, wow64_redirection_state) + end + end + end def script_file base_script_name = "chef-script" @@ -39,10 +68,6 @@ class Chef @script_file ||= Tempfile.open(temp_file_arguments) end - - def interpreter_script_path - script_file.path.gsub(::File::SEPARATOR) { | replace | ::File::ALT_SEPARATOR } - end end end end diff --git a/lib/chef/resource/batch.rb b/lib/chef/resource/batch.rb index b44489c549..705260bbce 100644 --- a/lib/chef/resource/batch.rb +++ b/lib/chef/resource/batch.rb @@ -16,12 +16,11 @@ # limitations under the License. # -require 'chef/resource/windows_system_script' -require 'chef/mixin/windows_architecture_helper' +require 'chef/resource/windows_script' class Chef class Resource - class Batch < Chef::Resource::WindowsSystemScript + class Batch < Chef::Resource::WindowsScript def initialize(name, run_context=nil) super(name, run_context, :batch, "cmd.exe") diff --git a/lib/chef/resource/powershell.rb b/lib/chef/resource/powershell.rb index 35474a1af9..e726e6f35a 100644 --- a/lib/chef/resource/powershell.rb +++ b/lib/chef/resource/powershell.rb @@ -16,15 +16,14 @@ # limitations under the License. # -require 'chef/resource/script' -require 'chef/mixin/windows_architecture_helper' +require 'chef/resource/windows_script' class Chef class Resource - class Powershell < Chef::Resource::WindowsSystemScript + class Powershell < Chef::Resource::WindowsScript def initialize(name, run_context=nil) - super(name, run_context, :powershell, "WindowsPowerShell\\v1.0\\powershell.exe") + super(name, run_context, :powershell, "powershell.exe") end end diff --git a/lib/chef/resource/windows_system_script.rb b/lib/chef/resource/windows_script.rb index 1bc618aea1..e210985e47 100644 --- a/lib/chef/resource/windows_system_script.rb +++ b/lib/chef/resource/windows_script.rb @@ -21,9 +21,20 @@ require 'chef/mixin/windows_architecture_helper' class Chef class Resource - class WindowsSystemScript < Chef::Resource::Script + class WindowsScript < Chef::Resource::Script + + protected + + def initialize(name, run_context=nil, resource_name, interpreter_command) + super(name, run_context) + @interpreter = interpreter_command + @resource_name = resource_name + end + include Chef::Mixin::WindowsArchitectureHelper + public + def architecture(arg=nil) assert_architecture_compatible!(arg) if ! arg.nil? result = set_or_return( @@ -32,34 +43,19 @@ class Chef :kind_of => Symbol ) end - - def interpreter - target_architecture = architecture.nil? ? node_windows_architecture(node) : architecture - path_prefix = (target_architecture == :x86_64) ? INTERPRETER_64_BIT_PATH_PREFIX : INTERPRETER_32_BIT_PATH_PREFIX - interpreter_path = "#{path_prefix}\\#{@interpreter_relative_path}" - end - INTERPRETER_64_BIT_PATH_PREFIX = "#{ENV['systemroot']}\\sysnative" - INTERPRETER_32_BIT_PATH_PREFIX = "#{ENV['systemroot']}\\system32" - - def initialize(name, run_context=nil, resource_name, interpreter_relative_path) - super(name, run_context) - @resource_name = resource_name - @interpreter_relative_path = interpreter_relative_path - init_arch = node_windows_architecture(node) - end - protected - def node - run_context && run_context.node - end - def assert_architecture_compatible!(desired_architecture) if ! node_supports_windows_architecture?(node, desired_architecture) - raise Chef::Exceptions::Win32ArchitectureIncorrect, "cannot execute script with requested architecture '#{desired_architecture.to_s}' on a system with architecture '#{node_windows_architecture(node)}'" + raise Chef::Exceptions::Win32ArchitectureIncorrect, + "cannot execute script with requested architecture '#{desired_architecture.to_s}' on a system with architecture '#{node_windows_architecture(node)}'" end end + + def node + run_context && run_context.node + end end end |
