chef 17.1.35 → 17.2.29
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/lib/chef/action_collection.rb +6 -26
- data/lib/chef/application.rb +1 -1
- data/lib/chef/application/base.rb +15 -0
- data/lib/chef/client.rb +6 -0
- data/lib/chef/cookbook_version.rb +26 -4
- data/lib/chef/data_bag.rb +2 -1
- data/lib/chef/data_bag_item.rb +2 -1
- data/lib/chef/data_collector.rb +0 -1
- data/lib/chef/data_collector/run_end_message.rb +1 -1
- data/lib/chef/deprecated.rb +4 -0
- data/lib/chef/event_dispatch/base.rb +2 -1
- data/lib/chef/exceptions.rb +3 -0
- data/lib/chef/handler.rb +46 -8
- data/lib/chef/handler/slow_report.rb +66 -0
- data/lib/chef/node.rb +20 -19
- data/lib/chef/provider/support/zypper_repo.erb +4 -2
- data/lib/chef/provider/zypper_repository.rb +27 -31
- data/lib/chef/resource/alternatives.rb +5 -5
- data/lib/chef/resource/apt_preference.rb +2 -2
- data/lib/chef/resource/apt_repository.rb +2 -2
- data/lib/chef/resource/apt_update.rb +4 -4
- data/lib/chef/resource/build_essential.rb +1 -1
- data/lib/chef/resource/chef_client_config.rb +3 -3
- data/lib/chef/resource/chef_client_cron.rb +2 -2
- data/lib/chef/resource/chef_client_launchd.rb +2 -2
- data/lib/chef/resource/chef_client_scheduled_task.rb +14 -14
- data/lib/chef/resource/chef_client_systemd_timer.rb +2 -2
- data/lib/chef/resource/chef_handler.rb +2 -2
- data/lib/chef/resource/chef_sleep.rb +1 -1
- data/lib/chef/resource/chocolatey_feature.rb +2 -2
- data/lib/chef/resource/chocolatey_source.rb +1 -1
- data/lib/chef/resource/cron/cron_d.rb +4 -6
- data/lib/chef/resource/cron_access.rb +1 -1
- data/lib/chef/resource/dmg_package.rb +1 -1
- data/lib/chef/resource/group.rb +4 -4
- data/lib/chef/resource/homebrew_cask.rb +17 -6
- data/lib/chef/resource/homebrew_package.rb +1 -1
- data/lib/chef/resource/homebrew_tap.rb +4 -3
- data/lib/chef/resource/homebrew_update.rb +2 -2
- data/lib/chef/resource/hostname.rb +49 -7
- data/lib/chef/resource/inspec_waiver_file_entry.rb +6 -5
- data/lib/chef/resource/kernel_module.rb +6 -6
- data/lib/chef/resource/locale.rb +1 -1
- data/lib/chef/resource/macos_userdefaults.rb +2 -2
- data/lib/chef/resource/ohai_hint.rb +2 -6
- data/lib/chef/resource/openbsd_package.rb +17 -0
- data/lib/chef/resource/openssl_dhparam.rb +1 -2
- data/lib/chef/resource/openssl_ec_private_key.rb +1 -3
- data/lib/chef/resource/openssl_ec_public_key.rb +1 -3
- data/lib/chef/resource/openssl_rsa_private_key.rb +1 -3
- data/lib/chef/resource/openssl_rsa_public_key.rb +1 -3
- data/lib/chef/resource/openssl_x509_certificate.rb +1 -4
- data/lib/chef/resource/openssl_x509_crl.rb +1 -3
- data/lib/chef/resource/openssl_x509_request.rb +1 -3
- data/lib/chef/resource/osx_profile.rb +3 -3
- data/lib/chef/resource/plist.rb +1 -1
- data/lib/chef/resource/powershell_package_source.rb +2 -4
- data/lib/chef/resource/reboot.rb +38 -9
- data/lib/chef/resource/remote_directory.rb +2 -2
- data/lib/chef/resource/rhsm_errata.rb +0 -2
- data/lib/chef/resource/rhsm_errata_level.rb +1 -5
- data/lib/chef/resource/rhsm_repo.rb +15 -0
- data/lib/chef/resource/ssh_known_hosts_entry.rb +4 -7
- data/lib/chef/resource/sudo.rb +2 -6
- data/lib/chef/resource/swap_file.rb +2 -6
- data/lib/chef/resource/sysctl.rb +2 -2
- data/lib/chef/resource/timezone.rb +1 -1
- data/lib/chef/resource/user_ulimit.rb +2 -2
- data/lib/chef/resource/windows_ad_join.rb +2 -2
- data/lib/chef/resource/windows_audit_policy.rb +2 -2
- data/lib/chef/resource/windows_auto_run.rb +2 -2
- data/lib/chef/resource/windows_certificate.rb +1 -1
- data/lib/chef/resource/windows_dfs_folder.rb +2 -2
- data/lib/chef/resource/windows_dfs_namespace.rb +2 -2
- data/lib/chef/resource/windows_dns_record.rb +2 -2
- data/lib/chef/resource/windows_dns_zone.rb +2 -2
- data/lib/chef/resource/windows_feature.rb +3 -3
- data/lib/chef/resource/windows_feature_dism.rb +3 -5
- data/lib/chef/resource/windows_feature_powershell.rb +3 -3
- data/lib/chef/resource/windows_firewall_profile.rb +2 -2
- data/lib/chef/resource/windows_firewall_rule.rb +20 -6
- data/lib/chef/resource/windows_font.rb +1 -1
- data/lib/chef/resource/windows_pagefile.rb +103 -64
- data/lib/chef/resource/windows_path.rb +2 -2
- data/lib/chef/resource/windows_printer.rb +5 -20
- data/lib/chef/resource/windows_printer_port.rb +48 -65
- data/lib/chef/resource/windows_security_policy.rb +2 -2
- data/lib/chef/resource/windows_share.rb +2 -2
- data/lib/chef/resource/windows_shortcut.rb +1 -1
- data/lib/chef/resource/windows_task.rb +1 -1
- data/lib/chef/resource/windows_uac.rb +3 -5
- data/lib/chef/resource/windows_user_privilege.rb +2 -2
- data/lib/chef/resource/windows_workgroup.rb +2 -2
- data/lib/chef/resource/yum_package.rb +10 -10
- data/lib/chef/resource/zypper_package.rb +4 -4
- data/lib/chef/resource/zypper_repository.rb +28 -8
- data/lib/chef/resource_reporter.rb +0 -1
- data/lib/chef/version.rb +1 -1
- data/spec/functional/resource/windows_hostname_spec.rb +91 -0
- data/spec/functional/resource/windows_pagefile_spec.rb +98 -0
- data/spec/unit/cookbook_version_spec.rb +52 -0
- data/spec/unit/data_bag_item_spec.rb +2 -2
- data/spec/unit/data_bag_spec.rb +1 -1
- data/spec/unit/data_collector_spec.rb +47 -1
- data/spec/unit/handler_spec.rb +8 -2
- data/spec/unit/provider/zypper_repository_spec.rb +3 -10
- data/spec/unit/resource/windows_firewall_rule_spec.rb +12 -7
- data/spec/unit/resource/windows_pagefile_spec.rb +4 -9
- data/spec/unit/resource/zypper_repository_spec.rb +1 -1
- metadata +9 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3259221c96da998dc7da695df0488bcfbe781ce3764dcd98309c78c1a46cb56c
|
4
|
+
data.tar.gz: 120938b331b2e96306b91c5a192a73ebbfaeebce9b3febfccae32d7e7918e4a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f1191c217a427591d0cdd0b0223249ed83164f53da4edd463258dfe37d084b9e928627eb9020a20aeb87f141d160eb72b64d4c1d37e47b7206f50e120b7738fe
|
7
|
+
data.tar.gz: '0148bdae1adf6ffa4539aab3c8dbc47fc225cb5d6f1e421967be4d53ce7504f9ff10af21cd0410412847b9e99d6308892b32a0ab673bd657ccb6922f191c91a1'
|
data/Gemfile
CHANGED
@@ -22,6 +22,7 @@ group(:omnibus_package) do
|
|
22
22
|
gem "rb-readline"
|
23
23
|
gem "inspec-core-bin", "~> 4.24" # need to provide the binaries for inspec
|
24
24
|
gem "chef-vault"
|
25
|
+
gem "ed25519", "~> 1.2" # to make it possible to install knife into chef. Remove this in Chef 18
|
25
26
|
end
|
26
27
|
|
27
28
|
group(:omnibus_package, :pry) do
|
@@ -87,13 +87,11 @@ class Chef
|
|
87
87
|
attr_reader :action_records
|
88
88
|
attr_reader :pending_updates
|
89
89
|
attr_reader :run_context
|
90
|
-
attr_reader :consumers
|
91
90
|
attr_reader :events
|
92
91
|
|
93
92
|
def initialize(events, run_context = nil, action_records = [])
|
94
93
|
@action_records = action_records
|
95
94
|
@pending_updates = []
|
96
|
-
@consumers = []
|
97
95
|
@events = events
|
98
96
|
@run_context = run_context
|
99
97
|
end
|
@@ -118,17 +116,17 @@ class Chef
|
|
118
116
|
self.class.new(events, run_context, subrecords)
|
119
117
|
end
|
120
118
|
|
119
|
+
def resources
|
120
|
+
action_records.map(&:new_resource)
|
121
|
+
end
|
122
|
+
|
121
123
|
# This hook gives us the run_context immediately after it is created so that we can wire up this object to it.
|
122
124
|
#
|
123
|
-
# This also causes the action_collection_registration event to fire, all consumers that have not yet registered with the
|
124
|
-
# action_collection must register via this callback. This is the latest point before resources actually start to get
|
125
|
-
# evaluated.
|
126
|
-
#
|
127
125
|
# (see EventDispatch::Base#)
|
128
126
|
#
|
129
127
|
def cookbook_compilation_start(run_context)
|
130
128
|
run_context.action_collection = self
|
131
|
-
#
|
129
|
+
# this hook is now poorly named since it is just a callback that lets other consumers snag a reference to the action_collection
|
132
130
|
run_context.events.enqueue(:action_collection_registration, self)
|
133
131
|
@run_context = run_context
|
134
132
|
end
|
@@ -139,7 +137,7 @@ class Chef
|
|
139
137
|
# @params object [Object] callers should call with `self`
|
140
138
|
#
|
141
139
|
def register(object)
|
142
|
-
|
140
|
+
Chef::Log.warn "the action collection no longer requires registration at #{caller[0]}"
|
143
141
|
end
|
144
142
|
|
145
143
|
# End of an unsuccessful converge used to fire off detect_unprocessed_resources.
|
@@ -147,8 +145,6 @@ class Chef
|
|
147
145
|
# (see EventDispatch::Base#)
|
148
146
|
#
|
149
147
|
def converge_failed(exception)
|
150
|
-
return if consumers.empty?
|
151
|
-
|
152
148
|
detect_unprocessed_resources
|
153
149
|
end
|
154
150
|
|
@@ -159,8 +155,6 @@ class Chef
|
|
159
155
|
# (see EventDispatch::Base#)
|
160
156
|
#
|
161
157
|
def resource_action_start(new_resource, action, notification_type = nil, notifier = nil)
|
162
|
-
return if consumers.empty?
|
163
|
-
|
164
158
|
pending_updates << ActionRecord.new(new_resource, action, pending_updates.length)
|
165
159
|
end
|
166
160
|
|
@@ -170,8 +164,6 @@ class Chef
|
|
170
164
|
# (see EventDispatch::Base#)
|
171
165
|
#
|
172
166
|
def resource_current_state_loaded(new_resource, action, current_resource)
|
173
|
-
return if consumers.empty?
|
174
|
-
|
175
167
|
current_record.current_resource = current_resource
|
176
168
|
end
|
177
169
|
|
@@ -181,8 +173,6 @@ class Chef
|
|
181
173
|
# (see EventDispatch::Base#)
|
182
174
|
#
|
183
175
|
def resource_after_state_loaded(new_resource, action, after_resource)
|
184
|
-
return if consumers.empty?
|
185
|
-
|
186
176
|
current_record.after_resource = after_resource
|
187
177
|
end
|
188
178
|
|
@@ -191,8 +181,6 @@ class Chef
|
|
191
181
|
# (see EventDispatch::Base#)
|
192
182
|
#
|
193
183
|
def resource_up_to_date(new_resource, action)
|
194
|
-
return if consumers.empty?
|
195
|
-
|
196
184
|
current_record.status = :up_to_date
|
197
185
|
end
|
198
186
|
|
@@ -201,8 +189,6 @@ class Chef
|
|
201
189
|
# (see EventDispatch::Base#)
|
202
190
|
#
|
203
191
|
def resource_skipped(resource, action, conditional)
|
204
|
-
return if consumers.empty?
|
205
|
-
|
206
192
|
current_record.status = :skipped
|
207
193
|
current_record.conditional = conditional
|
208
194
|
end
|
@@ -212,8 +198,6 @@ class Chef
|
|
212
198
|
# (see EventDispatch::Base#)
|
213
199
|
#
|
214
200
|
def resource_updated(new_resource, action)
|
215
|
-
return if consumers.empty?
|
216
|
-
|
217
201
|
current_record.status = :updated
|
218
202
|
end
|
219
203
|
|
@@ -222,8 +206,6 @@ class Chef
|
|
222
206
|
# (see EventDispatch::Base#)
|
223
207
|
#
|
224
208
|
def resource_failed(new_resource, action, exception)
|
225
|
-
return if consumers.empty?
|
226
|
-
|
227
209
|
current_record.status = :failed
|
228
210
|
current_record.exception = exception
|
229
211
|
current_record.error_description = Formatters::ErrorMapper.resource_failed(new_resource, action, exception).for_json
|
@@ -234,8 +216,6 @@ class Chef
|
|
234
216
|
# (see EventDispatch::Base#)
|
235
217
|
#
|
236
218
|
def resource_completed(new_resource)
|
237
|
-
return if consumers.empty?
|
238
|
-
|
239
219
|
current_record.elapsed_time = new_resource.elapsed_time
|
240
220
|
|
241
221
|
# Verify if the resource has sensitive data and create a new blank resource with only
|
data/lib/chef/application.rb
CHANGED
@@ -310,7 +310,7 @@ class Chef
|
|
310
310
|
logger.info "Forking #{ChefUtils::Dist::Infra::PRODUCT} instance to converge..."
|
311
311
|
pid = fork do
|
312
312
|
# Want to allow forked processes to finish converging when
|
313
|
-
# TERM
|
313
|
+
# TERM signal is received (exit gracefully)
|
314
314
|
trap("TERM") do
|
315
315
|
logger.debug("SIGTERM received during converge," +
|
316
316
|
" finishing converge to exit normally (send SIGINT to terminate immediately)")
|
@@ -297,6 +297,21 @@ class Chef::Application::Base < Chef::Application
|
|
297
297
|
long: "--named-run-list NAMED_RUN_LIST",
|
298
298
|
description: "Use a policyfile's named run list instead of the default run list."
|
299
299
|
|
300
|
+
option :slow_report,
|
301
|
+
long: "--[no-]slow-report [COUNT]",
|
302
|
+
description: "List the slowest resources at the end of the run (default: 10).",
|
303
|
+
boolean: true,
|
304
|
+
default: false,
|
305
|
+
proc: lambda { |argument|
|
306
|
+
if argument.nil?
|
307
|
+
true
|
308
|
+
elsif argument == false
|
309
|
+
false
|
310
|
+
else
|
311
|
+
Integer(argument)
|
312
|
+
end
|
313
|
+
}
|
314
|
+
|
300
315
|
IMMEDIATE_RUN_SIGNAL = "1".freeze
|
301
316
|
RECONFIGURE_SIGNAL = "H".freeze
|
302
317
|
|
data/lib/chef/client.rb
CHANGED
@@ -863,6 +863,12 @@ class Chef
|
|
863
863
|
end
|
864
864
|
|
865
865
|
def start_profiling
|
866
|
+
if Chef::Config[:slow_report]
|
867
|
+
require_relative "handler/slow_report"
|
868
|
+
|
869
|
+
Chef::Config.report_handlers << Chef::Handler::SlowReport.new(Chef::Config[:slow_report])
|
870
|
+
end
|
871
|
+
|
866
872
|
return unless Chef::Config[:profile_ruby]
|
867
873
|
|
868
874
|
profiling_prereqs!
|
@@ -138,11 +138,14 @@ class Chef
|
|
138
138
|
end
|
139
139
|
|
140
140
|
def recipe_yml_filenames_by_name
|
141
|
-
@
|
141
|
+
@recipe_yml_filenames_by_name ||= begin
|
142
142
|
name_map = yml_filenames_by_name(files_for("recipes"))
|
143
|
-
root_alias = cookbook_manifest.root_files.find { |record|
|
143
|
+
root_alias = cookbook_manifest.root_files.find { |record|
|
144
|
+
record[:name] == "root_files/recipe.yml" ||
|
145
|
+
record[:name] == "root_files/recipe.yaml"
|
146
|
+
}
|
144
147
|
if root_alias
|
145
|
-
Chef::Log.error("Cookbook #{name} contains both recipe.yml and
|
148
|
+
Chef::Log.error("Cookbook #{name} contains both recipe.yml and recipes/default.yml, ignoring recipes/default.yml") if name_map["default"]
|
146
149
|
name_map["default"] = root_alias[:full_path]
|
147
150
|
end
|
148
151
|
name_map
|
@@ -582,8 +585,27 @@ class Chef
|
|
582
585
|
records.select { |record| record[:name] =~ /\.rb$/ }.inject({}) { |memo, record| memo[File.basename(record[:name], ".rb")] = record[:full_path]; memo }
|
583
586
|
end
|
584
587
|
|
588
|
+
# Filters YAML files from the superset of provided files.
|
589
|
+
# Checks for duplicate basenames with differing extensions (eg yaml v yml)
|
590
|
+
# and raises error if any are detected.
|
591
|
+
# This prevents us from arbitrarily the ".yaml" or ".yml" version when both are present,
|
592
|
+
# because we don't know which is correct.
|
593
|
+
# This method runs in O(n^2) where N = number of yml files present. This number should be consistently
|
594
|
+
# low enough that there's no noticeable perf impact.
|
585
595
|
def yml_filenames_by_name(records)
|
586
|
-
records.select { |record| record[:name] =~ /\.
|
596
|
+
yml_files = records.select { |record| record[:name] =~ /\.(y[a]?ml)$/ }
|
597
|
+
result = yml_files.inject({}) do |acc, record|
|
598
|
+
filename = record[:name]
|
599
|
+
base_dup_name = File.join(File.dirname(filename), File.basename(filename, File.extname(filename)))
|
600
|
+
yml_files.each do |other|
|
601
|
+
if other[:name] =~ /#{(File.extname(filename) == ".yml") ? "#{base_dup_name}.yaml" : "#{base_dup_name}.yml"}$/
|
602
|
+
raise Chef::Exceptions::AmbiguousYAMLFile.new("Cookbook #{name}@#{version} contains ambiguous files: #{filename} and #{other[:name]}. Please update the cookbook to remove the incorrect file.")
|
603
|
+
end
|
604
|
+
end
|
605
|
+
acc[File.basename(record[:name], File.extname(record[:name]))] = record[:full_path]
|
606
|
+
acc
|
607
|
+
end
|
608
|
+
result
|
587
609
|
end
|
588
610
|
|
589
611
|
def file_vendor
|
data/lib/chef/data_bag.rb
CHANGED
@@ -32,7 +32,8 @@ class Chef
|
|
32
32
|
include Chef::Mixin::FromFile
|
33
33
|
include Chef::Mixin::ParamsValidate
|
34
34
|
|
35
|
-
|
35
|
+
# Regex reference: https://rubular.com/r/oIMySIO4USPm5x
|
36
|
+
VALID_NAME = /^[\-[:alnum:]_]+$/.freeze
|
36
37
|
RESERVED_NAMES = /^(node|role|environment|client)$/.freeze
|
37
38
|
|
38
39
|
def self.validate_name!(name)
|
data/lib/chef/data_bag_item.rb
CHANGED
@@ -36,7 +36,8 @@ class Chef
|
|
36
36
|
include Chef::Mixin::FromFile
|
37
37
|
include Chef::Mixin::ParamsValidate
|
38
38
|
|
39
|
-
|
39
|
+
# Regex reference: https://rubular.com/r/oIMySIO4USPm5x
|
40
|
+
VALID_ID = /^[\-[:alnum:]_]+$/.freeze
|
40
41
|
|
41
42
|
def self.validate_id!(id_str)
|
42
43
|
if id_str.nil? || ( id_str !~ VALID_ID )
|
data/lib/chef/data_collector.rb
CHANGED
@@ -51,7 +51,7 @@ class Chef
|
|
51
51
|
"id" => run_status&.run_id,
|
52
52
|
"message_version" => "1.1.0",
|
53
53
|
"message_type" => "run_converge",
|
54
|
-
"node" => node || {},
|
54
|
+
"node" => node&.data_for_save || {},
|
55
55
|
"node_name" => node&.name || data_collector.node_name,
|
56
56
|
"organization_name" => organization,
|
57
57
|
"resources" => all_action_records(action_collection),
|
data/lib/chef/deprecated.rb
CHANGED
@@ -221,7 +221,8 @@ class Chef
|
|
221
221
|
# Called before convergence starts
|
222
222
|
def converge_start(run_context); end
|
223
223
|
|
224
|
-
# Callback hook for handlers to
|
224
|
+
# Callback hook for handlers to grab a reference to the action_collection
|
225
|
+
# (sent before compiling cookbooks, consumers can also find it off the run_context.action_collection)
|
225
226
|
def action_collection_registration(action_collection); end
|
226
227
|
|
227
228
|
# Called when the converge phase is finished.
|
data/lib/chef/exceptions.rb
CHANGED
@@ -174,6 +174,9 @@ class Chef
|
|
174
174
|
class CannotDetermineWindowsInstallerType < Package; end
|
175
175
|
class NoWindowsPackageSource < Package; end
|
176
176
|
|
177
|
+
# for example, if both recipes/default.yml, recipes/default.yaml are present
|
178
|
+
class AmbiguousYAMLFile < RuntimeError; end
|
179
|
+
|
177
180
|
# Can not create staging file during file deployment
|
178
181
|
class FileContentStagingError < RuntimeError
|
179
182
|
def initialize(errors)
|
data/lib/chef/handler.rb
CHANGED
@@ -55,6 +55,12 @@ class Chef
|
|
55
55
|
#
|
56
56
|
class Handler
|
57
57
|
|
58
|
+
# FIXME: Chef::Handler should probably inherit from EventDispatch::Base
|
59
|
+
# and should wire up to those events rather than the "notifications" system
|
60
|
+
# which is hanging off of Chef::Client. Those "notifications" could then be
|
61
|
+
# deprecated in favor of events, and this class could become decoupled from
|
62
|
+
# the Chef::Client object.
|
63
|
+
|
58
64
|
def self.handler_for(*args)
|
59
65
|
if args.include?(:start)
|
60
66
|
Chef::Config[:start_handlers] ||= []
|
@@ -207,17 +213,45 @@ class Chef
|
|
207
213
|
# The Chef::Node for this client run
|
208
214
|
def_delegator :@run_status, :node
|
209
215
|
|
210
|
-
|
211
|
-
# :method: all_resources
|
216
|
+
# @return Array<Chef::Resource> all resources other than unprocessed
|
212
217
|
#
|
213
|
-
|
214
|
-
|
218
|
+
def all_resources
|
219
|
+
@all_resources ||= action_collection&.filtered_collection(unprocessed: false)&.resources || []
|
220
|
+
end
|
215
221
|
|
216
|
-
|
217
|
-
#
|
222
|
+
# @return Array<Chef::Resource> all updated resources
|
223
|
+
#
|
224
|
+
def updated_resources
|
225
|
+
@updated_resources ||= action_collection&.filtered_collection(up_to_date: false, skipped: false, failed: false, unprocessed: false)&.resources || []
|
226
|
+
end
|
227
|
+
|
228
|
+
# @return Array<Chef::Resource> all up_to_date resources
|
229
|
+
#
|
230
|
+
def up_to_date_resources
|
231
|
+
@up_to_date_resources ||= action_collection&.filtered_collection(updated: false, skipped: false, failed: false, unprocessed: false)&.resources || []
|
232
|
+
end
|
233
|
+
|
234
|
+
# @return Array<Chef::Resource> all failed resources
|
218
235
|
#
|
219
|
-
|
220
|
-
|
236
|
+
def failed_resources
|
237
|
+
@failed_resources ||= action_collection&.filtered_collection(updated: false, up_to_date: false, skipped: false, unprocessed: false)&.resources || []
|
238
|
+
end
|
239
|
+
|
240
|
+
# @return Array<Chef::Resource> all skipped resources
|
241
|
+
#
|
242
|
+
def skipped_resources
|
243
|
+
@skipped_resources ||= action_collection&.filtered_collection(updated: false, up_to_date: false, failed: false, unprocessed: false)&.resources || []
|
244
|
+
end
|
245
|
+
|
246
|
+
# Unprocessed resources are those which are left over in the outer recipe context when a run fails.
|
247
|
+
# Sub-resources of unprocessed resourced are impossible to capture because they would require processing
|
248
|
+
# the outer resource.
|
249
|
+
#
|
250
|
+
# @return Array<Chef::Resource> all unprocessed resources
|
251
|
+
#
|
252
|
+
def unprocessed_resources
|
253
|
+
@unprocessed_resources ||= action_collection&.filtered_collection(updated: false, up_to_date: false, failed: false, skipped: false)&.resources || []
|
254
|
+
end
|
221
255
|
|
222
256
|
##
|
223
257
|
# :method: success?
|
@@ -232,6 +266,10 @@ class Chef
|
|
232
266
|
# Did the chef run fail? True if the chef run raised an uncaught exception
|
233
267
|
def_delegator :@run_status, :failed?
|
234
268
|
|
269
|
+
def action_collection
|
270
|
+
@run_status.run_context.action_collection
|
271
|
+
end
|
272
|
+
|
235
273
|
# The main entry point for report handling. Subclasses should override this
|
236
274
|
# method with their own report handling logic.
|
237
275
|
def report; end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) Chef Software Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require_relative "../handler"
|
19
|
+
require "tty/table" unless defined?(TTY::Table)
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class Handler
|
23
|
+
class SlowReport < ::Chef::Handler
|
24
|
+
attr_accessor :amount
|
25
|
+
|
26
|
+
def initialize(amount)
|
27
|
+
@amount = Integer(amount) rescue nil
|
28
|
+
@amount ||= 10
|
29
|
+
end
|
30
|
+
|
31
|
+
def report
|
32
|
+
if count == 0
|
33
|
+
puts "\nNo resources to profile\n\n"
|
34
|
+
return
|
35
|
+
end
|
36
|
+
|
37
|
+
top = all_records.sort_by(&:elapsed_time).last(amount).reverse
|
38
|
+
data = top.map { |r| [ r.new_resource.to_s, r.elapsed_time, r.action, r.new_resource.cookbook_name, r.new_resource.recipe_name, stripped_source_line(r.new_resource) ] }
|
39
|
+
puts "\nTop #{count} slowest #{count == 1 ? "resource" : "resources"}:\n\n"
|
40
|
+
table = TTY::Table.new(%w{resource elapsed_time action cookbook recipe source}, data)
|
41
|
+
rendered = table.render do |renderer|
|
42
|
+
renderer.border do
|
43
|
+
mid "-"
|
44
|
+
mid_mid " "
|
45
|
+
end
|
46
|
+
end
|
47
|
+
puts rendered
|
48
|
+
puts "\n"
|
49
|
+
end
|
50
|
+
|
51
|
+
def all_records
|
52
|
+
@all_records ||= action_collection&.filtered_collection(unprocessed: false) || []
|
53
|
+
end
|
54
|
+
|
55
|
+
def count
|
56
|
+
num = all_resources.count
|
57
|
+
num > amount ? amount : num
|
58
|
+
end
|
59
|
+
|
60
|
+
def stripped_source_line(resource)
|
61
|
+
# strip the leading path off of the source line
|
62
|
+
resource.source_line.gsub(%r{.*/cookbooks/}, "").gsub(%r{.*/chef-[0-9\.]+/}, "")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|