chef 11.12.0.alpha.1 → 11.12.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/chef/api_client/registration.rb +46 -9
- data/lib/chef/application.rb +1 -0
- data/lib/chef/application/client.rb +25 -24
- data/lib/chef/client.rb +34 -0
- data/lib/chef/config.rb +11 -0
- data/lib/chef/cookbook/chefignore.rb +10 -2
- data/lib/chef/cookbook/metadata.rb +31 -3
- data/lib/chef/cookbook/synchronizer.rb +2 -2
- data/lib/chef/cookbook/syntax_check.rb +4 -4
- data/lib/chef/encrypted_data_bag_item.rb +37 -1
- data/lib/chef/exceptions.rb +1 -0
- data/lib/chef/guard_interpreter/default_guard_interpreter.rb +42 -0
- data/lib/chef/guard_interpreter/resource_guard_interpreter.rb +122 -0
- data/lib/chef/http.rb +0 -1
- data/lib/chef/http/decompressor.rb +7 -4
- data/lib/chef/http/simple.rb +5 -0
- data/lib/chef/http/validate_content_length.rb +28 -12
- data/lib/chef/knife.rb +1 -0
- data/lib/chef/knife/client_bulk_delete.rb +48 -9
- data/lib/chef/knife/client_delete.rb +4 -4
- data/lib/chef/knife/cookbook_bulk_delete.rb +1 -1
- data/lib/chef/knife/cookbook_upload.rb +17 -7
- data/lib/chef/knife/core/bootstrap_context.rb +1 -1
- data/lib/chef/knife/core/ui.rb +42 -5
- data/lib/chef/knife/node_run_list_add.rb +31 -2
- data/lib/chef/knife/ssh.rb +44 -31
- data/lib/chef/knife/ssl_check.rb +213 -0
- data/lib/chef/knife/ssl_fetch.rb +145 -0
- data/lib/chef/mixin/deep_merge.rb +13 -5
- data/lib/chef/mixin/shell_out.rb +9 -3
- data/lib/chef/node.rb +23 -4
- data/lib/chef/node/immutable_collections.rb +32 -0
- data/lib/chef/platform/provider_mapping.rb +21 -18
- data/lib/chef/platform/query_helpers.rb +10 -2
- data/lib/chef/policy_builder/expand_node_object.rb +3 -6
- data/lib/chef/provider/cron.rb +25 -3
- data/lib/chef/provider/mount/mount.rb +1 -1
- data/lib/chef/provider/package/dpkg.rb +2 -1
- data/lib/chef/provider/package/windows.rb +80 -0
- data/lib/chef/provider/package/windows/msi.rb +69 -0
- data/lib/chef/provider/powershell_script.rb +19 -6
- data/lib/chef/provider/service/solaris.rb +11 -7
- data/lib/chef/resource.rb +18 -5
- data/lib/chef/resource/conditional.rb +20 -7
- data/lib/chef/resource/cron.rb +18 -2
- data/lib/chef/resource/execute.rb +0 -2
- data/lib/chef/resource/powershell_script.rb +23 -1
- data/lib/chef/resource/script.rb +25 -0
- data/lib/chef/resource/subversion.rb +4 -0
- data/lib/chef/resource/windows_package.rb +79 -0
- data/lib/chef/resource/windows_script.rb +0 -5
- data/lib/chef/resources.rb +1 -0
- data/lib/chef/rest.rb +6 -1
- data/lib/chef/run_context.rb +22 -2
- data/lib/chef/run_context/cookbook_compiler.rb +12 -0
- data/lib/chef/util/editor.rb +92 -0
- data/lib/chef/util/file_edit.rb +22 -54
- data/lib/chef/version.rb +2 -2
- data/lib/chef/win32/api/installer.rb +166 -0
- data/lib/chef/win32/version.rb +8 -0
- data/spec/data/standalone_cookbook/Gemfile +1 -0
- data/spec/data/standalone_cookbook/chefignore +9 -0
- data/spec/data/standalone_cookbook/recipes/default.rb +3 -0
- data/spec/data/standalone_cookbook/vendor/bundle/ruby/2.0.0/gems/multi_json-1.9.0/lib/multi_json.rb +1 -0
- data/spec/functional/resource/powershell_spec.rb +262 -1
- data/spec/functional/win32/versions_spec.rb +3 -3
- data/spec/integration/knife/chefignore_spec.rb +1 -2
- data/spec/integration/knife/raw_spec.rb +8 -13
- data/spec/integration/knife/redirection_spec.rb +6 -14
- data/spec/integration/solo/solo_spec.rb +19 -0
- data/spec/support/shared/functional/windows_script.rb +1 -1
- data/spec/support/shared/integration/app_server_support.rb +42 -0
- data/spec/support/shared/integration/integration_helper.rb +1 -0
- data/spec/support/shared/unit/script_resource.rb +38 -0
- data/spec/unit/api_client/registration_spec.rb +109 -38
- data/spec/unit/application/client_spec.rb +48 -1
- data/spec/unit/cookbook/chefignore_spec.rb +10 -0
- data/spec/unit/cookbook/metadata_spec.rb +45 -1
- data/spec/unit/cookbook/syntax_check_spec.rb +28 -0
- data/spec/unit/cookbook_spec.rb +0 -10
- data/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb +56 -0
- data/spec/unit/http/simple_spec.rb +32 -0
- data/spec/unit/http/validate_content_length_spec.rb +187 -0
- data/spec/unit/knife/bootstrap_spec.rb +13 -4
- data/spec/unit/knife/client_bulk_delete_spec.rb +123 -38
- data/spec/unit/knife/client_delete_spec.rb +4 -4
- data/spec/unit/knife/cookbook_upload_spec.rb +181 -88
- data/spec/unit/knife/core/bootstrap_context_spec.rb +11 -1
- data/spec/unit/knife/core/ui_spec.rb +109 -38
- data/spec/unit/knife/node_run_list_add_spec.rb +24 -1
- data/spec/unit/knife/ssh_spec.rb +17 -6
- data/spec/unit/knife/ssl_check_spec.rb +187 -0
- data/spec/unit/knife/ssl_fetch_spec.rb +151 -0
- data/spec/unit/mixin/deep_merge_spec.rb +17 -0
- data/spec/unit/node/immutable_collections_spec.rb +55 -0
- data/spec/unit/node_spec.rb +9 -0
- data/spec/unit/platform/query_helpers_spec.rb +32 -0
- data/spec/unit/platform_spec.rb +193 -175
- data/spec/unit/policy_builder/expand_node_object_spec.rb +1 -1
- data/spec/unit/provider/cron_spec.rb +175 -1
- data/spec/unit/provider/mount/mount_spec.rb +33 -3
- data/spec/unit/provider/package/dpkg_spec.rb +4 -0
- data/spec/unit/provider/package/windows/msi_spec.rb +60 -0
- data/spec/unit/provider/package/windows_spec.rb +80 -0
- data/spec/unit/provider/service/macosx_spec.rb +3 -3
- data/spec/unit/provider/service/solaris_smf_service_spec.rb +35 -10
- data/spec/unit/pure_application_spec.rb +32 -0
- data/spec/unit/recipe_spec.rb +4 -0
- data/spec/unit/resource/conditional_spec.rb +13 -12
- data/spec/unit/resource/cron_spec.rb +7 -2
- data/spec/unit/resource/powershell_spec.rb +85 -2
- data/spec/unit/resource/subversion_spec.rb +5 -0
- data/spec/unit/resource/windows_package_spec.rb +74 -0
- data/spec/unit/resource_spec.rb +23 -1
- data/spec/unit/rest_spec.rb +15 -0
- data/spec/unit/run_context/cookbook_compiler_spec.rb +12 -0
- data/spec/unit/run_context_spec.rb +7 -0
- data/spec/unit/util/editor_spec.rb +152 -0
- data/spec/unit/util/file_edit_spec.rb +37 -1
- metadata +41 -30
data/lib/chef/provider/cron.rb
CHANGED
@@ -25,11 +25,14 @@ class Chef
|
|
25
25
|
class Cron < Chef::Provider
|
26
26
|
include Chef::Mixin::Command
|
27
27
|
|
28
|
+
SPECIAL_TIME_VALUES = [:reboot, :yearly, :annually, :monthly, :weekly, :daily, :midnight, :hourly]
|
29
|
+
CRON_ATTRIBUTES = [:minute, :hour, :day, :month, :weekday, :time, :command, :mailto, :path, :shell, :home, :environment]
|
30
|
+
WEEKDAY_SYMBOLS = [:sunday, :monday, :tuesday, :wednesday, :thursday, :friday, :saturday]
|
31
|
+
|
28
32
|
CRON_PATTERN = /\A([-0-9*,\/]+)\s([-0-9*,\/]+)\s([-0-9*,\/]+)\s([-0-9*,\/]+|[a-zA-Z]{3})\s([-0-9*,\/]+|[a-zA-Z]{3})\s(.*)/
|
33
|
+
SPECIAL_PATTERN = /\A(@(#{SPECIAL_TIME_VALUES.join('|')}))\s(.*)/
|
29
34
|
ENV_PATTERN = /\A(\S+)=(\S*)/
|
30
35
|
|
31
|
-
CRON_ATTRIBUTES = [:minute, :hour, :day, :month, :weekday, :command, :mailto, :path, :shell, :home, :environment]
|
32
|
-
|
33
36
|
def initialize(new_resource, run_context)
|
34
37
|
super(new_resource, run_context)
|
35
38
|
@cron_exists = false
|
@@ -58,6 +61,12 @@ class Chef
|
|
58
61
|
when ENV_PATTERN
|
59
62
|
set_environment_var($1, $2) if cron_found
|
60
63
|
next
|
64
|
+
when SPECIAL_PATTERN
|
65
|
+
if cron_found
|
66
|
+
@current_resource.time($2.to_sym)
|
67
|
+
@current_resource.command($3)
|
68
|
+
cron_found=false
|
69
|
+
end
|
61
70
|
when CRON_PATTERN
|
62
71
|
if cron_found
|
63
72
|
@current_resource.minute($1)
|
@@ -220,9 +229,22 @@ class Chef
|
|
220
229
|
@new_resource.environment.each do |name, value|
|
221
230
|
newcron << "#{name}=#{value}\n"
|
222
231
|
end
|
223
|
-
|
232
|
+
if @new_resource.time
|
233
|
+
newcron << "@#{@new_resource.time} #{@new_resource.command}\n"
|
234
|
+
else
|
235
|
+
newcron << "#{@new_resource.minute} #{@new_resource.hour} #{@new_resource.day} #{@new_resource.month} #{@new_resource.weekday} #{@new_resource.command}\n"
|
236
|
+
end
|
224
237
|
newcron
|
225
238
|
end
|
239
|
+
|
240
|
+
def weekday_in_crontab
|
241
|
+
weekday_in_crontab = WEEKDAY_SYMBOLS.index(@new_resource.weekday)
|
242
|
+
if weekday_in_crontab.nil?
|
243
|
+
@new_resource.weekday
|
244
|
+
else
|
245
|
+
weekday_in_crontab.to_s
|
246
|
+
end
|
247
|
+
end
|
226
248
|
end
|
227
249
|
end
|
228
250
|
end
|
@@ -244,7 +244,7 @@ class Chef
|
|
244
244
|
# So given a symlink like this:
|
245
245
|
# /dev/mapper/vgroot-tmp.vol -> /dev/dm-9
|
246
246
|
# First it will try to match "/dev/mapper/vgroot-tmp.vol". If there is no match it will try matching for "/dev/dm-9".
|
247
|
-
"(?:#{Regexp.escape(device_real)}|#{Regexp.escape(::File.readlink(device_real))})"
|
247
|
+
"(?:#{Regexp.escape(device_real)}|#{Regexp.escape(::File.expand_path(::File.readlink(device_real),::File.dirname(device_real)))})"
|
248
248
|
else
|
249
249
|
Regexp.escape(device_real)
|
250
250
|
end
|
@@ -25,7 +25,8 @@ class Chef
|
|
25
25
|
class Provider
|
26
26
|
class Package
|
27
27
|
class Dpkg < Chef::Provider::Package::Apt
|
28
|
-
|
28
|
+
# http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Version
|
29
|
+
DPKG_INFO = /([a-z\d\-\+\.]+)\t([\w\d.~:-]+)/
|
29
30
|
DPKG_INSTALLED = /^Status: install ok installed/
|
30
31
|
DPKG_VERSION = /^Version: (.+)$/
|
31
32
|
|
@@ -0,0 +1,80 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Bryan McLellan <btm@loftninjas.org>
|
3
|
+
# Copyright:: Copyright (c) 2014 Chef Software, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/resource/windows_package'
|
20
|
+
require 'chef/provider/package'
|
21
|
+
|
22
|
+
class Chef
|
23
|
+
class Provider
|
24
|
+
class Package
|
25
|
+
class Windows < Chef::Provider::Package
|
26
|
+
|
27
|
+
# Depending on the installer, we may need to examine installer_type or
|
28
|
+
# source attributes, or search for text strings in the installer file
|
29
|
+
# binary to determine the installer type for the user. Since the file
|
30
|
+
# must be on disk to do so, we have to make this choice in the provider.
|
31
|
+
require 'chef/provider/package/windows/msi.rb'
|
32
|
+
|
33
|
+
# load_current_resource is run in Chef::Provider#run_action when not in whyrun_mode?
|
34
|
+
def load_current_resource
|
35
|
+
@current_resource = Chef::Resource::WindowsPackage.new(@new_resource.name)
|
36
|
+
@current_resource.version(package_provider.installed_version)
|
37
|
+
@new_resource.version(package_provider.package_version)
|
38
|
+
@current_resource
|
39
|
+
end
|
40
|
+
|
41
|
+
def package_provider
|
42
|
+
@package_provider ||= begin
|
43
|
+
case installer_type
|
44
|
+
when :msi
|
45
|
+
Chef::Provider::Package::Windows::MSI.new(@new_resource)
|
46
|
+
else
|
47
|
+
raise "Unable to find a Chef::Provider::Package::Windows provider for installer_type '#{installer_type}'"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def installer_type
|
53
|
+
@installer_type ||= begin
|
54
|
+
if @new_resource.installer_type
|
55
|
+
@new_resource.installer_type
|
56
|
+
else
|
57
|
+
file_extension = ::File.basename(@new_resource.source).split(".").last.downcase
|
58
|
+
|
59
|
+
if file_extension == "msi"
|
60
|
+
:msi
|
61
|
+
else
|
62
|
+
raise ArgumentError, "Installer type for Windows Package '#{@new_resource.name}' not specified and cannot be determined from file extension '#{file_extension}'"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Chef::Provider::Package action_install + action_remove call install_package + remove_package
|
69
|
+
# Pass those calls to the correct sub-provider
|
70
|
+
def install_package(name, version)
|
71
|
+
package_provider.install_package(name, version)
|
72
|
+
end
|
73
|
+
|
74
|
+
def remove_package(name, version)
|
75
|
+
package_provider.remove_package(name, version)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Bryan McLellan <btm@loftninjas.org>
|
3
|
+
# Copyright:: Copyright (c) 2014 Chef Software, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
# TODO: Allow @new_resource.source to be a Product Code as a GUID for uninstall / network install
|
20
|
+
|
21
|
+
require 'chef/mixin/shell_out'
|
22
|
+
require 'chef/win32/api/installer' if RUBY_PLATFORM =~ /mswin|mingw32|windows/
|
23
|
+
|
24
|
+
class Chef
|
25
|
+
class Provider
|
26
|
+
class Package
|
27
|
+
class Windows
|
28
|
+
class MSI
|
29
|
+
include Chef::ReservedNames::Win32::API::Installer if RUBY_PLATFORM =~ /mswin|mingw32|windows/
|
30
|
+
include Chef::Mixin::ShellOut
|
31
|
+
|
32
|
+
def initialize(resource)
|
33
|
+
@new_resource = resource
|
34
|
+
end
|
35
|
+
|
36
|
+
# From Chef::Provider::Package
|
37
|
+
def expand_options(options)
|
38
|
+
options ? " #{options}" : ""
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns a version if the package is installed or nil if it is not.
|
42
|
+
def installed_version
|
43
|
+
Chef::Log.debug("#{@new_resource} getting product code for package at #{@new_resource.source}")
|
44
|
+
product_code = get_product_property(@new_resource.source, "ProductCode")
|
45
|
+
Chef::Log.debug("#{@new_resource} checking package status and verion for #{product_code}")
|
46
|
+
get_installed_version(product_code)
|
47
|
+
end
|
48
|
+
|
49
|
+
def package_version
|
50
|
+
Chef::Log.debug("#{@new_resource} getting product version for package at #{@new_resource.source}")
|
51
|
+
get_product_property(@new_resource.source, "ProductVersion")
|
52
|
+
end
|
53
|
+
|
54
|
+
def install_package(name, version)
|
55
|
+
# We could use MsiConfigureProduct here, but we'll start off with msiexec
|
56
|
+
Chef::Log.debug("#{@new_resource} installing MSI package '#{@new_resource.source}'")
|
57
|
+
shell_out!("msiexec /qn /i \"#{@new_resource.source}\" #{expand_options(@new_resource.options)}", {:timeout => @new_resource.timeout, :returns => @new_resource.returns})
|
58
|
+
end
|
59
|
+
|
60
|
+
def remove_package(name, version)
|
61
|
+
# We could use MsiConfigureProduct here, but we'll start off with msiexec
|
62
|
+
Chef::Log.debug("#{@new_resource} removing MSI package '#{@new_resource.source}'")
|
63
|
+
shell_out!("msiexec /qn /x \"#{@new_resource.source}\" #{expand_options(@new_resource.options)}", {:timeout => @new_resource.timeout, :returns => @new_resource.returns})
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -23,9 +23,9 @@ class Chef
|
|
23
23
|
class PowershellScript < Chef::Provider::WindowsScript
|
24
24
|
|
25
25
|
protected
|
26
|
-
|
27
|
-
EXIT_STATUS_NORMALIZATION_SCRIPT = "\nif ($? -
|
28
|
-
EXIT_STATUS_RESET_SCRIPT = "$LASTEXITCODE=0
|
26
|
+
EXIT_STATUS_EXCEPTION_HANDLER = "\ntrap [Exception] {write-error -exception ($_.Exception.Message);exit 1}".freeze
|
27
|
+
EXIT_STATUS_NORMALIZATION_SCRIPT = "\nif ($? -ne $true) { if ( $LASTEXITCODE -ne 0) {exit $LASTEXITCODE} else { exit 1 }}".freeze
|
28
|
+
EXIT_STATUS_RESET_SCRIPT = "\n$LASTEXITCODE=0".freeze
|
29
29
|
|
30
30
|
# Process exit codes are strange with PowerShell. Unless you
|
31
31
|
# explicitly call exit in Powershell, the powershell.exe
|
@@ -36,15 +36,28 @@ class Chef
|
|
36
36
|
# last process run in the script if it is the last command
|
37
37
|
# executed, otherwise 0 or 1 based on whether $? is set to true
|
38
38
|
# (success, where we return 0) or false (where we return 1).
|
39
|
-
def
|
40
|
-
|
39
|
+
def normalize_script_exit_status( code )
|
40
|
+
target_code = ( EXIT_STATUS_EXCEPTION_HANDLER +
|
41
|
+
EXIT_STATUS_RESET_SCRIPT +
|
42
|
+
"\n" +
|
43
|
+
code.to_s +
|
44
|
+
EXIT_STATUS_NORMALIZATION_SCRIPT )
|
45
|
+
convert_boolean_return = @new_resource.convert_boolean_return
|
46
|
+
@code = <<EOH
|
47
|
+
new-variable -name interpolatedexitcode -visibility private -value $#{convert_boolean_return}
|
48
|
+
new-variable -name chefscriptresult -visibility private
|
49
|
+
$chefscriptresult = {
|
50
|
+
#{target_code}
|
51
|
+
}.invokereturnasis()
|
52
|
+
if ($interpolatedexitcode -and $chefscriptresult.gettype().name -eq 'boolean') { exit [int32](!$chefscriptresult) } else { exit 0 }
|
53
|
+
EOH
|
41
54
|
end
|
42
55
|
|
43
56
|
public
|
44
57
|
|
45
58
|
def initialize (new_resource, run_context)
|
46
59
|
super(new_resource, run_context, '.ps1')
|
47
|
-
|
60
|
+
normalize_script_exit_status(new_resource.code)
|
48
61
|
end
|
49
62
|
|
50
63
|
def flags
|
@@ -25,11 +25,13 @@ class Chef
|
|
25
25
|
class Service
|
26
26
|
class Solaris < Chef::Provider::Service
|
27
27
|
include Chef::Mixin::ShellOut
|
28
|
+
attr_reader :maintenance
|
28
29
|
|
29
30
|
def initialize(new_resource, run_context=nil)
|
30
31
|
super
|
31
32
|
@init_command = "/usr/sbin/svcadm"
|
32
33
|
@status_command = "/bin/svcs -l"
|
34
|
+
@maintenace = false
|
33
35
|
end
|
34
36
|
|
35
37
|
|
@@ -44,6 +46,7 @@ class Chef
|
|
44
46
|
end
|
45
47
|
|
46
48
|
def enable_service
|
49
|
+
shell_out!("#{default_init_command} clear #{@new_resource.service_name}") if @maintenance
|
47
50
|
shell_out!("#{default_init_command} enable -s #{@new_resource.service_name}")
|
48
51
|
end
|
49
52
|
|
@@ -65,13 +68,14 @@ class Chef
|
|
65
68
|
end
|
66
69
|
|
67
70
|
def service_status
|
68
|
-
status =
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
71
|
+
status = shell_out!("#{@status_command} #{@current_resource.service_name}")
|
72
|
+
status.stdout.each_line do |line|
|
73
|
+
case line
|
74
|
+
when /state\s+online/
|
75
|
+
@current_resource.enabled(true)
|
76
|
+
@current_resource.running(true)
|
77
|
+
when /state\s+maintenance/
|
78
|
+
@maintenance = true
|
75
79
|
end
|
76
80
|
end
|
77
81
|
unless @current_resource.enabled
|
data/lib/chef/resource.rb
CHANGED
@@ -23,6 +23,7 @@ require 'chef/dsl/data_query'
|
|
23
23
|
require 'chef/dsl/registry_helper'
|
24
24
|
require 'chef/dsl/reboot_pending'
|
25
25
|
require 'chef/mixin/convert_to_class_name'
|
26
|
+
require 'chef//guard_interpreter/resource_guard_interpreter'
|
26
27
|
require 'chef/resource/conditional'
|
27
28
|
require 'chef/resource/conditional_action_not_nothing'
|
28
29
|
require 'chef/resource_collection'
|
@@ -249,6 +250,7 @@ F
|
|
249
250
|
@not_if = []
|
250
251
|
@only_if = []
|
251
252
|
@source_line = nil
|
253
|
+
@guard_interpreter = :default
|
252
254
|
@elapsed_time = 0
|
253
255
|
|
254
256
|
@node = run_context ? deprecated_ivar(run_context.node, :node, :warn) : nil
|
@@ -401,6 +403,14 @@ F
|
|
401
403
|
ignore_failure(arg)
|
402
404
|
end
|
403
405
|
|
406
|
+
def guard_interpreter(arg=nil)
|
407
|
+
set_or_return(
|
408
|
+
:guard_interpreter,
|
409
|
+
arg,
|
410
|
+
:kind_of => Symbol
|
411
|
+
)
|
412
|
+
end
|
413
|
+
|
404
414
|
# Sets up a notification from this resource to the resource specified by +resource_spec+.
|
405
415
|
def notifies(action, resource_spec, timing=:delayed)
|
406
416
|
# when using old-style resources(:template => "/foo.txt") style, you
|
@@ -552,7 +562,7 @@ F
|
|
552
562
|
# * evaluates to false if the block is false, or if the command returns a non-zero exit code.
|
553
563
|
def only_if(command=nil, opts={}, &block)
|
554
564
|
if command || block_given?
|
555
|
-
@only_if << Conditional.only_if(command, opts, &block)
|
565
|
+
@only_if << Conditional.only_if(self, command, opts, &block)
|
556
566
|
end
|
557
567
|
@only_if
|
558
568
|
end
|
@@ -573,7 +583,7 @@ F
|
|
573
583
|
# * evaluates to false if the block is true, or if the command returns a 0 exit status.
|
574
584
|
def not_if(command=nil, opts={}, &block)
|
575
585
|
if command || block_given?
|
576
|
-
@not_if << Conditional.not_if(command, opts, &block)
|
586
|
+
@not_if << Conditional.not_if(self, command, opts, &block)
|
577
587
|
end
|
578
588
|
@not_if
|
579
589
|
end
|
@@ -627,7 +637,7 @@ F
|
|
627
637
|
provider_for_action(action).run_action
|
628
638
|
rescue Exception => e
|
629
639
|
if ignore_failure
|
630
|
-
Chef::Log.error("#{
|
640
|
+
Chef::Log.error("#{custom_exception_message(e)}; ignore_failure is set, continuing")
|
631
641
|
events.resource_failed(self, action, e)
|
632
642
|
elsif retries > 0
|
633
643
|
events.resource_failed_retriable(self, action, retries, e)
|
@@ -662,8 +672,12 @@ F
|
|
662
672
|
end
|
663
673
|
end
|
664
674
|
|
675
|
+
def custom_exception_message(e)
|
676
|
+
"#{self} (#{defined_at}) had an error: #{e.class.name}: #{e.message}"
|
677
|
+
end
|
678
|
+
|
665
679
|
def customize_exception(e)
|
666
|
-
new_exception = e.exception(
|
680
|
+
new_exception = e.exception(custom_exception_message(e))
|
667
681
|
new_exception.set_backtrace(e.backtrace)
|
668
682
|
new_exception
|
669
683
|
end
|
@@ -815,6 +829,5 @@ F
|
|
815
829
|
end
|
816
830
|
end
|
817
831
|
end
|
818
|
-
|
819
832
|
end
|
820
833
|
end
|
@@ -17,6 +17,7 @@
|
|
17
17
|
#
|
18
18
|
|
19
19
|
require 'chef/mixin/shell_out'
|
20
|
+
require 'chef/guard_interpreter/resource_guard_interpreter'
|
20
21
|
|
21
22
|
class Chef
|
22
23
|
class Resource
|
@@ -29,12 +30,12 @@ class Chef
|
|
29
30
|
private :new
|
30
31
|
end
|
31
32
|
|
32
|
-
def self.not_if(command=nil, command_opts={}, &block)
|
33
|
-
new(:not_if, command, command_opts, &block)
|
33
|
+
def self.not_if(parent_resource, command=nil, command_opts={}, &block)
|
34
|
+
new(:not_if, parent_resource, command, command_opts, &block)
|
34
35
|
end
|
35
36
|
|
36
|
-
def self.only_if(command=nil, command_opts={}, &block)
|
37
|
-
new(:only_if, command, command_opts, &block)
|
37
|
+
def self.only_if(parent_resource, command=nil, command_opts={}, &block)
|
38
|
+
new(:only_if, parent_resource, command, command_opts, &block)
|
38
39
|
end
|
39
40
|
|
40
41
|
attr_reader :positivity
|
@@ -42,14 +43,16 @@ class Chef
|
|
42
43
|
attr_reader :command_opts
|
43
44
|
attr_reader :block
|
44
45
|
|
45
|
-
def initialize(positivity, command=nil, command_opts={}, &block)
|
46
|
+
def initialize(positivity, parent_resource, command=nil, command_opts={}, &block)
|
46
47
|
@positivity = positivity
|
47
48
|
case command
|
48
49
|
when String
|
50
|
+
@guard_interpreter = new_guard_interpreter(parent_resource, command, command_opts, &block)
|
49
51
|
@command, @command_opts = command, command_opts
|
50
52
|
@block = nil
|
51
53
|
when nil
|
52
54
|
raise ArgumentError, "only_if/not_if requires either a command or a block" unless block_given?
|
55
|
+
@guard_interpreter = nil
|
53
56
|
@command, @command_opts = nil, nil
|
54
57
|
@block = block
|
55
58
|
else
|
@@ -69,11 +72,11 @@ class Chef
|
|
69
72
|
end
|
70
73
|
|
71
74
|
def evaluate
|
72
|
-
@
|
75
|
+
@guard_interpreter ? evaluate_command : evaluate_block
|
73
76
|
end
|
74
77
|
|
75
78
|
def evaluate_command
|
76
|
-
|
79
|
+
@guard_interpreter.evaluate
|
77
80
|
rescue Chef::Exceptions::CommandTimeout
|
78
81
|
Chef::Log.warn "Command '#{@command}' timed out"
|
79
82
|
false
|
@@ -100,6 +103,16 @@ class Chef
|
|
100
103
|
end
|
101
104
|
end
|
102
105
|
|
106
|
+
private
|
107
|
+
|
108
|
+
def new_guard_interpreter(parent_resource, command, opts)
|
109
|
+
if parent_resource.guard_interpreter == :default
|
110
|
+
guard_interpreter = Chef::GuardInterpreter::DefaultGuardInterpreter.new(command, opts)
|
111
|
+
else
|
112
|
+
guard_interpreter = Chef::GuardInterpreter::ResourceGuardInterpreter.new(parent_resource, command, opts)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
103
116
|
end
|
104
117
|
end
|
105
118
|
end
|