kitchen_hooks 1.5.2 → 1.5.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Readme.md +89 -9
- data/VERSION +1 -1
- data/etc/commit.json +10 -10
- data/etc/config.json +3 -1
- data/lib/kitchen_hooks/app.rb +33 -13
- data/lib/kitchen_hooks/helpers.rb +13 -5
- data/lib/kitchen_hooks/main.rb +6 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc604b1b2abab2073d9e568aaa74126476eca24e
|
4
|
+
data.tar.gz: 6f8dab7e189d19fd33a4fa15c4e590b15c831b44
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e31f2ac0f8bb6d0e152ace39709ba420b56484f8e3ce22de3ea1d03e9697a352100eb29ff8853d1ccce9e92bc001b1403505df716cc2e8f8527c3048e25ff5cf
|
7
|
+
data.tar.gz: e1ed91030b09ec8dee1a399f316c46c193dd8d6cf9670528ed4f376dc2426cbfea227dcf08e4fd00a95cc568f0b7235e94394a547bb0e611d7c46d5e5e2f6728
|
data/Readme.md
CHANGED
@@ -4,9 +4,68 @@
|
|
4
4
|
WebHoook for automated Chef Server uploads following Kitchen standards.
|
5
5
|
|
6
6
|
|
7
|
+
## What?
|
8
|
+
|
9
|
+
So [the Kitchen](http://wiki.bluejeansnet.com/operations/kitchen) is this thing
|
10
|
+
we have now in Operations to help guide cookbook development. The [Workflow](http://wiki.bluejeansnet.com/operations/kitchen#workflow)
|
11
|
+
sction of the docs prescribes how to go about your day in Chef land including
|
12
|
+
how to version, release, and deploy changes to a Chef server.
|
13
|
+
|
14
|
+
But that's only _one_ Chef server. What if we want redundancy?
|
15
|
+
|
16
|
+
A distributed/highly-available Chef would do the job. It comes in a few flavors:
|
17
|
+
|
18
|
+
1. Pay for whatever they're calling [Hosted Chef](https://manage.chef.io/signup) nowadays
|
19
|
+
2. Manually deploy a [highly-available setup in AWS](https://docs.getchef.com/install_server_ha_aws.html)
|
20
|
+
3. Manually deploy a [highly-available setup with DRBD](https://docs.getchef.com/server_high_availability.html#drbd)
|
21
|
+
|
22
|
+
The third option is basically a recipe for disaster. DRBD is known to lose data
|
23
|
+
in split-brain scenarios. So that's actually two flavors.
|
24
|
+
|
25
|
+
Hosted Chef seems like a great option. Until you start using it. They give you
|
26
|
+
whatever bleeding-edge version of Chef they're testing so you don't have time
|
27
|
+
to breathe between incompatible versions. Chef is notorious for yanking gems
|
28
|
+
and botching releases. They've also got some odd permissions you probably have
|
29
|
+
never seen before, because vanilla Chef server doesn't have organizations.
|
30
|
+
|
31
|
+
That leaves AWS as an option. But it's a lot of work, and weirdly completely
|
32
|
+
not automated.
|
33
|
+
|
34
|
+
All I care about is having my Chef data replicated, why does it have to be hard?
|
35
|
+
I mean, we've been using `git` hooks to fan out to Chef servers for years now!
|
36
|
+
|
37
|
+
### So let's do that.
|
38
|
+
|
39
|
+
The old post-receive hook was pretty basic, but it worked. By default, it would
|
40
|
+
look up the `knife` and `berks` configuration files (`.rb` and `.json`) in
|
41
|
+
`~/knives` then loop over them when uploading Chef objects found in the
|
42
|
+
checkout specified by the hook.
|
43
|
+
|
44
|
+
The new Kitchen Hooks works much the same, except we're using GitLab WebHooks
|
45
|
+
rather than traditional `git` hooks. This makes the Hooks easier to maintain,
|
46
|
+
as installing `git` hooks has not been automated, and WebHooks are opt-in.
|
47
|
+
|
48
|
+
The new Hooks cover three scenarios:
|
49
|
+
|
50
|
+
1. Pushes to the `master` branch of the Kitchen trigger an upload of all roles,
|
51
|
+
environments, and data bags. This will overwrite any changes made on the Chef
|
52
|
+
server, but you shouldn't be doing that anyway. Importantly, this has no
|
53
|
+
effect on cookbook versions pinned in any environment.
|
54
|
+
2. Version tag pushes (e.g. `v1.0.0`) to cookbooks trigger a `knife`-style
|
55
|
+
cookbook upload with `freeze` set to true. A `Berksfile.lock` will also
|
56
|
+
trigger the equivalent of `berks install` and `berks upload`.
|
57
|
+
3. Environment tag pushes (e.g. `bjn_logger_prod`) to realm cookbooks trigger
|
58
|
+
`berks apply` behavior. Remember to delete both the local and remote tags
|
59
|
+
when you want to update an environment with a later version of the realm.
|
60
|
+
|
61
|
+
Actions performed by Kitchen Hooks are stored in a [Daybreak](http://propublica.github.io/daybreak/)
|
62
|
+
database and presented as a timeline in the [Web UI](http://git.bluejeansnet.com:4567).
|
63
|
+
Notifcations can are sent to HipChat.
|
64
|
+
|
7
65
|
## Installation
|
8
66
|
|
9
|
-
|
67
|
+
Try `gem install kitchen_hooks`. Or add it to your `Gemfile`. Or clone the repo
|
68
|
+
and `rake build`. Do all three, I don't care!
|
10
69
|
|
11
70
|
|
12
71
|
## Usage
|
@@ -29,21 +88,42 @@ Use the `server` command to start the WebHook receiver:
|
|
29
88
|
Listening on 0.0.0.0:80, CTRL+C to stop
|
30
89
|
...
|
31
90
|
|
91
|
+
## Configuration
|
92
|
+
|
93
|
+
The configuration file is just JSON. Hopefully it's obvious:
|
94
|
+
|
95
|
+
{
|
96
|
+
"hipchat": {
|
97
|
+
"nick": "name",
|
98
|
+
"room": "test",
|
99
|
+
"token": "your_v1_api_token"
|
100
|
+
},
|
101
|
+
"knives": {
|
102
|
+
"user": "~/.chef/knife.rb",
|
103
|
+
"system": "/etc/chef/knife.rb",
|
104
|
+
"another": "/path/to/knife.rb"
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
The `server` command also exposes some options for Sinatra configuration. See
|
109
|
+
`kitchen_hooks help server`.
|
110
|
+
|
111
|
+
## Development
|
32
112
|
|
33
|
-
|
113
|
+
### TODO
|
34
114
|
|
35
115
|
* Use Ridley for data bag, role, and environment uploads to remove Chef dependency
|
36
116
|
|
37
|
-
|
117
|
+
### Changelog
|
38
118
|
|
39
|
-
|
119
|
+
#### 1.5
|
40
120
|
|
41
121
|
* Add release notifications
|
42
122
|
* Add indication of success or failure
|
43
123
|
* Only upload on commits to Kitchen `master` branch
|
44
124
|
* Add custom timeline icons to distinguish event types
|
45
125
|
|
46
|
-
|
126
|
+
#### 1.4
|
47
127
|
|
48
128
|
* Simplified configuration format (breaking!)
|
49
129
|
* Added support for HipChat notifications when configured
|
@@ -51,19 +131,19 @@ Use the `server` command to start the WebHook receiver:
|
|
51
131
|
* Replaced "modified" with more appropriate verb where appropriate
|
52
132
|
* Corrected `berks upload` functionality (`berks install` first)
|
53
133
|
|
54
|
-
|
134
|
+
#### 1.3
|
55
135
|
|
56
136
|
* Added local database to store history (Daybreak), visualized on homepage
|
57
137
|
* Added `database` option to `server` command
|
58
138
|
* Corrected GitLab link for tagged commits
|
59
139
|
* Process events in the background to avoid duplicate entries [INF-6040]
|
60
140
|
|
61
|
-
|
141
|
+
#### 1.2
|
62
142
|
|
63
143
|
* Added `bind` option to `server` command
|
64
144
|
* Added `berks upload` functionality when tagging realm versions
|
65
145
|
|
66
|
-
|
146
|
+
#### 1.1
|
67
147
|
|
68
148
|
* Moved `examples` to `etc`
|
69
149
|
* Started checking in `Gemfile.lock` for future reference
|
@@ -73,6 +153,6 @@ Use the `server` command to start the WebHook receiver:
|
|
73
153
|
* Tagging a cookbook with a version triggers a cookbook upload (frozen)
|
74
154
|
* Tagging a realm with the name of an environment applies version constraints
|
75
155
|
|
76
|
-
|
156
|
+
#### 1.0
|
77
157
|
|
78
158
|
* Initial release. Gem structure in place, but lacking functionaily
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.5.
|
1
|
+
1.5.3
|
data/etc/commit.json
CHANGED
@@ -1,24 +1,24 @@
|
|
1
1
|
{
|
2
2
|
"before": "08f20548e398f634979047d0c8114260bcc2949a",
|
3
|
-
"after": "
|
4
|
-
"ref": "refs/
|
3
|
+
"after": "7b238ce9c6cff250db5a0b727b9661b618b82e1d",
|
4
|
+
"ref": "refs/tags/v1.5.1",
|
5
5
|
"user_id": 645,
|
6
6
|
"user_name": "Sean Clemmer",
|
7
7
|
"repository": {
|
8
|
-
"name": "
|
9
|
-
"url": "git@git.bluejeansnet.com:chef/
|
8
|
+
"name": "realm_logger",
|
9
|
+
"url": "git@git.bluejeansnet.com:chef/realm_logger.git",
|
10
10
|
"description": "",
|
11
|
-
"homepage": "http://git.bluejeansnet.com/
|
11
|
+
"homepage": "http://git.bluejeansnet.com/chef/realm_logger"
|
12
12
|
},
|
13
13
|
"commits": [
|
14
14
|
{
|
15
|
-
"id": "
|
16
|
-
"message": "
|
15
|
+
"id": "7b238ce9c6cff250db5a0b727b9661b618b82e1d",
|
16
|
+
"message": "XYZ",
|
17
17
|
"timestamp": "2014-11-25T18:30:57-08:00",
|
18
|
-
"url": "http://git.bluejeansnet.com/
|
18
|
+
"url": "http://git.bluejeansnet.com/chef/realm_logger/commit/7b238ce9c6cff250db5a0b727b9661b618b82e1d",
|
19
19
|
"author": {
|
20
|
-
"name": "
|
21
|
-
"email": "
|
20
|
+
"name": "Sean Clemmer",
|
21
|
+
"email": "sclemmer@bluejeans.com"
|
22
22
|
}
|
23
23
|
}
|
24
24
|
],
|
data/etc/config.json
CHANGED
data/lib/kitchen_hooks/app.rb
CHANGED
@@ -22,6 +22,10 @@ module KitchenHooks
|
|
22
22
|
@@db = Daybreak::DB.new path
|
23
23
|
end
|
24
24
|
|
25
|
+
def self.close!
|
26
|
+
@@db.close
|
27
|
+
end
|
28
|
+
|
25
29
|
def self.config! config
|
26
30
|
@@hipchat = nil
|
27
31
|
if config['hipchat']
|
@@ -39,7 +43,7 @@ module KitchenHooks
|
|
39
43
|
process_release
|
40
44
|
db_entries = {}
|
41
45
|
db.each do |k, v|
|
42
|
-
db_entries[k] = v unless k
|
46
|
+
db_entries[k] = v unless k =~ /^meta/
|
43
47
|
end
|
44
48
|
erb :app, locals: {
|
45
49
|
database: db_entries.sort_by { |stamp, _| stamp }
|
@@ -90,10 +94,12 @@ module KitchenHooks
|
|
90
94
|
|
91
95
|
|
92
96
|
# error == nil => success
|
97
|
+
# error == true => success
|
93
98
|
# error == false => nop
|
94
99
|
# otherwise => failure
|
95
100
|
def mark event, type, error=nil
|
96
101
|
return if error == false
|
102
|
+
error = nil if error == true
|
97
103
|
entry = { type: type, event: event }
|
98
104
|
entry.merge!(error: error, type: 'failure') if error
|
99
105
|
db.synchronize do
|
@@ -105,15 +111,20 @@ module KitchenHooks
|
|
105
111
|
|
106
112
|
|
107
113
|
def process_release version=KitchenHooks::VERSION
|
108
|
-
db['
|
109
|
-
|
114
|
+
return if db['meta_version'] == version
|
115
|
+
db.set! 'meta_version', version
|
110
116
|
mark version, 'release'
|
111
|
-
db.synchronize do
|
112
|
-
db['meta']['version'] = version
|
113
|
-
end
|
114
|
-
db.flush
|
115
117
|
end
|
116
118
|
|
119
|
+
|
120
|
+
def err_out e, msg
|
121
|
+
logger.error msg
|
122
|
+
logger.error e.message
|
123
|
+
logger.error e.backtrace.inspect
|
124
|
+
msg
|
125
|
+
end
|
126
|
+
|
127
|
+
|
117
128
|
def process event
|
118
129
|
if event.nil? # JSON parse failed
|
119
130
|
mark event, 'failure', 'Could not parse WebHook payload'
|
@@ -121,22 +132,31 @@ module KitchenHooks
|
|
121
132
|
end
|
122
133
|
|
123
134
|
if commit_to_kitchen?(event)
|
124
|
-
possible_error =
|
125
|
-
|
135
|
+
possible_error = begin
|
136
|
+
perform_kitchen_upload(event, knives)
|
137
|
+
rescue Exception => e
|
138
|
+
err_out e, 'Could not perform kitchen upload'
|
139
|
+
end
|
126
140
|
mark event, 'kitchen upload', possible_error
|
127
141
|
end
|
128
142
|
|
129
143
|
if tagged_commit_to_cookbook?(event) &&
|
130
144
|
tag_name(event) =~ /^v\d+/ # Cookbooks tagged with a version
|
131
|
-
possible_error =
|
132
|
-
|
145
|
+
possible_error = begin
|
146
|
+
perform_cookbook_upload(event, knives)
|
147
|
+
rescue Exception => e
|
148
|
+
err_out e, 'Could not perform cookbook upload'
|
149
|
+
end
|
133
150
|
mark event, 'cookbook upload', possible_error
|
134
151
|
end
|
135
152
|
|
136
153
|
if tagged_commit_to_realm?(event) &&
|
137
154
|
tag_name(event) =~ /^bjn_/ # Realms tagged with an environment
|
138
|
-
possible_error =
|
139
|
-
|
155
|
+
possible_error = begin
|
156
|
+
perform_constraint_application(event, knives)
|
157
|
+
rescue Exception => e
|
158
|
+
err_out e, 'Could not apply constraints'
|
159
|
+
end
|
140
160
|
mark event, 'constraint application', possible_error
|
141
161
|
end
|
142
162
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'shellwords'
|
2
|
+
require 'fileutils'
|
2
3
|
require 'tempfile'
|
3
4
|
require 'json'
|
4
5
|
|
@@ -24,7 +25,8 @@ module KitchenHooks
|
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
27
|
-
|
28
|
+
logger.info "finished perform_constraint_application: #{event['after']}"
|
29
|
+
return true # no error
|
28
30
|
end
|
29
31
|
|
30
32
|
|
@@ -48,7 +50,8 @@ module KitchenHooks
|
|
48
50
|
end
|
49
51
|
end
|
50
52
|
|
51
|
-
|
53
|
+
logger.info "finished perform_kitchen_upload: #{event['after']}"
|
54
|
+
return true # no error
|
52
55
|
end
|
53
56
|
|
54
57
|
|
@@ -57,7 +60,9 @@ module KitchenHooks
|
|
57
60
|
Dir.chdir clone do
|
58
61
|
tagged_version = tag_name(event).delete('v')
|
59
62
|
cookbook_version = File.read('VERSION').strip
|
60
|
-
|
63
|
+
unless tagged_version == cookbook_version
|
64
|
+
raise 'Tagged version does not match cookbook version'
|
65
|
+
end
|
61
66
|
|
62
67
|
logger.info 'Uploading cookbook'
|
63
68
|
with_each_knife "cookbook upload #{cookbook_name event} -o .. --freeze", knives
|
@@ -74,7 +79,8 @@ module KitchenHooks
|
|
74
79
|
end
|
75
80
|
end
|
76
81
|
|
77
|
-
|
82
|
+
logger.info "finished cookbook_upload: #{event['after']}"
|
83
|
+
return true # no error
|
78
84
|
end
|
79
85
|
|
80
86
|
|
@@ -98,8 +104,10 @@ module KitchenHooks
|
|
98
104
|
Dir.mktmpdir do |tmp|
|
99
105
|
dir = File::join tmp, cookbook_name(event)
|
100
106
|
repo = Git.clone git_daemon_style_url(event), dir, log: $stdout
|
101
|
-
|
107
|
+
commit = self.send(commit_method, event)
|
108
|
+
repo.checkout commit
|
102
109
|
yield dir
|
110
|
+
FileUtils.rm_rf dir
|
103
111
|
end
|
104
112
|
end
|
105
113
|
|
data/lib/kitchen_hooks/main.rb
CHANGED
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.5.
|
4
|
+
version: 1.5.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kelly Wong
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hipchat
|