summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/chef/mixin/windows_architecture_helper.rb48
-rw-r--r--lib/chef/provider/script.rb9
-rw-r--r--lib/chef/provider/windows_script.rb41
-rw-r--r--lib/chef/resource/batch.rb5
-rw-r--r--lib/chef/resource/powershell.rb7
-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