chef 10.14.0.beta.1 → 10.14.0.beta.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/distro/common/html/chef-client.8.html +3 -3
  2. data/distro/common/html/chef-expander.8.html +3 -3
  3. data/distro/common/html/chef-expanderctl.8.html +3 -3
  4. data/distro/common/html/chef-server-webui.8.html +3 -3
  5. data/distro/common/html/chef-server.8.html +3 -3
  6. data/distro/common/html/chef-solo.8.html +3 -3
  7. data/distro/common/html/chef-solr.8.html +3 -3
  8. data/distro/common/html/knife-bootstrap.1.html +3 -3
  9. data/distro/common/html/knife-client.1.html +3 -3
  10. data/distro/common/html/knife-configure.1.html +3 -3
  11. data/distro/common/html/knife-cookbook-site.1.html +3 -3
  12. data/distro/common/html/knife-cookbook.1.html +3 -3
  13. data/distro/common/html/knife-data-bag.1.html +3 -3
  14. data/distro/common/html/knife-environment.1.html +3 -3
  15. data/distro/common/html/knife-exec.1.html +3 -3
  16. data/distro/common/html/knife-index.1.html +4 -4
  17. data/distro/common/html/knife-node.1.html +3 -3
  18. data/distro/common/html/knife-role.1.html +3 -3
  19. data/distro/common/html/knife-search.1.html +5 -5
  20. data/distro/common/html/knife-ssh.1.html +4 -4
  21. data/distro/common/html/knife-status.1.html +4 -4
  22. data/distro/common/html/knife-tag.1.html +4 -4
  23. data/distro/common/html/knife.1.html +3 -3
  24. data/distro/common/html/shef.1.html +7 -7
  25. data/distro/common/man/man1/knife-bootstrap.1 +1 -1
  26. data/distro/common/man/man1/knife-client.1 +1 -1
  27. data/distro/common/man/man1/knife-configure.1 +1 -1
  28. data/distro/common/man/man1/knife-cookbook-site.1 +1 -1
  29. data/distro/common/man/man1/knife-cookbook.1 +1 -1
  30. data/distro/common/man/man1/knife-data-bag.1 +1 -1
  31. data/distro/common/man/man1/knife-environment.1 +1 -1
  32. data/distro/common/man/man1/knife-exec.1 +1 -1
  33. data/distro/common/man/man1/knife-index.1 +1 -1
  34. data/distro/common/man/man1/knife-node.1 +1 -1
  35. data/distro/common/man/man1/knife-role.1 +1 -1
  36. data/distro/common/man/man1/knife-search.1 +1 -1
  37. data/distro/common/man/man1/knife-ssh.1 +1 -1
  38. data/distro/common/man/man1/knife-status.1 +1 -1
  39. data/distro/common/man/man1/knife-tag.1 +1 -1
  40. data/distro/common/man/man1/knife.1 +1 -1
  41. data/distro/common/man/man1/shef.1 +1 -1
  42. data/distro/common/man/man8/chef-client.8 +1 -1
  43. data/distro/common/man/man8/chef-expander.8 +1 -1
  44. data/distro/common/man/man8/chef-expanderctl.8 +1 -1
  45. data/distro/common/man/man8/chef-server-webui.8 +1 -1
  46. data/distro/common/man/man8/chef-server.8 +1 -1
  47. data/distro/common/man/man8/chef-solo.8 +1 -1
  48. data/distro/common/man/man8/chef-solr.8 +1 -1
  49. data/lib/chef/event_dispatch/base.rb +4 -0
  50. data/lib/chef/formatters/base.rb +39 -56
  51. data/lib/chef/formatters/error_descriptor.rb +66 -0
  52. data/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb +2 -1
  53. data/lib/chef/formatters/error_inspectors/run_list_expansion_error_inspector.rb +3 -2
  54. data/lib/chef/formatters/error_mapper.rb +78 -0
  55. data/lib/chef/mixin/language_include_recipe.rb +1 -0
  56. data/lib/chef/provider.rb +5 -0
  57. data/lib/chef/provider/package/rubygems.rb +10 -0
  58. data/lib/chef/resource.rb +68 -12
  59. data/lib/chef/resource_reporter.rb +40 -16
  60. data/lib/chef/run_context.rb +37 -1
  61. data/lib/chef/runner.rb +2 -2
  62. data/lib/chef/version.rb +1 -1
  63. data/spec/unit/provider/deploy/revision_spec.rb +3 -2
  64. data/spec/unit/resource_reporter_spec.rb +36 -18
  65. data/spec/unit/resource_spec.rb +98 -3
  66. metadata +6 -4
@@ -0,0 +1,66 @@
1
+ #
2
+ # Author:: Tyler Cloke (<tyler@opscode.com>)
3
+ #
4
+ # Copyright:: Copyright (c) 2012 Opscode, Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ class Chef
21
+ module Formatters
22
+ # == Formatters::ErrorDescription
23
+ # Class for displaying errors on STDOUT.
24
+ class ErrorDescription
25
+
26
+ attr_reader :sections
27
+
28
+ def initialize(title)
29
+ @title = title
30
+ @sections = []
31
+ end
32
+
33
+ def section(heading, text)
34
+ @sections << [heading, text]
35
+ end
36
+
37
+ def display(out)
38
+ out.puts "=" * 80
39
+ out.puts @title, :red
40
+ out.puts "=" * 80
41
+ out.puts "\n"
42
+ sections.each do |section|
43
+ display_section(section, out)
44
+ end
45
+ end
46
+
47
+ def for_json()
48
+ {
49
+ 'title' => @title,
50
+ 'sections' => @sections
51
+ }
52
+ end
53
+
54
+ private
55
+
56
+ def display_section(section, out)
57
+ heading, text = section
58
+ out.puts heading
59
+ out.puts "-" * heading.size
60
+ out.puts text
61
+ out.puts "\n"
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -1,5 +1,6 @@
1
1
  #--
2
2
  # Author:: Daniel DeLeo (<dan@opscode.com>)
3
+ # Author:: Tyler Cloke (<tyler@opscode.com>)
3
4
  # Copyright:: Copyright (c) 2012 Opscode, Inc.
4
5
  # License:: Apache License, Version 2.0
5
6
  #
@@ -84,7 +85,7 @@ class Chef
84
85
  end
85
86
 
86
87
  def filtered_bt
87
- exception.backtrace.select {|l| l =~ /^#{Chef::Config.file_cache_path}/ }
88
+ Array( exception.backtrace ).select {|l| l =~ /^#{Chef::Config.file_cache_path}/ }
88
89
  end
89
90
 
90
91
  private
@@ -1,14 +1,15 @@
1
1
  #--
2
2
  # Author:: Daniel DeLeo (<dan@opscode.com>)
3
+ # Author:: Tyler Cloke (<tyler@opscode.com>)
3
4
  # Copyright:: Copyright (c) 2012 Opscode, Inc.
4
5
  # License:: Apache License, Version 2.0
5
6
  #
6
7
  # Licensed under the Apache License, Version 2.0 (the "License");
7
8
  # you may not use this file except in compliance with the License.
8
9
  # You may obtain a copy of the License at
9
- #
10
+ #
10
11
  # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
+ #
12
13
  # Unless required by applicable law or agreed to in writing, software
13
14
  # distributed under the License is distributed on an "AS IS" BASIS,
14
15
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -0,0 +1,78 @@
1
+ #--
2
+ # Author:: Tyler Cloke (<tyler@opscode.com>)
3
+ # Copyright:: Copyright (c) 2012 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
+
19
+ class Chef
20
+ module Formatters
21
+ # == Formatters::ErrorMapper
22
+ # Collection of methods for creating and returning
23
+ # Formatters::ErrorDescription objects based on node,
24
+ # exception, and configuration information.
25
+ module ErrorMapper
26
+
27
+ # Failed to register this client with the server.
28
+ def self.registration_failed_helper(node_name, exception, config)
29
+ error_inspector = ErrorInspectors::RegistrationErrorInspector.new(node_name, exception, config)
30
+ headline = "Chef encountered an error attempting to create the client \"#{node_name}\""
31
+ description = ErrorDescription.new(headline)
32
+ error_inspector.add_explanation(description)
33
+ return description
34
+ end
35
+
36
+ def self.node_load_failed_helper(node_name, exception, config)
37
+ error_inspector = ErrorInspectors::NodeLoadErrorInspector.new(node_name, exception, config)
38
+ headline = "Chef encountered an error attempting to load the node data for \"#{node_name}\""
39
+ description = ErrorDescription.new(headline)
40
+ error_inspector.add_explanation(description)
41
+ return description
42
+ end
43
+
44
+ def self.run_list_expand_failed_helper(node, exception)
45
+ error_inspector = ErrorInspectors::RunListExpansionErrorInspector.new(node, exception)
46
+ headline = "Error expanding the run_list:"
47
+ description = ErrorDescription.new(headline)
48
+ error_inspector.add_explanation(description)
49
+ return description
50
+ end
51
+
52
+ def self.cookbook_resolution_failed_helper(expanded_run_list, exception)
53
+ error_inspector = ErrorInspectors::CookbookResolveErrorInspector.new(expanded_run_list, exception)
54
+ headline = "Error Resolving Cookbooks for Run List:"
55
+ description = ErrorDescription.new(headline)
56
+ error_inspector.add_explanation(description)
57
+ return description
58
+ end
59
+
60
+ def self.cookbook_sync_failed_helper(cookbooks, exception)
61
+ error_inspector = ErrorInspectors::CookbookSyncErrorInspector.new(cookbooks, exception)
62
+ headline = "Error Syncing Cookbooks:"
63
+ description = ErrorDescription.new(headline)
64
+ error_inspector.add_explanation(description)
65
+ return description
66
+ end
67
+
68
+ def self.resource_failed_helper(resource, action, exception)
69
+ error_inspector = ErrorInspectors::ResourceFailureInspector.new(resource, action, exception)
70
+ headline = "Error executing action `#{action}` on resource '#{resource}'"
71
+ description = ErrorDescription.new(headline)
72
+ error_inspector.add_explanation(description)
73
+ return description
74
+ end
75
+
76
+ end
77
+ end
78
+ end
@@ -48,6 +48,7 @@ class Chef
48
48
 
49
49
 
50
50
  def require_recipe(*args)
51
+ Chef::Log.warn("require_recipe is deprecated and will be removed in a future release, please use include_recipe")
51
52
  include_recipe(*args)
52
53
  end
53
54
 
@@ -79,6 +79,9 @@ class Chef
79
79
  def define_resource_requirements
80
80
  end
81
81
 
82
+ def cleanup_after_converge
83
+ end
84
+
82
85
  def action_nothing
83
86
  Chef::Log.debug("Doing nothing for #{@new_resource.to_s}")
84
87
  true
@@ -120,6 +123,8 @@ class Chef
120
123
  send("action_#{@action}")
121
124
  end
122
125
  converge
126
+
127
+ cleanup_after_converge
123
128
  end
124
129
 
125
130
  def process_resource_requirements
@@ -323,6 +323,7 @@ class Chef
323
323
  include Chef::Mixin::ShellOut
324
324
 
325
325
  attr_reader :gem_env
326
+ attr_reader :cleanup_gem_env
326
327
 
327
328
  def logger
328
329
  Chef::Log.logger
@@ -332,6 +333,7 @@ class Chef
332
333
 
333
334
  def initialize(new_resource, run_context=nil)
334
335
  super
336
+ @cleanup_gem_env = true
335
337
  if new_resource.gem_binary
336
338
  if new_resource.options && new_resource.options.kind_of?(Hash)
337
339
  msg = "options cannot be given as a hash when using an explicit gem_binary\n"
@@ -349,6 +351,7 @@ class Chef
349
351
  Chef::Log.debug("#{@new_resource} using gem '#{gem_location}'")
350
352
  else
351
353
  @gem_env = CurrentGemEnvironment.new
354
+ @cleanup_gem_env = false
352
355
  Chef::Log.debug("#{@new_resource} using gem from running ruby environment")
353
356
  end
354
357
  end
@@ -430,6 +433,13 @@ class Chef
430
433
  @current_resource
431
434
  end
432
435
 
436
+ def cleanup_after_converge
437
+ if @cleanup_gem_env
438
+ logger.debug { "#{@new_resource} resetting gem environment to default" }
439
+ Gem.clear_paths
440
+ end
441
+ end
442
+
433
443
  def candidate_version
434
444
  @candidate_version ||= begin
435
445
  if target_version_already_installed?
@@ -41,19 +41,34 @@ class Chef
41
41
  other_notification.resource == resource && other_notification.action == action
42
42
  end
43
43
 
44
+ # If resource and/or notifying_resource is not a resource object, this will look them up in the resource collection
45
+ # and fix the references from strings to actual Resource objects.
44
46
  def resolve_resource_reference(resource_collection)
45
- return resource if resource.kind_of?(Chef::Resource)
47
+ return resource if resource.kind_of?(Chef::Resource) && notifying_resource.kind_of?(Chef::Resource)
46
48
 
49
+ if not(resource.kind_of?(Chef::Resource))
50
+ fix_resource_reference(resource_collection)
51
+ end
52
+
53
+ if not(notifying_resource.kind_of?(Chef::Resource))
54
+ fix_notifier_reference(resource_collection)
55
+ end
56
+ end
57
+
58
+ # This will look up the resource if it is not a Resource Object. It will complain if it finds multiple
59
+ # resources, can't find a resource, or gets invalid syntax.
60
+ def fix_resource_reference(resource_collection)
47
61
  matching_resource = resource_collection.find(resource)
48
62
  if Array(matching_resource).size > 1
49
63
  msg = "Notification #{self} from #{notifying_resource} was created with a reference to multiple resources, "\
50
- "but can only notify one resource. Notifying resource was defined on #{notifying_resource.source_line}"
64
+ "but can only notify one resource. Notifying resource was defined on #{notifying_resource.source_line}"
51
65
  raise Chef::Exceptions::InvalidResourceReference, msg
52
66
  end
53
67
  self.resource = matching_resource
68
+
54
69
  rescue Chef::Exceptions::ResourceNotFound => e
55
70
  err = Chef::Exceptions::ResourceNotFound.new(<<-FAIL)
56
- Resource #{notifying_resource} is configured to notify resource #{resource} with action #{action}, \
71
+ resource #{notifying_resource} is configured to notify resource #{resource} with action #{action}, \
57
72
  but #{resource} cannot be found in the resource collection. #{notifying_resource} is defined in \
58
73
  #{notifying_resource.source_line}
59
74
  FAIL
@@ -64,6 +79,36 @@ FAIL
64
79
  Resource #{notifying_resource} is configured to notify resource #{resource} with action #{action}, \
65
80
  but #{resource.inspect} is not valid syntax to look up a resource in the resource collection. Notification \
66
81
  is defined near #{notifying_resource.source_line}
82
+ F
83
+ err.set_backtrace(e.backtrace)
84
+ raise err
85
+ end
86
+
87
+ # This will look up the notifying_resource if it is not a Resource Object. It will complain if it finds multiple
88
+ # resources, can't find a resource, or gets invalid syntax.
89
+ def fix_notifier_reference(resource_collection)
90
+ matching_notifier = resource_collection.find(notifying_resource)
91
+ if Array(matching_notifier).size > 1
92
+ msg = "Notification #{self} from #{notifying_resource} was created with a reference to multiple notifying "\
93
+ "resources, but can only originate from one resource. Destination resource was defined "\
94
+ "on #{resource.source_line}"
95
+ raise Chef::Exceptions::InvalidResourceReference, msg
96
+ end
97
+ self.notifying_resource = matching_notifier
98
+
99
+ rescue Chef::Exceptions::ResourceNotFound => e
100
+ err = Chef::Exceptions::ResourceNotFound.new(<<-FAIL)
101
+ Resource #{resource} is configured to receive notifications from #{notifying_resource} with action #{action}, \
102
+ but #{notifying_resource} cannot be found in the resource collection. #{resource} is defined in \
103
+ #{resource.source_line}
104
+ FAIL
105
+ err.set_backtrace(e.backtrace)
106
+ raise err
107
+ rescue Chef::Exceptions::InvalidResourceSpecification => e
108
+ err = Chef::Exceptions::InvalidResourceSpecification.new(<<-F)
109
+ Resource #{resource} is configured to receive notifications from #{notifying_resource} with action #{action}, \
110
+ but #{notifying_resource.inspect} is not valid syntax to look up a resource in the resource collection. Notification \
111
+ is defined near #{resource.source_line}
67
112
  F
68
113
  err.set_backtrace(e.backtrace)
69
114
  raise err
@@ -148,8 +193,6 @@ F
148
193
 
149
194
  # Each notify entry is a resource/action pair, modeled as an
150
195
  # Struct with a #resource and #action member
151
- attr_reader :immediate_notifications
152
- attr_reader :delayed_notifications
153
196
 
154
197
  def initialize(name, run_context=nil)
155
198
  @name = name
@@ -168,8 +211,6 @@ F
168
211
  @retry_delay = 2
169
212
  @not_if = []
170
213
  @only_if = []
171
- @immediate_notifications = Array.new
172
- @delayed_notifications = Array.new
173
214
  @source_line = nil
174
215
  @elapsed_time = 0
175
216
 
@@ -361,16 +402,24 @@ F
361
402
  # resolve_resource_reference on each in turn, causing them to
362
403
  # resolve lazy/forward references.
363
404
  def resolve_notification_references
364
- @immediate_notifications.each { |n| n.resolve_resource_reference(run_context.resource_collection) }
365
- @delayed_notifications.each {|n| n.resolve_resource_reference(run_context.resource_collection) }
405
+ run_context.immediate_notifications(self).each { |n| n.resolve_resource_reference(run_context.resource_collection) }
406
+ run_context.delayed_notifications(self).each {|n| n.resolve_resource_reference(run_context.resource_collection) }
366
407
  end
367
408
 
368
409
  def notifies_immediately(action, resource_spec)
369
- @immediate_notifications << Notification.new(resource_spec, action, self)
410
+ run_context.notifies_immediately(Notification.new(resource_spec, action, self))
370
411
  end
371
412
 
372
413
  def notifies_delayed(action, resource_spec)
373
- @delayed_notifications << Notification.new(resource_spec, action, self)
414
+ run_context.notifies_delayed(Notification.new(resource_spec, action, self))
415
+ end
416
+
417
+ def immediate_notifications
418
+ run_context.immediate_notifications(self)
419
+ end
420
+
421
+ def delayed_notifications
422
+ run_context.delayed_notifications(self)
374
423
  end
375
424
 
376
425
  def resources(*args)
@@ -380,7 +429,13 @@ F
380
429
  def subscribes(action, resources, timing=:delayed)
381
430
  resources = [resources].flatten
382
431
  resources.each do |resource|
383
- resource.notifies(action, self, timing)
432
+ if resource.is_a?(String)
433
+ resource = Chef::Resource.new(resource, run_context)
434
+ end
435
+ if resource.run_context.nil?
436
+ resource.run_context = run_context
437
+ end
438
+ resource.add_notification(action, self, timing)
384
439
  end
385
440
  true
386
441
  end
@@ -551,6 +606,7 @@ F
551
606
  raise customize_exception(e)
552
607
  end
553
608
  ensure
609
+ events.resource_completed(self)
554
610
  @elapsed_time = Time.now - start_time
555
611
  end
556
612
  end
@@ -1,6 +1,7 @@
1
1
  #
2
2
  # Author:: Daniel DeLeo (<dan@opscode.com>)
3
3
  # Author:: Prajakta Purohit (prajakta@opscode.com>)
4
+ # Auther:: Tyler Cloke (<tyler@opscode.com>)
4
5
  #
5
6
  # Copyright:: Copyright (c) 2012 Opscode, Inc.
6
7
  # License:: Apache License, Version 2.0
@@ -24,6 +25,8 @@ require 'chef/event_dispatch/base'
24
25
  class Chef
25
26
  class ResourceReporter < EventDispatch::Base
26
27
 
28
+
29
+
27
30
  class ResourceReport < Struct.new(:new_resource,
28
31
  :current_resource,
29
32
  :action,
@@ -51,7 +54,7 @@ class Chef
51
54
  as_hash["name"] = new_resource.name
52
55
  as_hash["id"] = new_resource.identity
53
56
  as_hash["after"] = new_resource.state
54
- as_hash["before"] = current_resource.state if current_resource
57
+ as_hash["before"] = current_resource ? current_resource.state : {}
55
58
  as_hash["duration"] = (elapsed_time * 1000).to_i.to_s
56
59
  # TODO: include diffs, etc. here:
57
60
  as_hash["delta"] = ""
@@ -80,6 +83,7 @@ class Chef
80
83
  attr_reader :status
81
84
  attr_reader :exception
82
85
  attr_reader :run_id
86
+ attr_reader :error_descriptions
83
87
 
84
88
  def initialize(rest_client)
85
89
  @reporting_enabled = true
@@ -91,6 +95,7 @@ class Chef
91
95
  @run_id = nil
92
96
  @rest_client = rest_client
93
97
  @node = nil
98
+ @error_descriptions = nil
94
99
  end
95
100
 
96
101
  def node_load_completed(node, expanded_run_list_with_versions, config)
@@ -99,6 +104,7 @@ class Chef
99
104
  server_response = @rest_client.post_rest(resource_history_url, {:action => :begin})
100
105
  run_uri = URI.parse(server_response["uri"])
101
106
  @run_id = ::File.basename(run_uri.path)
107
+ Chef::Log.info("Chef server generated run history id: #{@run_id}")
102
108
  rescue Net::HTTPServerException => e
103
109
  raise unless e.response.code.to_s == "404"
104
110
  Chef::Log.debug("Received 404 attempting to generate run history id (URL Path: #{resource_history_url}), assuming feature is not supported.")
@@ -118,11 +124,11 @@ class Chef
118
124
 
119
125
  def resource_skipped(resource, action, conditional)
120
126
  @total_res_count += 1
127
+ @pending_update = nil unless nested_resource?(resource)
121
128
  end
122
129
 
123
130
  def resource_updated(new_resource, action)
124
131
  @total_res_count += 1
125
- resource_completed unless nested_resource?(new_resource)
126
132
  end
127
133
 
128
134
  def resource_failed(new_resource, action, exception)
@@ -130,7 +136,16 @@ class Chef
130
136
  unless nested_resource?(new_resource)
131
137
  @pending_update ||= ResourceReport.new_for_exception(new_resource, action)
132
138
  @pending_update.exception = exception
133
- resource_completed
139
+ end
140
+ description = Formatters::ErrorMapper.resource_failed_helper(new_resource, action, exception)
141
+ @error_descriptions = description.for_json
142
+ end
143
+
144
+ def resource_completed(new_resource)
145
+ if @pending_update && !nested_resource?(new_resource)
146
+ @pending_update.finish
147
+ @updated_resources << @pending_update
148
+ @pending_update = nil
134
149
  end
135
150
  end
136
151
 
@@ -149,7 +164,7 @@ class Chef
149
164
 
150
165
  def run_failed(exception)
151
166
  @exception = exception
152
- @status = "failed"
167
+ @status = "failure"
153
168
  end
154
169
 
155
170
  def report(node)
@@ -160,17 +175,32 @@ class Chef
160
175
  run_data["status"] = status
161
176
  run_data["run_list"] = node.run_list.to_json
162
177
  run_data["total_res_count"] = @total_res_count.to_s
178
+ run_data["data"] = {}
163
179
  if exception
164
- run_data["exception"] = {}
165
- run_data["exception"]["class"] = exception.inspect
166
- run_data["exception"]["message"] = exception.message
167
- run_data["exception"]["backtrace"] = exception.backtrace
168
- run_data["exception"]["description"] = "FIXME: error inspection stuff should go here"
180
+ run_data["data"]["exception"] = {}
181
+ run_data["data"]["exception"]["class"] = exception.inspect
182
+ run_data["data"]["exception"]["message"] = exception.message
183
+ run_data["data"]["exception"]["backtrace"] = exception.backtrace
184
+ run_data["data"]["exception"]["description"] = @error_descriptions
169
185
  end
170
- run_data["data"] = {}
171
186
  run_data
172
187
  end
173
188
 
189
+ def run_list_expand_failed(node, exception)
190
+ description = Formatters::ErrorMapper.run_list_expand_failed_helper(node, exception)
191
+ @error_descriptions = description.for_json
192
+ end
193
+
194
+ def cookbook_resolution_failed(expanded_run_list, exception)
195
+ description = Formatters::ErrorMapper.cookbook_resolution_failed_helper(expanded_run_list, exception)
196
+ @error_descriptions = description.for_json
197
+ end
198
+
199
+ def cookbook_sync_failed(cookbooks, exception)
200
+ description = Formatters::ErrorMapper.cookbook_sync_failed_helper(cookbooks, exception)
201
+ @error_descriptions = description.for_json
202
+ end
203
+
174
204
  def reporting_enabled?
175
205
  @reporting_enabled
176
206
  end
@@ -185,11 +215,5 @@ class Chef
185
215
  @pending_update && @pending_update.new_resource != new_resource
186
216
  end
187
217
 
188
- def resource_completed
189
- @pending_update.finish
190
- @updated_resources << @pending_update
191
- @pending_update = nil
192
- end
193
-
194
218
  end
195
219
  end