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.
- checksums.yaml +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +44 -0
- data/Rakefile +2 -0
- data/lib/voxer-chef-formatter.rb +279 -0
- data/voxer-chef-formatter.gemspec +24 -0
- metadata +79 -0
checksums.yaml
ADDED
|
@@ -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
data/LICENSE.txt
ADDED
|
@@ -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.
|
data/README.md
ADDED
|
@@ -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
|
data/Rakefile
ADDED
|
@@ -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: []
|