voxer-chef-formatter 0.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8b027873422ba551983712a16398b4673f839255
4
+ data.tar.gz: d336eba018d851b53f438d93f0c16867c0119302
5
+ SHA512:
6
+ metadata.gz: fae1f919656196d6dea691c41619e8cffebfeeee9502716568c990f2724b1efcec6db6a3394821a34e415413ad46b691e0b051c92ae6fd29cadc36fce382a51e
7
+ data.tar.gz: ffacac1103de51b31e6a940ea340109d44ae0296834b017a05747f6c519bbac9cc6de53ba0ca1e6dfd9a05070ca6cee58f05dcce01ed1316ee4d19ecc3a01c1c
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in voxer-chef-formatter.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright 2007-2014, Voxer, Inc
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,44 @@
1
+ Voxer::Chef::Formatter
2
+ ======================
3
+
4
+ Voxer's Chef Formatter improves the output of a chef-client or chef-solo run to be useful.
5
+
6
+ Features
7
+ --------
8
+
9
+ Based on the chef [minimal formatter](https://github.com/opscode/chef/blob/master/lib/chef/formatters/minimal.rb)
10
+
11
+ updates include
12
+
13
+ - live updates as resources are updated (output isn't queued until the end of the run)
14
+ - colorized diffs
15
+ - file written to at the end with status information if `ENV['VOXER_FORMATTER_FILE']` is set
16
+ - more verbose error messages
17
+
18
+ Note: this formatter is best used with log_level :warn
19
+
20
+ Installation
21
+ ------------
22
+
23
+ Add this line to your application's Gemfile:
24
+
25
+ ```ruby
26
+ gem 'voxer-chef-formatter'
27
+ ```
28
+
29
+ And then execute:
30
+
31
+ $ bundle
32
+
33
+ Or install it yourself as:
34
+
35
+ $ gem install voxer-chef-formatter
36
+
37
+ Contributing
38
+ ------------
39
+
40
+ 1. Fork it ( https://github.com/[my-github-username]/voxer-chef-formatter/fork )
41
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
42
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
43
+ 4. Push to the branch (`git push origin my-new-feature`)
44
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,279 @@
1
+ #
2
+ # Voxer Chef Formatter
3
+ #
4
+ # based on the chef `minimal` formatter
5
+ # https://github.com/opscode/chef/blob/master/lib/chef/formatters/minimal.rb
6
+ # updates include
7
+ # - live updates as resources are updated
8
+ # - colorized diff
9
+ # - file written to at the end with status information if `ENV['VOXER_FORMATTER_FILE']` is set
10
+ # - more verbose error messages
11
+ #
12
+ # This formatter is best used with log_level :warn
13
+ #
14
+ # Author:: Dave Eddy <dave@daveeddy.com>
15
+ # Copyright:: Copyright (c) 2007-2014, Voxer LLC
16
+ # License:: MIT
17
+ #
18
+
19
+ require 'chef/formatters/base'
20
+
21
+ class Chef
22
+ module Formatters
23
+ class Voxer < Formatters::Base
24
+ cli_name(:voxer)
25
+
26
+ COLOR_RED = "\e[31m"
27
+ COLOR_GREEN = "\e[32m"
28
+ COLOR_MAGENTA = "\e[35m"
29
+ COLOR_RESET = "\e[0m"
30
+
31
+ def initialize(out, err)
32
+ super
33
+ @start_time = Time.now
34
+ @updated_resources = 0
35
+ @updates_by_resource = Hash.new { |h, k| h[k] = [] }
36
+ end
37
+
38
+ # Called at the very start of a Chef Run
39
+ def run_start(version)
40
+ puts "starting chef, version #{version}"
41
+ end
42
+
43
+ # Called at the end of the Chef run.
44
+ def run_completed(node)
45
+ chef_dir = Chef::Config[:root_path]
46
+ now = Time.now
47
+ elapsed = (now - @start_time).round(2)
48
+ file = ENV['VOXER_FORMATTER_FILE']
49
+ unless file.nil?
50
+ data = {
51
+ :finished => now,
52
+ :elapsed => elapsed,
53
+ :dir => chef_dir,
54
+ :git => {
55
+ :branch => `git --git-dir #{chef_dir}/.git rev-parse --abbrev-ref HEAD 2>&1`.strip,
56
+ :commit => `git --git-dir #{chef_dir}/.git rev-parse HEAD 2>&1`.strip
57
+ }
58
+ }
59
+ IO.write(file, JSON.pretty_generate(data) + "\n")
60
+ end
61
+ puts "chef client finished. #{@updated_resources} resources updated, took #{elapsed} seconds"
62
+ end
63
+
64
+ # called at the end of a failed run
65
+ def run_failed(exception)
66
+ elapsed = (Time.now - @start_time).round(2)
67
+ puts "chef client failed. #{@updated_resources} resources updated, took #{elapsed} seconds"
68
+ end
69
+
70
+ # Called right after ohai runs.
71
+ def ohai_completed(node)
72
+ end
73
+
74
+ # Already have a client key, assuming this node has registered.
75
+ def skipping_registration(node_name, config)
76
+ end
77
+
78
+ # About to attempt to register as +node_name+
79
+ def registration_start(node_name, config)
80
+ end
81
+
82
+ def registration_completed
83
+ end
84
+
85
+ # Failed to register this client with the server.
86
+ def registration_failed(node_name, exception, config)
87
+ super
88
+ end
89
+
90
+ def node_load_start(node_name, config)
91
+ end
92
+
93
+ # Failed to load node data from the server
94
+ def node_load_failed(node_name, exception, config)
95
+ end
96
+
97
+ # Default and override attrs from roles have been computed, but not yet applied.
98
+ # Normal attrs from JSON have been added to the node.
99
+ def node_load_completed(node, expanded_run_list, config)
100
+ end
101
+
102
+ # Called before the cookbook collection is fetched from the server.
103
+ def cookbook_resolution_start(expanded_run_list)
104
+ puts "resolving cookbooks for run list: #{expanded_run_list.inspect}"
105
+ end
106
+
107
+ # Called when there is an error getting the cookbook collection from the
108
+ # server.
109
+ def cookbook_resolution_failed(expanded_run_list, exception)
110
+ end
111
+
112
+ # Called when the cookbook collection is returned from the server.
113
+ def cookbook_resolution_complete(cookbook_collection)
114
+ end
115
+
116
+ # Called before unneeded cookbooks are removed
117
+ def cookbook_clean_start
118
+ end
119
+
120
+ # Called after the file at +path+ is removed. It may be removed if the
121
+ # cookbook containing it was removed from the run list, or if the file was
122
+ # removed from the cookbook.
123
+ def removed_cookbook_file(path)
124
+ end
125
+
126
+ # Called when cookbook cleaning is finished.
127
+ def cookbook_clean_complete
128
+ end
129
+
130
+ # Called before cookbook sync starts
131
+ def cookbook_sync_start(cookbook_count)
132
+ puts 'synchronizing cookbooks'
133
+ end
134
+
135
+ # Called when cookbook +cookbook_name+ has been sync'd
136
+ def synchronized_cookbook(cookbook_name)
137
+ print '.'
138
+ end
139
+
140
+ # Called when an individual file in a cookbook has been updated
141
+ def updated_cookbook_file(cookbook_name, path)
142
+ end
143
+
144
+ # Called after all cookbooks have been sync'd.
145
+ def cookbook_sync_complete
146
+ puts 'done.'
147
+ end
148
+
149
+ # Called when cookbook loading starts.
150
+ def library_load_start(file_count)
151
+ puts 'compiling cookbooks'
152
+ end
153
+
154
+ # Called after a file in a cookbook is loaded.
155
+ def file_loaded(path)
156
+ print '.'
157
+ end
158
+
159
+ def file_load_failed(path, exception)
160
+ puts COLOR_RED
161
+ puts "failed to load file --> #{path}"
162
+ puts " --> #{exception}"
163
+ puts COLOR_RESET
164
+ super
165
+ end
166
+
167
+ # Called when recipes have been loaded.
168
+ def recipe_load_complete
169
+ puts 'done.'
170
+ end
171
+
172
+ # Called before convergence starts
173
+ def converge_start(run_context)
174
+ puts "converging #{run_context.resource_collection.all_resources.size} resources"
175
+ end
176
+
177
+ # Called when the converge phase is finished.
178
+ def converge_complete
179
+ end
180
+
181
+ # Called before action is executed on a resource.
182
+ def resource_action_start(resource, action, notification_type=nil, notifier=nil)
183
+ end
184
+
185
+ # Called when a resource fails, but will retry.
186
+ def resource_failed_retriable(resource, action, retry_count, exception)
187
+ end
188
+
189
+ # Called when a resource fails and will not be retried.
190
+ def resource_failed(resource, action, exception)
191
+ puts COLOR_RED
192
+ puts "failed to handle resource --> :#{action} #{resource}"
193
+ puts COLOR_RESET
194
+ puts "#{exception}"
195
+ end
196
+
197
+ # Called when a resource action has been skipped b/c of a conditional
198
+ def resource_skipped(resource, action, conditional)
199
+ end
200
+
201
+ # Called after #load_current_resource has run.
202
+ def resource_current_state_loaded(resource, action, current_resource)
203
+ end
204
+
205
+ # Called when a resource has no converge actions, e.g., it was already correct.
206
+ def resource_up_to_date(resource, action)
207
+ end
208
+
209
+ ## TODO: callback for assertion failures
210
+
211
+ ## TODO: callback for assertion fallback in why run
212
+
213
+ # Called when a change has been made to a resource. May be called multiple
214
+ # times per resource, e.g., a file may have its content updated, and then
215
+ # its permissions updated.
216
+ def resource_update_applied(resource, action, update)
217
+ @updates_by_resource[resource.name] << update
218
+ end
219
+
220
+ # Called after a resource has been completely converged.
221
+ def resource_updated(resource, action)
222
+ @updated_resources += 1
223
+
224
+ puts "* #{resource.to_s}"
225
+ @updates_by_resource[resource.name].each do |update|
226
+ u = Array(update)
227
+
228
+ # print what happened in green
229
+ puts "#{COLOR_GREEN} - #{u[0]}#{COLOR_RESET}"
230
+
231
+ if u[1].is_a?(Array) then
232
+ # most likely a diff
233
+ puts ''
234
+ puts colorize_diff(u[1]).join("\n")
235
+ end
236
+ end
237
+ puts ''
238
+ end
239
+
240
+ # Called before handlers run
241
+ def handlers_start(handler_count)
242
+ end
243
+
244
+ # Called after an individual handler has run
245
+ def handler_executed(handler)
246
+ end
247
+
248
+ # Called after all handlers have executed
249
+ def handlers_completed
250
+ end
251
+
252
+ # An uncategorized message. This supports the case that a user needs to
253
+ # pass output that doesn't fit into one of the callbacks above. Note that
254
+ # there's no semantic information about the content or importance of the
255
+ # message. That means that if you're using this too often, you should add a
256
+ # callback for it.
257
+ def msg(message)
258
+ end
259
+
260
+ # helper functions
261
+ def colorize_diff(diff)
262
+ diff.map do |l|
263
+ f = ' '
264
+ if l.start_with?('-') then
265
+ f += COLOR_RED
266
+ elsif l.start_with?('+') then
267
+ f += COLOR_GREEN
268
+ elsif l.start_with?('@') then
269
+ f += COLOR_MAGENTA
270
+ end
271
+ f += l
272
+ f += COLOR_RESET
273
+ f
274
+ end
275
+ end
276
+
277
+ end
278
+ end
279
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "voxer-chef-formatter"
7
+ spec.version = "0.0.1"
8
+ spec.authors = ["Michael Burns"]
9
+ spec.email = ["michael.burns@rackspace.com"]
10
+ spec.summary = %q{Chef Formatter based on Minimal.}
11
+ spec.description = %q{Improves the output of a chef run with colorized output and better error messages.}
12
+ spec.homepage = "https://github.com/mburns/voxer-chef-formatter"
13
+ spec.license = "MIT"
14
+
15
+ spec.rubyforge_project = "voxer-chef-formatter"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.7"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: voxer-chef-formatter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Michael Burns
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: Improves the output of a chef run with colorized output and better error
42
+ messages.
43
+ email:
44
+ - michael.burns@rackspace.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - Gemfile
50
+ - LICENSE.txt
51
+ - README.md
52
+ - Rakefile
53
+ - lib/voxer-chef-formatter.rb
54
+ - voxer-chef-formatter.gemspec
55
+ homepage: https://github.com/mburns/voxer-chef-formatter
56
+ licenses:
57
+ - MIT
58
+ metadata: {}
59
+ post_install_message:
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ requirements: []
74
+ rubyforge_project: voxer-chef-formatter
75
+ rubygems_version: 2.0.14
76
+ signing_key:
77
+ specification_version: 4
78
+ summary: Chef Formatter based on Minimal.
79
+ test_files: []