summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--spec/functional/resource/batch_spec.rb29
-rw-r--r--spec/functional/resource/powershell_spec.rb31
-rw-r--r--spec/support/shared/functional/windows_script_resource.rb65
-rw-r--r--spec/support/shared/unit/windows_script_resource.rb (renamed from spec/support/shared/unit/windows_system_script_resource.rb)10
-rw-r--r--spec/unit/provider/powershell_spec.rb2
-rw-r--r--spec/unit/resource/batch_spec.rb4
-rw-r--r--spec/unit/resource/powershell_spec.rb4
13 files changed, 235 insertions, 60 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
diff --git a/spec/functional/resource/batch_spec.rb b/spec/functional/resource/batch_spec.rb
new file mode 100644
index 0000000000..3c73ff2e65
--- /dev/null
+++ b/spec/functional/resource/batch_spec.rb
@@ -0,0 +1,29 @@
+#
+# Author:: Adam Edwards (<adamed@opscode.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'spec_helper'
+
+describe Chef::Resource::WindowsScript::Batch, :windows_only do
+ let(:script_content) { "whoami" }
+
+ let!(:resource) do
+ Chef::Resource::WindowsScript::Batch.new("Batch resource functional test", run_context)
+ end
+
+ it_behaves_like "a functional Windows script resource"
+end
diff --git a/spec/functional/resource/powershell_spec.rb b/spec/functional/resource/powershell_spec.rb
new file mode 100644
index 0000000000..410f41f442
--- /dev/null
+++ b/spec/functional/resource/powershell_spec.rb
@@ -0,0 +1,31 @@
+#
+# Author:: Adam Edwards (<adamed@opscode.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'spec_helper'
+
+describe Chef::Resource::WindowsScript::Powershell, :windows_only do
+ let(:script_content) { "whoami" }
+
+ let!(:resource) do
+ r = Chef::Resource::WindowsScript::Powershell.new("Powershell resource functional test", run_context)
+ r.code(script_content)
+ r
+ end
+
+ it_behaves_like "a functional Windows script resource"
+end
diff --git a/spec/support/shared/functional/windows_script_resource.rb b/spec/support/shared/functional/windows_script_resource.rb
new file mode 100644
index 0000000000..8bc15313b7
--- /dev/null
+++ b/spec/support/shared/functional/windows_script_resource.rb
@@ -0,0 +1,65 @@
+#
+# Author:: Adam Edwards (<adamed@opscode.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'spec_helper'
+
+shared_context Chef::Resource::WindowsScript do
+ let(:ohai) do
+ ohai_reader = Ohai::System.new
+ ohai_reader.require_plugin("os")
+ ohai_reader.require_plugin("windows::platform")
+ ohai_reader
+ end
+
+ let(:node) do
+ new_node = Chef::Node.new
+ new_node.consume_external_attrs(ohai.data,{})
+ new_node
+ end
+
+ let(:run_context) do
+ events = Chef::EventDispatch::Dispatcher.new
+
+ run_context = Chef::RunContext.new(node, {}, events)
+ end
+
+ let(:script_output_path) do
+ File.join(Dir.tmpdir, make_tmpname("windows_script_test"))
+ end
+
+ before(:each) do
+k File.delete(script_output_path) if File.exists?(script_output_path)
+ end
+
+ after(:each) do
+ File.delete(script_output_path) if File.exists?(script_output_path)
+ end
+end
+
+describe Chef::Resource::WindowsScript, :windows_only do
+ shared_examples_for "a functional Windows script resource", :windows_only do
+ include_context Chef::Resource::WindowsScript
+ context "when a Windows script resource run action is invoked " do
+ it "executes the script code" do
+ resource.code(script_content + " > #{script_output_path}")
+ resource.returns(0)
+ resource.run_action(:run)
+ end
+ end
+ end
+end
diff --git a/spec/support/shared/unit/windows_system_script_resource.rb b/spec/support/shared/unit/windows_script_resource.rb
index 75d7933209..0a0079a287 100644
--- a/spec/support/shared/unit/windows_system_script_resource.rb
+++ b/spec/support/shared/unit/windows_script_resource.rb
@@ -21,7 +21,7 @@ require 'spec_helper'
require 'support/shared/unit/execute_resource'
require 'support/shared/unit/script_resource'
-shared_examples_for "a Windows system script resource" do
+shared_examples_for "a Windows script resource" do
before(:each) do
node = Chef::Node.new
@@ -34,15 +34,11 @@ shared_examples_for "a Windows system script resource" do
end
- it "should be a kind of Chef::Resource::WindowsSystemScript" do
+ it "should be a kind of Chef::Resource::WindowsScript" do
@resource.should be_a_kind_of(Chef::Resource)
- @resource.should be_a_kind_of(Chef::Resource::WindowsSystemScript)
+ @resource.should be_a_kind_of(Chef::Resource::WindowsScript)
end
- it "should have an interpreter with a file name of cmd.exe" do
- @resource.interpreter.split('\\').pop.casecmp(interpreter_file_name).should == 0
- end
-
context "script" do
let(:script_resource) { resource_instance }
it_should_behave_like "a script resource"
diff --git a/spec/unit/provider/powershell_spec.rb b/spec/unit/provider/powershell_spec.rb
index fc973a686a..038de47742 100644
--- a/spec/unit/provider/powershell_spec.rb
+++ b/spec/unit/provider/powershell_spec.rb
@@ -27,8 +27,6 @@ describe Chef::Provider::Powershell, "action_run" do
@run_context = Chef::RunContext.new(@node, {}, @events)
@new_resource = Chef::Resource::Powershell.new('run some powershell code', @run_context)
-# @new_resource.code "$| = 1; print 'i like beans'"
-# @new_resource.interpreter 'perl'
@provider = Chef::Provider::Powershell.new(@new_resource, @run_context)
end
diff --git a/spec/unit/resource/batch_spec.rb b/spec/unit/resource/batch_spec.rb
index 119b0dd5f1..91b840908e 100644
--- a/spec/unit/resource/batch_spec.rb
+++ b/spec/unit/resource/batch_spec.rb
@@ -36,13 +36,13 @@ describe Chef::Resource::Batch do
@resource.should be_a_kind_of(Chef::Resource::Batch)
end
- context "windowssystemscript" do
+ context "windows script" do
let(:resource_instance) { @resource }
let(:resource_instance_name ) { @resource.command }
let(:resource_name) { :batch }
let(:interpreter_file_name) { 'cmd.exe' }
- it_should_behave_like "a Windows system script resource"
+ it_should_behave_like "a Windows script resource"
end
end
diff --git a/spec/unit/resource/powershell_spec.rb b/spec/unit/resource/powershell_spec.rb
index c6650f4daa..22d5b5371b 100644
--- a/spec/unit/resource/powershell_spec.rb
+++ b/spec/unit/resource/powershell_spec.rb
@@ -36,13 +36,13 @@ describe Chef::Resource::Powershell do
@resource.should be_a_kind_of(Chef::Resource::Powershell)
end
- context "windowssystemscript" do
+ context "windowsscript" do
let(:resource_instance) { @resource }
let(:resource_instance_name ) { @resource.command }
let(:resource_name) { :powershell }
let(:interpreter_file_name) { 'powershell.exe' }
- it_should_behave_like "a Windows system script resource"
+ it_should_behave_like "a Windows script resource"
end
end