Class: Chef::Formatters::Doc

Inherits:
Base show all
Defined in:
lib/chef/formatters/doc.rb

Overview

Formatter similar to RSpec's documentation formatter. Uses indentation to show context.

Instance Attribute Summary collapse

Attributes inherited from Base

#err, #out, #output

Instance Method Summary collapse

Methods inherited from Base

#attribute_file_load_failed, #attribute_file_loaded, cli_name, #cookbook_sync_failed, #definition_file_load_failed, #definition_file_loaded, #display_error, #file_load_failed, #indent_by, #is_formatter?, #is_structured_deprecation?, #library_file_load_failed, #library_file_loaded, #lwrp_file_load_failed, #lwrp_file_loaded, #print, #puts, #puts_line, #recipe_file_load_failed, #recipe_file_loaded, #recipe_not_found, #registration_failed, #run_list_expand_failed, #start_line

Methods included from ErrorMapper

cookbook_resolution_failed, cookbook_sync_failed, file_load_failed, node_load_failed, registration_failed, resource_failed, run_list_expand_failed

Methods inherited from EventDispatch::Base

#attribute_changed, #attribute_file_load_failed, #attribute_file_loaded, #attribute_load_complete, #attribute_load_start, #control_group_started, #cookbook_sync_failed, #definition_file_load_failed, #definition_file_loaded, #definition_load_complete, #definition_load_start, #library_file_load_failed, #library_file_loaded, #library_load_complete, #lwrp_file_load_failed, #lwrp_file_loaded, #lwrp_load_complete, #lwrp_load_start, #msg, #ohai_plugin_file_load_failed, #ohai_plugin_file_loaded, #ohai_plugin_load_complete, #ohai_plugin_load_start, #recipe_file_load_failed, #recipe_file_loaded, #recipe_load_start, #recipe_not_found, #registration_failed, #resource_completed, #run_list_expand_failed, #run_list_expanded, #run_started, #stream_closed, #stream_opened

Constructor Details

#initialize(out, err) ⇒ Doc

Returns a new instance of Doc


16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/chef/formatters/doc.rb', line 16

def initialize(out, err)
  super

  @updated_resources = 0
  @up_to_date_resources = 0
  @successful_audits = 0
  @failed_audits = 0
  @start_time = Time.now
  @end_time = @start_time
  @skipped_resources = 0
  @progress = {}
end

Instance Attribute Details

#end_timeObject (readonly)

Returns the value of attribute end_time


11
12
13
# File 'lib/chef/formatters/doc.rb', line 11

def end_time
  @end_time
end

#start_timeObject (readonly)

Returns the value of attribute start_time


11
12
13
# File 'lib/chef/formatters/doc.rb', line 11

def start_time
  @start_time
end

Instance Method Details

#audit_phase_complete(audit_output) ⇒ Object


247
248
249
250
# File 'lib/chef/formatters/doc.rb', line 247

def audit_phase_complete(audit_output)
  puts_line audit_output
  puts_line "Auditing complete"
end

#audit_phase_failed(error, audit_output) ⇒ Object


252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/chef/formatters/doc.rb', line 252

def audit_phase_failed(error, audit_output)
  puts_line audit_output
  puts_line ""
  puts_line "Audit phase exception:"
  indent
  puts_line "#{error.message}"
  if error.backtrace
    error.backtrace.each do |l|
      puts_line l
    end
  end
end

#audit_phase_start(run_status) ⇒ Object

Called before audit phase starts


243
244
245
# File 'lib/chef/formatters/doc.rb', line 243

def audit_phase_start(run_status)
  puts_line "Starting audit phase"
end

#control_example_failure(control_group_name, example_data, error) ⇒ Object


269
270
271
# File 'lib/chef/formatters/doc.rb', line 269

def control_example_failure(control_group_name, example_data, error)
  @failed_audits += 1
end

#control_example_success(control_group_name, example_data) ⇒ Object


265
266
267
# File 'lib/chef/formatters/doc.rb', line 265

def control_example_success(control_group_name, example_data)
  @successful_audits += 1
end

#converge_completeObject

Called when the converge phase is finished.


233
234
235
# File 'lib/chef/formatters/doc.rb', line 233

def converge_complete
  unindent if @current_recipe
end

#converge_failed(e) ⇒ Object


237
238
239
240
# File 'lib/chef/formatters/doc.rb', line 237

def converge_failed(e)
  # Currently a failed converge is handled the same way as a successful converge
  converge_complete
end

#converge_start(run_context) ⇒ Object

Called before convergence starts


228
229
230
# File 'lib/chef/formatters/doc.rb', line 228

def converge_start(run_context)
  puts_line "Converging #{run_context.resource_collection.all_resources.size} resources"
end

#cookbook_clean_completeObject

Called when cookbook cleaning is finished.


165
166
# File 'lib/chef/formatters/doc.rb', line 165

def cookbook_clean_complete
end

#cookbook_clean_startObject

Called before unneeded cookbooks are removed


155
156
# File 'lib/chef/formatters/doc.rb', line 155

def cookbook_clean_start
end

#cookbook_gem_failed(exception) ⇒ Object

Called when cookbook gem installation fails


210
211
212
# File 'lib/chef/formatters/doc.rb', line 210

def cookbook_gem_failed(exception)
  unindent
end

#cookbook_gem_finishedObject

Called when finished installing cookbook gems


205
206
207
# File 'lib/chef/formatters/doc.rb', line 205

def cookbook_gem_finished
  unindent
end

#cookbook_gem_installing(gem, version) ⇒ Object

Called when the result of installing the bundle is to install the gem


195
196
197
# File 'lib/chef/formatters/doc.rb', line 195

def cookbook_gem_installing(gem, version)
  puts_line "- Installing #{gem} #{version}", :green
end

#cookbook_gem_start(gems) ⇒ Object

Called when starting to collect gems from the cookbooks


189
190
191
192
# File 'lib/chef/formatters/doc.rb', line 189

def cookbook_gem_start(gems)
  puts_line "Installing Cookbook Gems:"
  indent
end

#cookbook_gem_using(gem, version) ⇒ Object

Called when the result of installing the bundle is to use the gem


200
201
202
# File 'lib/chef/formatters/doc.rb', line 200

def cookbook_gem_using(gem, version)
  puts_line "- Using #{gem} #{version}"
end

#cookbook_resolution_complete(cookbook_collection) ⇒ Object

Called when the cookbook collection is returned from the server.


151
152
# File 'lib/chef/formatters/doc.rb', line 151

def cookbook_resolution_complete(cookbook_collection)
end

#cookbook_resolution_failed(expanded_run_list, exception) ⇒ Object

Called when there is an error getting the cookbook collection from the server.


146
147
148
# File 'lib/chef/formatters/doc.rb', line 146

def cookbook_resolution_failed(expanded_run_list, exception)
  super
end

#cookbook_resolution_start(expanded_run_list) ⇒ Object

Called before the cookbook collection is fetched from the server.


140
141
142
# File 'lib/chef/formatters/doc.rb', line 140

def cookbook_resolution_start(expanded_run_list)
  puts_line "resolving cookbooks for run list: #{expanded_run_list.inspect}"
end

#cookbook_sync_completeObject

Called after all cookbooks have been sync'd.


184
185
186
# File 'lib/chef/formatters/doc.rb', line 184

def cookbook_sync_complete
  unindent
end

#cookbook_sync_start(cookbook_count) ⇒ Object

Called before cookbook sync starts


169
170
171
172
# File 'lib/chef/formatters/doc.rb', line 169

def cookbook_sync_start(cookbook_count)
  puts_line "Synchronizing Cookbooks:"
  indent
end

#deprecation(message, location = caller(2..2)[0]) ⇒ Object


417
418
419
420
421
422
423
424
425
426
427
428
429
430
# File 'lib/chef/formatters/doc.rb', line 417

def deprecation(message, location = caller(2..2)[0])
  if Chef::Config[:treat_deprecation_warnings_as_errors]
    super
  end

  # Save deprecations to the screen until the end
  if is_structured_deprecation?(message)
    url = message.url
    message = message.message
  end

  deprecations[message] ||= { url: url, locations: Set.new }
  deprecations[message][:locations] << location
end

#elapsed_timeObject


29
30
31
# File 'lib/chef/formatters/doc.rb', line 29

def elapsed_time
  end_time - start_time
end

#file_loaded(path) ⇒ Object

Called after a file in a cookbook is loaded.


220
221
# File 'lib/chef/formatters/doc.rb', line 220

def file_loaded(path)
end

#handler_executed(handler) ⇒ Object

Called after an individual handler has run


389
390
391
# File 'lib/chef/formatters/doc.rb', line 389

def handler_executed(handler)
  puts_line "- #{handler.class.name}"
end

#handlers_completedObject

Called after all handlers have executed


394
395
396
397
# File 'lib/chef/formatters/doc.rb', line 394

def handlers_completed
  unindent
  puts_line "Running handlers complete\n"
end

#handlers_start(handler_count) ⇒ Object

Called before handlers run


382
383
384
385
386
# File 'lib/chef/formatters/doc.rb', line 382

def handlers_start(handler_count)
  puts ""
  puts "Running handlers:"
  indent
end

#indentObject


432
433
434
# File 'lib/chef/formatters/doc.rb', line 432

def indent
  indent_by(2)
end

#library_load_start(file_count) ⇒ Object

Called when cookbook loading starts.


215
216
217
# File 'lib/chef/formatters/doc.rb', line 215

def library_load_start(file_count)
  puts_line "Compiling Cookbooks..."
end

#node_load_completed(node, expanded_run_list, config) ⇒ Object

Default and override attrs from roles have been computed, but not yet applied. Normal attrs from JSON have been added to the node.


132
133
# File 'lib/chef/formatters/doc.rb', line 132

def node_load_completed(node, expanded_run_list, config)
end

#node_load_failed(node_name, exception, config) ⇒ Object

Failed to load node data from the server


126
127
128
# File 'lib/chef/formatters/doc.rb', line 126

def node_load_failed(node_name, exception, config)
  super
end

#node_load_start(node_name, config) ⇒ Object


122
123
# File 'lib/chef/formatters/doc.rb', line 122

def node_load_start(node_name, config)
end

#ohai_completed(node) ⇒ Object

Called right after ohai runs.


107
108
# File 'lib/chef/formatters/doc.rb', line 107

def ohai_completed(node)
end

#output_record(line) ⇒ Object


341
342
# File 'lib/chef/formatters/doc.rb', line 341

def output_record(line)
end

#policyfile_loaded(policy) ⇒ Object


135
136
137
# File 'lib/chef/formatters/doc.rb', line 135

def policyfile_loaded(policy)
  puts_line "Using policy '#{policy["name"]}' at revision '#{policy["revision_id"]}'"
end

#pretty_elapsed_timeObject


33
34
35
36
37
38
39
40
41
42
43
# File 'lib/chef/formatters/doc.rb', line 33

def pretty_elapsed_time
  time = elapsed_time
  if time < 60
    message = Time.at(time).utc.strftime("%S seconds")
  elsif time < 3600
    message = Time.at(time).utc.strftime("%M minutes %S seconds")
  else
    message = Time.at(time).utc.strftime("%H hours %M minutes %S seconds")
  end
  message
end

#provider_requirement_failed(action, resource, exception, message) ⇒ Object

Called when an assertion declared by a provider fails


409
410
411
412
413
414
415
# File 'lib/chef/formatters/doc.rb', line 409

def provider_requirement_failed(action, resource, exception, message)
  return unless message
  color = Chef::Config[:why_run] ? :yellow : :red
  [ message ].flatten.each do |line|
    start_line("* #{line}", color)
  end
end

#recipe_load_completeObject

Called when recipes have been loaded.


224
225
# File 'lib/chef/formatters/doc.rb', line 224

def recipe_load_complete
end

#registration_completedObject


119
120
# File 'lib/chef/formatters/doc.rb', line 119

def registration_completed
end

#registration_start(node_name, config) ⇒ Object

About to attempt to register as +node_name+


115
116
117
# File 'lib/chef/formatters/doc.rb', line 115

def registration_start(node_name, config)
  puts_line "Creating a new client identity for #{node_name} using the validator key."
end

#removed_cookbook_file(path) ⇒ Object

Called after the file at +path+ is removed. It may be removed if the cookbook containing it was removed from the run list, or if the file was removed from the cookbook.


161
162
# File 'lib/chef/formatters/doc.rb', line 161

def removed_cookbook_file(path)
end

#resource_action_start(resource, action, notification_type = nil, notifier = nil) ⇒ Object

Called before action is executed on a resource.


274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
# File 'lib/chef/formatters/doc.rb', line 274

def resource_action_start(resource, action, notification_type = nil, notifier = nil)
  if resource.cookbook_name && resource.recipe_name
    resource_recipe = "#{resource.cookbook_name}::#{resource.recipe_name}"
  else
    resource_recipe = "<Dynamically Defined Resource>"
  end

  if resource_recipe != @current_recipe && !resource.enclosing_provider
    unindent if @current_recipe
    puts_line "Recipe: #{resource_recipe}"
    @current_recipe = resource_recipe
    indent
  end
  # TODO: info about notifies
  start_line "* #{resource} action #{action}", :stream => resource
  indent
end

#resource_bypassed(resource, action, provider) ⇒ Object


336
337
338
339
# File 'lib/chef/formatters/doc.rb', line 336

def resource_bypassed(resource, action, provider)
  puts " (Skipped: whyrun not supported by provider #{provider.class.name})", :stream => resource
  unindent
end

#resource_current_state_load_bypassed(resource, action, current_resource) ⇒ Object

Called when resource current state load is skipped due to the provider not supporting whyrun mode.


373
374
375
# File 'lib/chef/formatters/doc.rb', line 373

def resource_current_state_load_bypassed(resource, action, current_resource)
  puts_line("* Whyrun not supported for #{resource}, bypassing load.", :yellow)
end

#resource_current_state_loaded(resource, action, current_resource) ⇒ Object

Called after #load_current_resource has run.


326
327
# File 'lib/chef/formatters/doc.rb', line 326

def resource_current_state_loaded(resource, action, current_resource)
end

#resource_failed(resource, action, exception) ⇒ Object

Called when a resource fails and will not be retried.


312
313
314
315
# File 'lib/chef/formatters/doc.rb', line 312

def resource_failed(resource, action, exception)
  super
  unindent
end

#resource_failed_retriable(resource, action, retry_count, exception) ⇒ Object

Called when a resource fails, but will retry.


308
309
# File 'lib/chef/formatters/doc.rb', line 308

def resource_failed_retriable(resource, action, retry_count, exception)
end

#resource_skipped(resource, action, conditional) ⇒ Object

Called when a resource action has been skipped b/c of a conditional


318
319
320
321
322
323
# File 'lib/chef/formatters/doc.rb', line 318

def resource_skipped(resource, action, conditional)
  @skipped_resources += 1
  # TODO: more info about conditional
  puts " (skipped due to #{conditional.short_description})", :stream => resource
  unindent
end

#resource_up_to_date(resource, action) ⇒ Object

Called when a resource has no converge actions, e.g., it was already correct.


330
331
332
333
334
# File 'lib/chef/formatters/doc.rb', line 330

def resource_up_to_date(resource, action)
  @up_to_date_resources += 1
  puts " (up to date)", :stream => resource
  unindent
end

#resource_update_applied(resource, action, update) ⇒ Object

Called when a change has been made to a resource. May be called multiple times per resource, e.g., a file may have its content updated, and then its permissions updated.


347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
# File 'lib/chef/formatters/doc.rb', line 347

def resource_update_applied(resource, action, update)
  prefix = Chef::Config[:why_run] ? "Would " : ""
  Array(update).each do |line|
    next if line.nil?
    output_record line
    if line.kind_of? String
      start_line "- #{prefix}#{line}", :green
    elsif line.kind_of? Array
      # Expanded output - delta
      # @todo should we have a resource_update_delta callback?
      line.each do |detail|
        start_line detail, :white
      end
    end
  end
end

#resource_update_progress(resource, current, total, interval) ⇒ Object


292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/chef/formatters/doc.rb', line 292

def resource_update_progress(resource, current, total, interval)
  @progress[resource] ||= 0

  percent_complete = (current.to_f / total.to_f * 100).to_i

  if percent_complete > @progress[resource]

    @progress[resource] = percent_complete

    if percent_complete % interval == 0
      start_line " - Progress: #{percent_complete}%", :green
    end
  end
end

#resource_updated(resource, action) ⇒ Object

Called after a resource has been completely converged.


365
366
367
368
369
# File 'lib/chef/formatters/doc.rb', line 365

def resource_updated(resource, action)
  @updated_resources += 1
  unindent
  puts "\n"
end

#run_completed(node) ⇒ Object


58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/chef/formatters/doc.rb', line 58

def run_completed(node)
  @end_time = Time.now
  # Print out deprecations.
  if !deprecations.empty?
    puts_line ""
    puts_line "Deprecated features used!"
    deprecations.each do |message, details|
      locations = details[:locations]
      if locations.size == 1
        puts_line "  #{message} at 1 location:"
      else
        puts_line "  #{message} at #{locations.size} locations:"
      end
      locations.each do |location|
        prefix = "    - "
        Array(location).each do |line|
          puts_line "#{prefix}#{line}"
          prefix = "      "
        end
      end
      unless details[:url].nil?
        puts_line "   See #{details[:url]} for further details."
      end
    end
    puts_line ""
  end
  if Chef::Config[:why_run]
    puts_line "Chef Client finished, #{@updated_resources}/#{total_resources} resources would have been updated"
  else
    puts_line "Chef Client finished, #{@updated_resources}/#{total_resources} resources updated in #{pretty_elapsed_time}"
    if total_audits > 0
      puts_line "  #{successful_audits}/#{total_audits} controls succeeded"
    end
  end
end

#run_failed(exception) ⇒ Object


94
95
96
97
98
99
100
101
102
103
104
# File 'lib/chef/formatters/doc.rb', line 94

def run_failed(exception)
  @end_time = Time.now
  if Chef::Config[:why_run]
    puts_line "Chef Client failed. #{@updated_resources} resources would have been updated"
  else
    puts_line "Chef Client failed. #{@updated_resources} resources updated in #{pretty_elapsed_time}"
    if total_audits > 0
      puts_line "  #{successful_audits} controls succeeded"
    end
  end
end

#run_start(version) ⇒ Object


45
46
47
48
# File 'lib/chef/formatters/doc.rb', line 45

def run_start(version)
  puts_line "Starting Chef Client, version #{version}"
  puts_line "OpenSSL FIPS 140 mode enabled" if Chef::Config[:fips]
end

#skipping_registration(node_name, config) ⇒ Object

Already have a client key, assuming this node has registered.


111
112
# File 'lib/chef/formatters/doc.rb', line 111

def skipping_registration(node_name, config)
end

#stream_output(stream, output, options = {}) ⇒ Object


377
378
379
# File 'lib/chef/formatters/doc.rb', line 377

def stream_output(stream, output, options = {})
  print(output, { :stream => stream }.merge(options))
end

#synchronized_cookbook(cookbook_name, cookbook) ⇒ Object

Called when cookbook +cookbook+ has been sync'd


175
176
177
# File 'lib/chef/formatters/doc.rb', line 175

def synchronized_cookbook(cookbook_name, cookbook)
  puts_line "- #{cookbook.name} (#{cookbook.version})"
end

#total_auditsObject


54
55
56
# File 'lib/chef/formatters/doc.rb', line 54

def total_audits
  successful_audits + failed_audits
end

#total_resourcesObject


50
51
52
# File 'lib/chef/formatters/doc.rb', line 50

def total_resources
  @up_to_date_resources + @updated_resources + @skipped_resources
end

#unindentObject


436
437
438
# File 'lib/chef/formatters/doc.rb', line 436

def unindent
  indent_by(-2)
end

#updated_cookbook_file(cookbook_name, path) ⇒ Object

Called when an individual file in a cookbook has been updated


180
181
# File 'lib/chef/formatters/doc.rb', line 180

def updated_cookbook_file(cookbook_name, path)
end

#whyrun_assumption(action, resource, message) ⇒ Object

Called when a provider makes an assumption after a failed assertion in whyrun mode, in order to allow execution to continue


401
402
403
404
405
406
# File 'lib/chef/formatters/doc.rb', line 401

def whyrun_assumption(action, resource, message)
  return unless message
  [ message ].flatten.each do |line|
    start_line("* #{line}", :yellow)
  end
end