microwave 0.1004.6 → 0.1006.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/chef/checksum.rb +33 -13
- data/lib/chef/checksum/storage.rb +18 -0
- data/lib/chef/checksum/storage/filesystem.rb +56 -0
- data/lib/chef/config.rb +5 -1
- data/lib/chef/cookbook/syntax_check.rb +1 -1
- data/lib/chef/cookbook_version.rb +37 -9
- data/lib/chef/file_access_control.rb +1 -1
- data/lib/chef/handler.rb +21 -0
- data/lib/chef/mixin/command.rb +0 -58
- data/lib/chef/mixin/command/windows.rb +1 -1
- data/lib/chef/provider/file.rb +5 -1
- data/lib/chef/provider/remote_directory.rb +0 -1
- data/lib/chef/resource.rb +66 -41
- data/lib/chef/resource/conditional.rb +90 -0
- data/lib/chef/shell_out.rb +0 -1
- data/lib/chef/shell_out/windows.rb +511 -52
- data/lib/chef/tasks/chef_repo.rake +9 -5
- data/lib/chef/version.rb +1 -1
- data/lib/chef/version_class.rb +1 -1
- metadata +9 -6
data/lib/chef/checksum.rb
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
# limitations under the License.
|
|
17
17
|
|
|
18
18
|
require 'chef/log'
|
|
19
|
+
require 'chef/checksum/storage'
|
|
19
20
|
require 'uuidtools'
|
|
20
21
|
|
|
21
22
|
class Chef
|
|
@@ -25,6 +26,14 @@ class Chef
|
|
|
25
26
|
class Checksum
|
|
26
27
|
attr_accessor :checksum, :create_time
|
|
27
28
|
|
|
29
|
+
attr_reader :storage
|
|
30
|
+
|
|
31
|
+
# When a Checksum commits a sandboxed file to its final home in the checksum
|
|
32
|
+
# repo, this attribute will have the original on-disk path where the file
|
|
33
|
+
# was stored; it will be used if the commit is reverted to restore the sandbox
|
|
34
|
+
# to the pre-commit state.
|
|
35
|
+
attr_reader :original_committed_file_location
|
|
36
|
+
|
|
28
37
|
# Creates a new Chef::Checksum object.
|
|
29
38
|
# === Arguments
|
|
30
39
|
# checksum::: the MD5 content hash of the file
|
|
@@ -35,6 +44,7 @@ class Chef
|
|
|
35
44
|
@create_time = Time.now.iso8601
|
|
36
45
|
@checksum = checksum
|
|
37
46
|
@original_committed_file_location = nil
|
|
47
|
+
@storage = Storage::Filesystem.new(Chef::Config.checksum_path, checksum)
|
|
38
48
|
end
|
|
39
49
|
|
|
40
50
|
def to_json(*a)
|
|
@@ -55,28 +65,38 @@ class Chef
|
|
|
55
65
|
checksum
|
|
56
66
|
end
|
|
57
67
|
|
|
68
|
+
# Moves the given +sandbox_file+ into the checksum repo using the path
|
|
69
|
+
# given by +file_location+ and saves the Checksum to the database
|
|
70
|
+
def commit_sandbox_file(sandbox_file)
|
|
71
|
+
@original_committed_file_location = sandbox_file
|
|
72
|
+
Chef::Log.info("Commiting sandbox file: move #{sandbox_file} to #{@storage}")
|
|
73
|
+
@storage.commit(sandbox_file)
|
|
74
|
+
end
|
|
58
75
|
|
|
59
|
-
|
|
60
|
-
#
|
|
61
|
-
|
|
76
|
+
# Moves the checksum file back to its pre-commit location and deletes
|
|
77
|
+
# the checksum object from the database, effectively undoing +commit_sandbox_file+.
|
|
78
|
+
# Raises Chef::Exceptions::IllegalChecksumRevert if the original file location
|
|
79
|
+
# is unknown, which is will be the case if commit_sandbox_file was not
|
|
80
|
+
# previously called
|
|
81
|
+
def revert_sandbox_file_commit
|
|
82
|
+
unless original_committed_file_location
|
|
83
|
+
raise Chef::Exceptions::IllegalChecksumRevert, "Checksum #{self.inspect} cannot be reverted because the original sandbox file location is not known"
|
|
84
|
+
end
|
|
62
85
|
|
|
63
|
-
|
|
64
|
-
|
|
86
|
+
Chef::Log.warn("Reverting sandbox file commit: moving #{@storage} back to #{original_committed_file_location}")
|
|
87
|
+
@storage.revert(original_committed_file_location)
|
|
65
88
|
end
|
|
66
89
|
|
|
67
|
-
|
|
68
|
-
|
|
90
|
+
# Removes the on-disk file backing this checksum object, then removes it
|
|
91
|
+
# from the database
|
|
92
|
+
def purge
|
|
93
|
+
purge_file
|
|
69
94
|
end
|
|
70
95
|
|
|
71
96
|
private
|
|
72
97
|
|
|
73
|
-
# Deletes the file backing this checksum from the on-disk repo.
|
|
74
|
-
# Purging the checksums is how users can get back to a valid state if
|
|
75
|
-
# they've deleted files, so we silently swallow Errno::ENOENT here.
|
|
76
98
|
def purge_file
|
|
77
|
-
|
|
78
|
-
rescue Errno::ENOENT
|
|
79
|
-
true
|
|
99
|
+
@storage.purge
|
|
80
100
|
end
|
|
81
101
|
|
|
82
102
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Andrea Campi (<andrea.campi@zephirworks.com>)
|
|
3
|
+
# Copyright:: Copyright (c) 2011 Opscode, 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
|
+
require 'chef/checksum/storage/filesystem'
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Tim Hinderliter (<tim@opscode.com>)
|
|
3
|
+
# Copyright:: Copyright (c) 2011 Opscode, 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
|
+
class Chef
|
|
19
|
+
class Checksum
|
|
20
|
+
class Storage
|
|
21
|
+
class Filesystem
|
|
22
|
+
def initialize(base_dir, checksum)
|
|
23
|
+
@base_dir = base_dir
|
|
24
|
+
@checksum = checksum
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def file_location
|
|
28
|
+
File.join(checksum_repo_directory, @checksum)
|
|
29
|
+
end
|
|
30
|
+
alias :to_s :file_location
|
|
31
|
+
|
|
32
|
+
def checksum_repo_directory
|
|
33
|
+
File.join(Chef::Config.checksum_path, @checksum[0..1])
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def commit(sandbox_file)
|
|
37
|
+
FileUtils.mkdir_p(checksum_repo_directory)
|
|
38
|
+
File.rename(sandbox_file, file_location)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def revert(original_committed_file_location)
|
|
42
|
+
File.rename(file_location, original_committed_file_location)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Deletes the file backing this checksum from the on-disk repo.
|
|
46
|
+
# Purging the checksums is how users can get back to a valid state if
|
|
47
|
+
# they've deleted files, so we silently swallow Errno::ENOENT here.
|
|
48
|
+
def purge
|
|
49
|
+
FileUtils.rm(file_location)
|
|
50
|
+
rescue Errno::ENOENT
|
|
51
|
+
true
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
data/lib/chef/config.rb
CHANGED
|
@@ -64,7 +64,8 @@ class Chef
|
|
|
64
64
|
interval nil
|
|
65
65
|
log_level :info
|
|
66
66
|
log_location STDOUT
|
|
67
|
-
|
|
67
|
+
# toggle info level log items that can create a lot of output
|
|
68
|
+
verbose_logging true
|
|
68
69
|
node_name nil
|
|
69
70
|
node_path "#{ENV['HOME']}/nodes"
|
|
70
71
|
|
|
@@ -84,6 +85,9 @@ class Chef
|
|
|
84
85
|
# Exception Handlers
|
|
85
86
|
exception_handlers []
|
|
86
87
|
|
|
88
|
+
# Start handlers
|
|
89
|
+
start_handlers []
|
|
90
|
+
|
|
87
91
|
# Checksum Cache
|
|
88
92
|
# Uses Moneta on the back-end
|
|
89
93
|
cache_type "BasicFile"
|
|
@@ -109,7 +109,7 @@ class Chef
|
|
|
109
109
|
|
|
110
110
|
def validate_template(erb_file)
|
|
111
111
|
Chef::Log.debug("Testing template #{erb_file} for syntax errors...")
|
|
112
|
-
result = shell_out("
|
|
112
|
+
result = shell_out("erubis -x #{erb_file} | ruby -c")
|
|
113
113
|
result.error!
|
|
114
114
|
true
|
|
115
115
|
rescue Chef::Exceptions::ShellCommandFailed
|
|
@@ -377,7 +377,24 @@ class Chef
|
|
|
377
377
|
if found_pref
|
|
378
378
|
@manifest_records_by_path[found_pref]
|
|
379
379
|
else
|
|
380
|
-
|
|
380
|
+
if segment == :files || segment == :templates
|
|
381
|
+
error_message = "Cookbook '#{name}' (#{version}) does not contain a file at any of these locations:\n"
|
|
382
|
+
error_locations = [
|
|
383
|
+
" #{segment}/#{node[:platform]}-#{node[:platform_version]}/#{filename}",
|
|
384
|
+
" #{segment}/#{node[:platform]}/#{filename}",
|
|
385
|
+
" #{segment}/default/#{filename}",
|
|
386
|
+
]
|
|
387
|
+
error_message << error_locations.join("\n")
|
|
388
|
+
existing_files = segment_filenames(segment)
|
|
389
|
+
# Show the files that the cookbook does have. If the user made a typo,
|
|
390
|
+
# hopefully they'll see it here.
|
|
391
|
+
unless existing_files.empty?
|
|
392
|
+
error_message << "\n\nThis cookbook _does_ contain: ['#{existing_files.join("','")}']"
|
|
393
|
+
end
|
|
394
|
+
raise Chef::Exceptions::FileNotFound, error_message
|
|
395
|
+
else
|
|
396
|
+
raise Chef::Exceptions::FileNotFound, "cookbook #{name} does not contain file #{segment}/#{filename}"
|
|
397
|
+
end
|
|
381
398
|
end
|
|
382
399
|
end
|
|
383
400
|
|
|
@@ -422,7 +439,7 @@ class Chef
|
|
|
422
439
|
|
|
423
440
|
best_pref = preferences.find { |pref| !filenames_by_pref[pref].empty? }
|
|
424
441
|
|
|
425
|
-
raise Chef::Exceptions::FileNotFound, "cookbook #{name} has no directory #{segment}/#{dirname}" unless best_pref
|
|
442
|
+
raise Chef::Exceptions::FileNotFound, "cookbook #{name} has no directory #{segment}/default/#{dirname}" unless best_pref
|
|
426
443
|
|
|
427
444
|
filenames_by_pref[best_pref]
|
|
428
445
|
|
|
@@ -457,7 +474,7 @@ class Chef
|
|
|
457
474
|
|
|
458
475
|
best_pref = preferences.find { |pref| !records_by_pref[pref].empty? }
|
|
459
476
|
|
|
460
|
-
raise Chef::Exceptions::FileNotFound, "cookbook #{name} has no directory #{segment}/#{dirname}" unless best_pref
|
|
477
|
+
raise Chef::Exceptions::FileNotFound, "cookbook #{name} (#{version}) has no directory #{segment}/default/#{dirname}" unless best_pref
|
|
461
478
|
|
|
462
479
|
records_by_pref[best_pref]
|
|
463
480
|
end
|
|
@@ -483,13 +500,24 @@ class Chef
|
|
|
483
500
|
|
|
484
501
|
fqdn = node[:fqdn]
|
|
485
502
|
|
|
503
|
+
# Break version into components, eg: "5.7.1" => [ "5.7.1", "5.7", "5" ]
|
|
504
|
+
search_versions = []
|
|
505
|
+
parts = version.to_s.split('.')
|
|
506
|
+
|
|
507
|
+
parts.size.times do
|
|
508
|
+
search_versions << parts.join('.')
|
|
509
|
+
parts.pop
|
|
510
|
+
end
|
|
511
|
+
|
|
486
512
|
# Most specific to least specific places to find the path
|
|
487
|
-
[
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
513
|
+
search_path = [ File.join(segment.to_s, "host-#{fqdn}", path) ]
|
|
514
|
+
search_versions.each do |v|
|
|
515
|
+
search_path << File.join(segment.to_s, "#{platform}-#{v}", path)
|
|
516
|
+
end
|
|
517
|
+
search_path << File.join(segment.to_s, platform.to_s, path)
|
|
518
|
+
search_path << File.join(segment.to_s, "default", path)
|
|
519
|
+
|
|
520
|
+
search_path
|
|
493
521
|
else
|
|
494
522
|
[File.join(segment, path)]
|
|
495
523
|
end
|
|
@@ -107,7 +107,7 @@ class Chef
|
|
|
107
107
|
def set_group
|
|
108
108
|
if (gid = target_gid) && (gid != stat.gid)
|
|
109
109
|
File.chown(nil, gid, file)
|
|
110
|
-
Chef::Log.info("#{log_string}
|
|
110
|
+
Chef::Log.info("#{log_string} group changed to #{gid}")
|
|
111
111
|
modified
|
|
112
112
|
end
|
|
113
113
|
end
|
data/lib/chef/handler.rb
CHANGED
|
@@ -57,6 +57,27 @@ class Chef
|
|
|
57
57
|
#
|
|
58
58
|
class Handler
|
|
59
59
|
|
|
60
|
+
# The list of currently configured start handlers
|
|
61
|
+
def self.start_handlers
|
|
62
|
+
Array(Chef::Config[:start_handlers])
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Run the start handlers. This will usually be called by a notification
|
|
66
|
+
# from Chef::Client
|
|
67
|
+
def self.run_start_handlers(run_status)
|
|
68
|
+
Chef::Log.info("Running start handlers")
|
|
69
|
+
start_handlers.each do |handler|
|
|
70
|
+
handler.run_report_safely(run_status)
|
|
71
|
+
end
|
|
72
|
+
Chef::Log.info("Start handlers complete.")
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Wire up a notification to run the start handlers when the chef run
|
|
76
|
+
# starts.
|
|
77
|
+
Chef::Client.when_run_starts do |run_status|
|
|
78
|
+
run_start_handlers(run_status)
|
|
79
|
+
end
|
|
80
|
+
|
|
60
81
|
# The list of currently configured report handlers
|
|
61
82
|
def self.report_handlers
|
|
62
83
|
Array(Chef::Config[:report_handlers])
|
data/lib/chef/mixin/command.rb
CHANGED
|
@@ -38,64 +38,6 @@ class Chef
|
|
|
38
38
|
extend ::Chef::Mixin::Command::Unix
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
# If command is a block, returns true if the block returns true, false if it returns false.
|
|
42
|
-
# ("Only run this resource if the block is true")
|
|
43
|
-
#
|
|
44
|
-
# If the command is not a block, executes the command. If it returns any status other than
|
|
45
|
-
# 0, it returns false (clearly, a 0 status code is true)
|
|
46
|
-
#
|
|
47
|
-
# === Parameters
|
|
48
|
-
# command<Block>, <String>:: A block to check, or a string to execute
|
|
49
|
-
#
|
|
50
|
-
# === Returns
|
|
51
|
-
# true:: Returns true if the block is true, or if the command returns 0
|
|
52
|
-
# false:: Returns false if the block is false, or if the command returns a non-zero exit code.
|
|
53
|
-
def only_if(command, args = {})
|
|
54
|
-
if command.kind_of?(Proc)
|
|
55
|
-
chdir_or_tmpdir(args[:cwd]) do
|
|
56
|
-
res = command.call
|
|
57
|
-
unless res
|
|
58
|
-
return false
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
else
|
|
62
|
-
status = run_command({:command => command, :ignore_failure => true}.merge(args))
|
|
63
|
-
if status.exitstatus != 0
|
|
64
|
-
return false
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
true
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
# If command is a block, returns false if the block returns true, true if it returns false.
|
|
71
|
-
# ("Do not run this resource if the block is true")
|
|
72
|
-
#
|
|
73
|
-
# If the command is not a block, executes the command. If it returns a 0 exitstatus, returns false.
|
|
74
|
-
# ("Do not run this resource if the command returns 0")
|
|
75
|
-
#
|
|
76
|
-
# === Parameters
|
|
77
|
-
# command<Block>, <String>:: A block to check, or a string to execute
|
|
78
|
-
#
|
|
79
|
-
# === Returns
|
|
80
|
-
# true:: Returns true if the block is false, or if the command returns a non-zero exit status.
|
|
81
|
-
# false:: Returns false if the block is true, or if the command returns a 0 exit status.
|
|
82
|
-
def not_if(command, args = {})
|
|
83
|
-
if command.kind_of?(Proc)
|
|
84
|
-
chdir_or_tmpdir(args[:cwd]) do
|
|
85
|
-
res = command.call
|
|
86
|
-
if res
|
|
87
|
-
return false
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
else
|
|
91
|
-
status = run_command({:command => command, :ignore_failure => true}.merge(args))
|
|
92
|
-
if status.exitstatus == 0
|
|
93
|
-
return false
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
true
|
|
97
|
-
end
|
|
98
|
-
|
|
99
41
|
# === Parameters
|
|
100
42
|
# args<Hash>: A number of required and optional arguments
|
|
101
43
|
# command<String>, <Array>: A complete command with options to execute or a command and options as an Array
|
data/lib/chef/provider/file.rb
CHANGED
|
@@ -151,7 +151,11 @@ class Chef
|
|
|
151
151
|
end
|
|
152
152
|
|
|
153
153
|
def action_create_if_missing
|
|
154
|
-
|
|
154
|
+
if ::File.exists?(@new_resource.path)
|
|
155
|
+
Chef::Log.debug("File #{@new_resource.path} exists, taking no action.")
|
|
156
|
+
else
|
|
157
|
+
action_create
|
|
158
|
+
end
|
|
155
159
|
end
|
|
156
160
|
|
|
157
161
|
def action_delete
|
data/lib/chef/resource.rb
CHANGED
|
@@ -21,7 +21,7 @@ require 'chef/mixin/params_validate'
|
|
|
21
21
|
require 'chef/mixin/check_helper'
|
|
22
22
|
require 'chef/mixin/language'
|
|
23
23
|
require 'chef/mixin/convert_to_class_name'
|
|
24
|
-
require 'chef/
|
|
24
|
+
require 'chef/resource/conditional'
|
|
25
25
|
require 'chef/resource_collection'
|
|
26
26
|
require 'chef/node'
|
|
27
27
|
|
|
@@ -70,7 +70,7 @@ F
|
|
|
70
70
|
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
-
FORBIDDEN_IVARS = [:@run_context, :@node]
|
|
73
|
+
FORBIDDEN_IVARS = [:@run_context, :@node, :@not_if, :@only_if]
|
|
74
74
|
HIDDEN_IVARS = [:@allowed_actions, :@resource_name, :@source_line, :@run_context, :@name, :@node]
|
|
75
75
|
|
|
76
76
|
include Chef::Mixin::CheckHelper
|
|
@@ -116,10 +116,8 @@ F
|
|
|
116
116
|
@ignore_failure = false
|
|
117
117
|
@retries = 0
|
|
118
118
|
@retry_delay = 2
|
|
119
|
-
@not_if =
|
|
120
|
-
@
|
|
121
|
-
@only_if = nil
|
|
122
|
-
@only_if_args = {}
|
|
119
|
+
@not_if = []
|
|
120
|
+
@only_if = []
|
|
123
121
|
@immediate_notifications = Array.new
|
|
124
122
|
@delayed_notifications = Array.new
|
|
125
123
|
@source_line = nil
|
|
@@ -371,24 +369,44 @@ F
|
|
|
371
369
|
instance_vars
|
|
372
370
|
end
|
|
373
371
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
372
|
+
# If command is a block, returns true if the block returns true, false if it returns false.
|
|
373
|
+
# ("Only run this resource if the block is true")
|
|
374
|
+
#
|
|
375
|
+
# If the command is not a block, executes the command. If it returns any status other than
|
|
376
|
+
# 0, it returns false (clearly, a 0 status code is true)
|
|
377
|
+
#
|
|
378
|
+
# === Parameters
|
|
379
|
+
# command<String>:: A a string to execute.
|
|
380
|
+
# opts<Hash>:: Options control the execution of the command
|
|
381
|
+
# block<Proc>:: A ruby block to run. Ignored if a command is given.
|
|
382
|
+
#
|
|
383
|
+
# === Evaluation
|
|
384
|
+
# * evaluates to true if the block is true, or if the command returns 0
|
|
385
|
+
# * evaluates to false if the block is false, or if the command returns a non-zero exit code.
|
|
386
|
+
def only_if(command=nil, opts={}, &block)
|
|
387
|
+
if command || block_given?
|
|
388
|
+
@only_if << Conditional.only_if(command, opts, &block)
|
|
381
389
|
end
|
|
382
390
|
@only_if
|
|
383
391
|
end
|
|
384
392
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
393
|
+
# If command is a block, returns false if the block returns true, true if it returns false.
|
|
394
|
+
# ("Do not run this resource if the block is true")
|
|
395
|
+
#
|
|
396
|
+
# If the command is not a block, executes the command. If it returns a 0 exitstatus, returns false.
|
|
397
|
+
# ("Do not run this resource if the command returns 0")
|
|
398
|
+
#
|
|
399
|
+
# === Parameters
|
|
400
|
+
# command<String>:: A a string to execute.
|
|
401
|
+
# opts<Hash>:: Options control the execution of the command
|
|
402
|
+
# block<Proc>:: A ruby block to run. Ignored if a command is given.
|
|
403
|
+
#
|
|
404
|
+
# === Evaluation
|
|
405
|
+
# * evaluates to true if the block is false, or if the command returns a non-zero exit status.
|
|
406
|
+
# * evaluates to false if the block is true, or if the command returns a 0 exit status.
|
|
407
|
+
def not_if(command=nil, opts={}, &block)
|
|
408
|
+
if command || block_given?
|
|
409
|
+
@not_if << Conditional.not_if(command, opts, &block)
|
|
392
410
|
end
|
|
393
411
|
@not_if
|
|
394
412
|
end
|
|
@@ -405,32 +423,17 @@ F
|
|
|
405
423
|
end
|
|
406
424
|
|
|
407
425
|
def run_action(action)
|
|
408
|
-
Chef::Log.
|
|
426
|
+
if Chef::Config[:verbose_logging] || Chef::Log.level == :debug
|
|
427
|
+
# This can be noisy
|
|
428
|
+
Chef::Log.info("Processing #{self} action #{action} (#{defined_at})")
|
|
429
|
+
end
|
|
409
430
|
|
|
410
431
|
# ensure that we don't leave @updated_by_last_action set to true
|
|
411
432
|
# on accident
|
|
412
433
|
updated_by_last_action(false)
|
|
413
434
|
|
|
414
435
|
begin
|
|
415
|
-
|
|
416
|
-
# evaluate the only_if block and skip the resource if
|
|
417
|
-
# appropriate.
|
|
418
|
-
if only_if
|
|
419
|
-
unless Chef::Mixin::Command.only_if(only_if, only_if_args)
|
|
420
|
-
Chef::Log.debug("Skipping #{self} due to only_if")
|
|
421
|
-
return
|
|
422
|
-
end
|
|
423
|
-
end
|
|
424
|
-
|
|
425
|
-
# Check if this resource has a not_if block -- if it does,
|
|
426
|
-
# evaluate the not_if block and skip the resource if
|
|
427
|
-
# appropriate.
|
|
428
|
-
if not_if
|
|
429
|
-
unless Chef::Mixin::Command.not_if(not_if, not_if_args)
|
|
430
|
-
Chef::Log.debug("Skipping #{self} due to not_if")
|
|
431
|
-
return
|
|
432
|
-
end
|
|
433
|
-
end
|
|
436
|
+
return if should_skip?
|
|
434
437
|
|
|
435
438
|
provider = Chef::Platform.provider_for_resource(self)
|
|
436
439
|
provider.load_current_resource
|
|
@@ -440,13 +443,35 @@ F
|
|
|
440
443
|
Chef::Log.error("#{self} (#{defined_at}) had an error: #{e.message}")
|
|
441
444
|
else
|
|
442
445
|
Chef::Log.error("#{self} (#{defined_at}) has had an error")
|
|
443
|
-
new_exception = e.exception("#{self} (#{defined_at}) had an error: #{e.message}")
|
|
446
|
+
new_exception = e.exception("#{self} (#{defined_at}) had an error: #{e.class.name}: #{e.message}")
|
|
444
447
|
new_exception.set_backtrace(e.backtrace)
|
|
445
448
|
raise new_exception
|
|
446
449
|
end
|
|
447
450
|
end
|
|
448
451
|
end
|
|
449
452
|
|
|
453
|
+
# Evaluates not_if and only_if conditionals. Returns a falsey value if any
|
|
454
|
+
# of the conditionals indicate that this resource should be skipped, i.e.,
|
|
455
|
+
# if an only_if evaluates to false or a not_if evaluates to true.
|
|
456
|
+
#
|
|
457
|
+
# If this resource should be skipped, returns the first conditional that
|
|
458
|
+
# "fails" its check. Subsequent conditionals are not evaluated, so in
|
|
459
|
+
# general it's not a good idea to rely on side effects from not_if or
|
|
460
|
+
# only_if commands/blocks being evaluated.
|
|
461
|
+
def should_skip?
|
|
462
|
+
conditionals = only_if + not_if
|
|
463
|
+
return false if conditionals.empty?
|
|
464
|
+
|
|
465
|
+
conditionals.find do |conditional|
|
|
466
|
+
if conditional.continue?
|
|
467
|
+
false
|
|
468
|
+
else
|
|
469
|
+
Chef::Log.debug("Skipping #{self} due to #{conditional.description}")
|
|
470
|
+
true
|
|
471
|
+
end
|
|
472
|
+
end
|
|
473
|
+
end
|
|
474
|
+
|
|
450
475
|
def updated_by_last_action(true_or_false)
|
|
451
476
|
@updated ||= true_or_false
|
|
452
477
|
@updated_by_last_action = true_or_false
|