From 63d34bb7887606ee5d55ad70264ff14a90aa3f09 Mon Sep 17 00:00:00 2001 From: adamedx Date: Fri, 25 Jan 2013 16:33:43 -0800 Subject: OC-4739: OC-4748: Create powershell and batch providers in core Chef --- lib/chef/exceptions.rb | 4 +- lib/chef/mixin/windows_architecture_helper.rb | 47 +++++++++++++++++++ lib/chef/provider/batch.rb | 35 ++++++++++++++ lib/chef/provider/powershell.rb | 35 ++++++++++++++ lib/chef/provider/script.rb | 16 ++++++- lib/chef/provider/windows_script.rb | 48 +++++++++++++++++++ lib/chef/providers.rb | 2 + lib/chef/resource/batch.rb | 32 +++++++++++++ lib/chef/resource/powershell.rb | 32 +++++++++++++ lib/chef/resource/windows_system_script.rb | 66 +++++++++++++++++++++++++++ lib/chef/resources.rb | 2 + 11 files changed, 317 insertions(+), 2 deletions(-) create mode 100644 lib/chef/mixin/windows_architecture_helper.rb create mode 100644 lib/chef/provider/batch.rb create mode 100644 lib/chef/provider/powershell.rb create mode 100644 lib/chef/provider/windows_script.rb create mode 100644 lib/chef/resource/batch.rb create mode 100644 lib/chef/resource/powershell.rb create mode 100644 lib/chef/resource/windows_system_script.rb (limited to 'lib') diff --git a/lib/chef/exceptions.rb b/lib/chef/exceptions.rb index c8654d7801..783a640654 100644 --- a/lib/chef/exceptions.rb +++ b/lib/chef/exceptions.rb @@ -97,6 +97,8 @@ class Chef # Attempting to run windows code on a not-windows node class Win32NotWindows < RuntimeError; end class WindowsNotAdmin < RuntimeError; end + # Attempting to access a 64-bit only resource on a 32-bit Windows system + class Win32ArchitectureIncorrect < RuntimeError; end class ObsoleteDependencySyntax < ArgumentError; end class InvalidDataBagPath < ArgumentError; end @@ -131,7 +133,7 @@ class Chef class StaleAttributeRead < StandardError; end #Registry Helper throws the following errors - class Win32RegArchitectureIncorrect < RuntimeError; end + class Win32RegArchitectureIncorrect < Win32ArchitectureIncorrect; end class Win32RegHiveMissing < ArgumentError; end class Win32RegKeyMissing < RuntimeError; end class Win32RegValueMissing < RuntimeError; end diff --git a/lib/chef/mixin/windows_architecture_helper.rb b/lib/chef/mixin/windows_architecture_helper.rb new file mode 100644 index 0000000000..7744c20b5f --- /dev/null +++ b/lib/chef/mixin/windows_architecture_helper.rb @@ -0,0 +1,47 @@ +# +# Author:: Adam Edwards () +# 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 'chef/exceptions' + +class Chef + module Mixin + module WindowsArchitectureHelper + + def node_windows_architecture(node) + node[:kernel][:machine].to_sym + 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 + end + + def valid_windows_architecture?(architecture) + return (architecture == :x86_64) || (architecture == :i386) + end + + def assert_valid_windows_architecture!(architecture) + if ! valid_windows_architecture?(architecture) + raise Chef::Exceptions::Win32ArchitectureIncorrect, + "The specified architecture was not valid. It must be one of :i386 or :x86_64" + end + end + + end + end +end diff --git a/lib/chef/provider/batch.rb b/lib/chef/provider/batch.rb new file mode 100644 index 0000000000..e4b35b64f3 --- /dev/null +++ b/lib/chef/provider/batch.rb @@ -0,0 +1,35 @@ +# +# Author:: Adam Edwards () +# 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 'chef/provider/windows_script' + +class Chef + class Provider + class Batch < Chef::Provider::WindowsScript + + def initialize (new_resource, run_context) + super(new_resource, run_context, '.bat') + end + + def flags + @new_resource.flags.nil? ? '/c' : new_resource.flags + ' /c' + end + + end + end +end diff --git a/lib/chef/provider/powershell.rb b/lib/chef/provider/powershell.rb new file mode 100644 index 0000000000..2ae7552197 --- /dev/null +++ b/lib/chef/provider/powershell.rb @@ -0,0 +1,35 @@ +# +# Author:: Adam Edwards () +# 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 'chef/provider/windows_script' + +class Chef + class Provider + class Powershell < Chef::Provider::WindowsScript + + def initialize (new_resource, run_context) + super(new_resource, run_context, '.ps1') + end + + def flags + @new_resource.flags.nil? ? '-ExecutionPolicy RemoteSigned -Command' : new_resource.flags + '-ExecutionPolicy RemoteSigned -Commmand' + end + + end + end +end diff --git a/lib/chef/provider/script.rb b/lib/chef/provider/script.rb index 9e5a7d7fe1..5c3d2ebb33 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("\"#{@new_resource.interpreter}\" #{@new_resource.flags} \"#{script_file.path}\"") + @new_resource.command("\"#{interpreter}\" #{flags} \"#{interpreter_script_path}\"") super converge_by(nil) do # ensure script is unlinked at end of converge! @@ -52,6 +52,20 @@ class Chef @script_file && @script_file.close! end + def interpreter + @new_resource.interpreter + end + + 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 new file mode 100644 index 0000000000..0dfd4d81b3 --- /dev/null +++ b/lib/chef/provider/windows_script.rb @@ -0,0 +1,48 @@ +# +# Author:: Adam Edwards () +# 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 'chef/provider/script' + +class Chef + class Provider + class WindowsScript < Chef::Provider::Script + + def initialize( new_resource, run_context, script_extension='') + super( new_resource, run_context ) + @script_extension = script_extension + end + + def flags + @new_resource.flags + end + + protected + + def script_file + base_script_name = "chef-script" + temp_file_arguments = [ base_script_name, @script_extension ] + + @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/providers.rb b/lib/chef/providers.rb index be3f487ca3..ae95632eaa 100644 --- a/lib/chef/providers.rb +++ b/lib/chef/providers.rb @@ -16,6 +16,7 @@ # limitations under the License. # +require 'chef/provider/batch' require 'chef/provider/breakpoint' require 'chef/provider/cookbook_file' require 'chef/provider/cron' @@ -36,6 +37,7 @@ require 'chef/provider/ohai' require 'chef/provider/mdadm' require 'chef/provider/mount' require 'chef/provider/package' +require 'chef/provider/powershell' require 'chef/provider/remote_directory' require 'chef/provider/remote_file' require 'chef/provider/route' diff --git a/lib/chef/resource/batch.rb b/lib/chef/resource/batch.rb new file mode 100644 index 0000000000..b44489c549 --- /dev/null +++ b/lib/chef/resource/batch.rb @@ -0,0 +1,32 @@ +# +# Author:: Adam Edwards () +# 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 'chef/resource/windows_system_script' +require 'chef/mixin/windows_architecture_helper' + +class Chef + class Resource + class Batch < Chef::Resource::WindowsSystemScript + + def initialize(name, run_context=nil) + super(name, run_context, :batch, "cmd.exe") + end + + end + end +end diff --git a/lib/chef/resource/powershell.rb b/lib/chef/resource/powershell.rb new file mode 100644 index 0000000000..35474a1af9 --- /dev/null +++ b/lib/chef/resource/powershell.rb @@ -0,0 +1,32 @@ +# +# Author:: Adam Edwards () +# 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 'chef/resource/script' +require 'chef/mixin/windows_architecture_helper' + +class Chef + class Resource + class Powershell < Chef::Resource::WindowsSystemScript + + def initialize(name, run_context=nil) + super(name, run_context, :powershell, "WindowsPowerShell\\v1.0\\powershell.exe") + end + + end + end +end diff --git a/lib/chef/resource/windows_system_script.rb b/lib/chef/resource/windows_system_script.rb new file mode 100644 index 0000000000..1bc618aea1 --- /dev/null +++ b/lib/chef/resource/windows_system_script.rb @@ -0,0 +1,66 @@ +# +# Author:: Adam Edwards () +# 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 'chef/resource/script' +require 'chef/mixin/windows_architecture_helper' + +class Chef + class Resource + class WindowsSystemScript < Chef::Resource::Script + include Chef::Mixin::WindowsArchitectureHelper + + def architecture(arg=nil) + assert_architecture_compatible!(arg) if ! arg.nil? + result = set_or_return( + :architecture, + arg, + :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)}'" + end + end + + end + end +end diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb index 6dea46bfc9..1b295fc4e1 100644 --- a/lib/chef/resources.rb +++ b/lib/chef/resources.rb @@ -18,6 +18,7 @@ require 'chef/resource/apt_package' require 'chef/resource/bash' +require 'chef/resource/batch' require 'chef/resource/breakpoint' require 'chef/resource/cookbook_file' require 'chef/resource/chef_gem' @@ -49,6 +50,7 @@ require 'chef/resource/package' require 'chef/resource/pacman_package' require 'chef/resource/perl' require 'chef/resource/portage_package' +require 'chef/resource/powershell' require 'chef/resource/python' require 'chef/resource/registry_key' require 'chef/resource/remote_directory' -- cgit v1.2.1