kitchen_hooks 1.6.3 → 1.7.0
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 +4 -4
- data/Readme.md +1 -0
- data/VERSION +1 -1
- data/etc/config.json +2 -1
- data/kitchen_hooks.gemspec +1 -1
- data/lib/kitchen_hooks/app.rb +30 -0
- data/lib/kitchen_hooks/helpers.rb +43 -0
- data/lib/kitchen_hooks/helpers/sync_servers.rb +64 -0
- data/lib/kitchen_hooks/main.rb +2 -1
- data/web/app/style/kitchen_hooks.css +4 -0
- data/web/public/vendor/img/sync.svg +12 -0
- data/web/views/app.erb +8 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57e367c61cc0d252a78fa6a7a934347f702b59bd
|
4
|
+
data.tar.gz: e3c96ae9eb5a51e064f968d564c7f90772ffd57e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0448e0bd79eddca8a029766ee64bfb6ce9767795492be28e13a91925c06b59ad1bfbe387d43f13097ffc4ddf6e01d06500db95e34124dd4c641a6222ebc7ab08
|
7
|
+
data.tar.gz: 37295349df30512542481063ddc17cf69a3c7fb0a171ddf7dcbe5bf664336fd1b72e4fe7420a5082fea59458b51e41dc071c1b9325a79efd17f0901116d85224
|
data/Readme.md
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.7.0
|
data/etc/config.json
CHANGED
data/kitchen_hooks.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.add_runtime_dependency 'daybreak', '~> 0.3'
|
18
18
|
s.add_runtime_dependency 'retryable', '~> 2'
|
19
19
|
s.add_runtime_dependency 'berkshelf', '~> 3'
|
20
|
-
s.add_runtime_dependency 'chef', '~>
|
20
|
+
s.add_runtime_dependency 'chef', '~> 12.0.0'
|
21
21
|
s.add_runtime_dependency 'thor', '~> 0'
|
22
22
|
s.add_runtime_dependency 'git', '~> 1.2'
|
23
23
|
s.add_runtime_dependency 'sinatra', '~> 1.4'
|
data/lib/kitchen_hooks/app.rb
CHANGED
@@ -9,6 +9,8 @@ require 'sinatra/base'
|
|
9
9
|
require_relative 'helpers'
|
10
10
|
require_relative 'metadata'
|
11
11
|
|
12
|
+
Thread.abort_on_exception = true
|
13
|
+
|
12
14
|
|
13
15
|
module KitchenHooks
|
14
16
|
class App < Sinatra::Application
|
@@ -23,6 +25,7 @@ module KitchenHooks
|
|
23
25
|
def self.tmp! dir ; @@tmp = dir end
|
24
26
|
|
25
27
|
def self.close!
|
28
|
+
@@sync_worker.kill
|
26
29
|
@@backlog_worker.kill
|
27
30
|
@@db.close
|
28
31
|
end
|
@@ -37,7 +40,18 @@ module KitchenHooks
|
|
37
40
|
end
|
38
41
|
end
|
39
42
|
|
43
|
+
def self.sync!
|
44
|
+
@@sync_worker = Thread.new do
|
45
|
+
loop do
|
46
|
+
process_sync
|
47
|
+
sleep @@sync_interval
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
40
53
|
def self.config! config
|
54
|
+
@@config = config
|
41
55
|
@@hipchat = nil
|
42
56
|
if config['hipchat']
|
43
57
|
@@hipchat = HipChat::Client.new config['hipchat']['token']
|
@@ -47,6 +61,7 @@ module KitchenHooks
|
|
47
61
|
@@knives = config['knives'].map do |_, knife|
|
48
62
|
Pathname.new(knife).expand_path.realpath.to_s
|
49
63
|
end
|
64
|
+
@@sync_interval = config.fetch 'sync_interval', 3600 # Hourly
|
50
65
|
end
|
51
66
|
|
52
67
|
get '/backlog' do
|
@@ -103,6 +118,7 @@ module KitchenHooks
|
|
103
118
|
color = case entry[:type]
|
104
119
|
when 'failure' ; 'red'
|
105
120
|
when 'release' ; 'purple'
|
121
|
+
when 'unsynced' ; 'yellow'
|
106
122
|
else ; 'green'
|
107
123
|
end
|
108
124
|
hipchat notification(entry), color
|
@@ -133,6 +149,20 @@ module KitchenHooks
|
|
133
149
|
end
|
134
150
|
|
135
151
|
|
152
|
+
def self.process_sync
|
153
|
+
sync = sync_servers(knives).status
|
154
|
+
|
155
|
+
if sync.nil?
|
156
|
+
mark "Couldn't sync Chef servers (unknown issue)", 'unsynced'
|
157
|
+
return
|
158
|
+
end
|
159
|
+
|
160
|
+
sync_tag = sync[:num_failures].zero? ? 'synced' : 'unsynced'
|
161
|
+
|
162
|
+
mark sync, sync_tag
|
163
|
+
end
|
164
|
+
|
165
|
+
|
136
166
|
def self.process event
|
137
167
|
if event.nil? # JSON parse failed
|
138
168
|
mark event, 'failure', 'Could not parse WebHook payload'
|
@@ -10,12 +10,43 @@ require 'berkshelf'
|
|
10
10
|
require 'sinatra/base'
|
11
11
|
require 'pmap'
|
12
12
|
|
13
|
+
require_relative 'helpers/sync_servers'
|
13
14
|
|
14
15
|
Celluloid.logger = nil
|
15
16
|
Berkshelf.logger = Logger.new $stdout
|
16
17
|
|
18
|
+
|
19
|
+
|
17
20
|
module KitchenHooks
|
18
21
|
class App < Sinatra::Application
|
22
|
+
|
23
|
+
def self.pluralize n, singular, plural=nil
|
24
|
+
plural = "#{singular}s" if plural.nil?
|
25
|
+
return "no #{plural}" if n.zero?
|
26
|
+
return "1 #{singular}" if n == 1
|
27
|
+
"#{n} #{plural}"
|
28
|
+
end
|
29
|
+
|
30
|
+
# http://stackoverflow.com/questions/4136248/how-to-generate-a-human-readable-time-range-using-ruby-on-rails
|
31
|
+
def self.humanize_seconds secs
|
32
|
+
[
|
33
|
+
[ 60, :seconds ],
|
34
|
+
[ 60, :minutes ],
|
35
|
+
[ 24, :hours ],
|
36
|
+
[ 1000, :days ]
|
37
|
+
].map { |count, name|
|
38
|
+
if secs > 0
|
39
|
+
secs, n = secs.divmod(count)
|
40
|
+
"#{n.to_i} #{name}"
|
41
|
+
end
|
42
|
+
}.compact.reverse.join(' ')
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.sync_servers knives
|
46
|
+
SyncServers.new knives
|
47
|
+
end
|
48
|
+
|
49
|
+
|
19
50
|
def self.report_error e, msg=nil
|
20
51
|
msg = e.message if msg.nil?
|
21
52
|
$stdout.puts msg
|
@@ -304,7 +335,19 @@ module KitchenHooks
|
|
304
335
|
def self.notification entry
|
305
336
|
return entry[:error] if entry[:error]
|
306
337
|
event = entry[:event]
|
338
|
+
|
307
339
|
case entry[:type]
|
340
|
+
when 'synced', 'unsynced'
|
341
|
+
if event.is_a? String
|
342
|
+
event
|
343
|
+
else
|
344
|
+
'Synced <b>%d</b> of <b>%d</b> nodes (%s, %s elapsed)' % [
|
345
|
+
event[:num_successes],
|
346
|
+
event[:num_nodes],
|
347
|
+
pluralize(event[:num_failures], 'failure'),
|
348
|
+
humanize_seconds(event[:elapsed])
|
349
|
+
]
|
350
|
+
end
|
308
351
|
when 'kitchen upload'
|
309
352
|
%Q| <i>#{author(event)}</i> updated <a href="#{gitlab_url(event)}">the Kitchen</a> |
|
310
353
|
when 'cookbook upload'
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'ridley'
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
|
6
|
+
class SyncServers
|
7
|
+
attr_reader :status
|
8
|
+
|
9
|
+
|
10
|
+
def initialize knives
|
11
|
+
@knives = knives
|
12
|
+
@started = Time.now
|
13
|
+
@status = sync_servers.merge \
|
14
|
+
elapsed: Time.now - @started
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def ridleys
|
21
|
+
@ridleys ||= @knives.map do |knife|
|
22
|
+
Ridley.from_chef_config(knife)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def all_nodes
|
27
|
+
@all_nodes ||= ridleys.flat_map do |ridley|
|
28
|
+
ridley.partial_search(:node, '*:*', %w[ ohai_time ])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def merged_nodes
|
34
|
+
@merged_nodes ||= all_nodes.group_by(&:name).pmap do |name, copies|
|
35
|
+
copies.sort_by { |c| c.automatic.ohai_time }.last
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def sync_servers
|
41
|
+
nodes = merged_nodes
|
42
|
+
failures = Set.new
|
43
|
+
|
44
|
+
nodes.peach(8) do |n|
|
45
|
+
n.reload
|
46
|
+
ridleys.peach(4) do |ridley|
|
47
|
+
ridley.node.create(n) \
|
48
|
+
rescue ridley.node.update(n) \
|
49
|
+
rescue failures << n.name
|
50
|
+
end
|
51
|
+
puts 'Synced node "%s"' % n.name
|
52
|
+
end
|
53
|
+
|
54
|
+
return {
|
55
|
+
failures: failures,
|
56
|
+
num_successes: nodes.length - failures.length,
|
57
|
+
num_failures: failures.length,
|
58
|
+
num_nodes: nodes.length
|
59
|
+
}
|
60
|
+
rescue
|
61
|
+
return nil
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
data/lib/kitchen_hooks/main.rb
CHANGED
@@ -61,10 +61,11 @@ module KitchenHooks
|
|
61
61
|
desc: 'Location of temporary directory',
|
62
62
|
default: '/tmp'
|
63
63
|
def server
|
64
|
+
App.config! JSON::parse(File.read(options.config))
|
64
65
|
App.backlog!
|
65
66
|
App.db! options.database
|
66
67
|
App.tmp! options.tmpdir
|
67
|
-
App.
|
68
|
+
App.sync!
|
68
69
|
App.set :environment, options.environment
|
69
70
|
App.set :port, options.port
|
70
71
|
App.set :bind, options.bind
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<svg width="800" height="800" xmlns="http://www.w3.org/2000/svg">
|
3
|
+
<g>
|
4
|
+
<title>background</title>
|
5
|
+
<rect x="-1" y="-1" width="802" height="802" id="canvas_background" fill="none"/>
|
6
|
+
</g>
|
7
|
+
|
8
|
+
<g>
|
9
|
+
<title>Layer 1</title>
|
10
|
+
<path id="cloud-5-icon" d="m709.958801,397.394226c-12.598816,-158.646255 -221.498688,-210.920303 -306.884827,-75.072937c-55.378632,-31.311005 -126.010834,5.526672 -130.436066,70.253632c-60.718811,7.439392 -107.756332,59.146332 -107.756332,121.873932c0,67.83905 54.990204,122.829346 122.829361,122.829346l384.973877,0c67.835327,0 122.827454,-54.990295 122.827454,-122.829346c0.002014,-54.838409 -35.941895,-101.266602 -85.553467,-117.054626zm-591.126747,143.131042c-65.176666,-6.489807 -115.318749,-60.720673 -115.318749,-126.443329c0,-57.07019 37.981427,-106.291473 91.172333,-121.91629c14.955742,-50.987915 68.608047,-80.878265 119.807449,-67.225845c30.647736,-36.243652 75.486191,-57.308533 123.855881,-57.308533c44.846069,0 85.705231,18.275543 115.236084,47.994858c-17.300964,7.968079 -33.211975,18.15062 -47.62381,30.420929c-19.500092,-15.799637 -43.733093,-23.289108 -67.612274,-23.289108c-69.332733,0 -97.812119,52.479721 -104.920914,72.575729c-28.264053,-40.766861 -104.982407,-9.986542 -89.084747,44.580872c-47.595016,-8.629364 -85.703339,27.202789 -85.703339,74.167389c0,35.530396 25.891945,65.111328 60.782272,70.918701c-3.256432,18.646515 -3.39489,37.287445 -0.590187,55.524628z" fill="#ffffff"/>
|
11
|
+
</g>
|
12
|
+
</svg>
|
data/web/views/app.erb
CHANGED
@@ -16,6 +16,10 @@
|
|
16
16
|
<img src="/vendor/img/error.svg" alt="Error">
|
17
17
|
<% when 'release' %>
|
18
18
|
<img src="/vendor/img/cube.svg" alt="Cube">
|
19
|
+
<% when 'synced' %>
|
20
|
+
<img src="/vendor/img/sync.svg" alt="Sync">
|
21
|
+
<% when 'unsynced' %>
|
22
|
+
<img src="/vendor/img/sync.svg" alt="Sync">
|
19
23
|
<% end %>
|
20
24
|
</div>
|
21
25
|
<div class="cd-timeline-content">
|
@@ -26,6 +30,10 @@
|
|
26
30
|
<p><%= notification entry %></p>
|
27
31
|
<% elsif type == 'release' %>
|
28
32
|
<p><%= notification entry %></p>
|
33
|
+
<% elsif type == 'synced' %>
|
34
|
+
<p><%= notification entry %></p>
|
35
|
+
<% elsif type == 'unsynced' %>
|
36
|
+
<p><%= notification entry %></p>
|
29
37
|
<% else %>
|
30
38
|
<p><%= notification entry %> by pushing <%= push_details(entry[:event]) %></p>
|
31
39
|
<% end %>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kitchen_hooks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sean Clemmer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-02-
|
11
|
+
date: 2015-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hipchat
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 12.0.0
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 12.0.0
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: thor
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -171,6 +171,7 @@ files:
|
|
171
171
|
- lib/kitchen_hooks.rb
|
172
172
|
- lib/kitchen_hooks/app.rb
|
173
173
|
- lib/kitchen_hooks/helpers.rb
|
174
|
+
- lib/kitchen_hooks/helpers/sync_servers.rb
|
174
175
|
- lib/kitchen_hooks/main.rb
|
175
176
|
- lib/kitchen_hooks/metadata.rb
|
176
177
|
- web/app/kitchen_hooks.js
|
@@ -183,6 +184,7 @@ files:
|
|
183
184
|
- web/public/vendor/img/cutlery.svg
|
184
185
|
- web/public/vendor/img/error.svg
|
185
186
|
- web/public/vendor/img/shield.svg
|
187
|
+
- web/public/vendor/img/sync.svg
|
186
188
|
- web/public/vendor/js/bootstrap-v3.3.0.js
|
187
189
|
- web/public/vendor/js/jquery-timeago-v1.4.1.js
|
188
190
|
- web/public/vendor/js/jquery-v2.1.1.js
|