batali 0.3.8 → 0.3.10
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/CHANGELOG.md +3 -0
- data/README.md +14 -0
- data/lib/batali/version.rb +1 -1
- data/lib/chef/knife/batali_sync.rb +221 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc79c37709d9a82123b18ff7f3708d3ab3090747
|
4
|
+
data.tar.gz: d71675d5533528818ffdafe8a2b7727ae7d20566
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e745bf572287f0c86144b03a55493f0de0f8954762664d5165e2cce579bffb80742af7f22c4ac9881fe06519a459b619f922cb7f8c7390cb3d59f62ca7dfc042
|
7
|
+
data.tar.gz: 6dcb427899adfbc5c7d9e7c9b5b2cb1900a52e98e27511c357f4287b53c94a2698c26ffad5d44efab9cf7df2d66d2f74286ebaac93c0e1d74bc75128de531b96
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -393,6 +393,20 @@ line to your `spec_helper.rb` file:
|
|
393
393
|
require 'batali/chefspec'
|
394
394
|
```
|
395
395
|
|
396
|
+
## Chef Server Sync
|
397
|
+
|
398
|
+
Batali includes a knife plugin to sync cookbooks defined within the local
|
399
|
+
`batali.manifest` file with the cookbooks available from on the Chef server.
|
400
|
+
|
401
|
+
```
|
402
|
+
$ knife batali sync
|
403
|
+
```
|
404
|
+
|
405
|
+
This command will remove any cookbooks on the Chef server that are not found
|
406
|
+
within the `batali.manifest` file. If cookbooks are defined within the
|
407
|
+
`batali.manifest` file that have not been uploaded to the Chef server, those
|
408
|
+
cookbooks will be uploaded.
|
409
|
+
|
396
410
|
# Info
|
397
411
|
|
398
412
|
* Repository: https://github.com/hw-labs/batali
|
data/lib/batali/version.rb
CHANGED
@@ -0,0 +1,221 @@
|
|
1
|
+
require 'batali'
|
2
|
+
|
3
|
+
class Chef
|
4
|
+
class Knife
|
5
|
+
class BataliSync < Knife
|
6
|
+
|
7
|
+
banner 'knife batali sync'
|
8
|
+
|
9
|
+
option(:blacklist,
|
10
|
+
:short => '-B COOKBOOK_NAME[,COOKBOOK_NAME]',
|
11
|
+
:long => '--blacklist COOKBOOK_NAME[,COOKBOOK_NAME]',
|
12
|
+
:description => 'Cookbooks to ignore from sync',
|
13
|
+
:proc => lambda{|val|
|
14
|
+
Chef::Config[:knife][:batali_blacklist] ||= []
|
15
|
+
Chef::Config[:knife][:batali_blacklist] += val.split(',')
|
16
|
+
}
|
17
|
+
)
|
18
|
+
|
19
|
+
option(:details,
|
20
|
+
:long => '--[no-]details',
|
21
|
+
:boolean => true,
|
22
|
+
:default => true,
|
23
|
+
:description => 'Show details of cookbooks to be removed / added'
|
24
|
+
)
|
25
|
+
|
26
|
+
option(:show_remaining,
|
27
|
+
:long => '--[no-]show-remaining',
|
28
|
+
:description => 'Display cookbook details of expected final server state',
|
29
|
+
:boolean => true,
|
30
|
+
:default => false,
|
31
|
+
:proc => lambda{|val|
|
32
|
+
Chef::Config[:knife][:batali_show_remaining] = val
|
33
|
+
}
|
34
|
+
)
|
35
|
+
|
36
|
+
option(:dry_run,
|
37
|
+
:long => '--[no-]dry-run',
|
38
|
+
:description => 'Display information but perform no action',
|
39
|
+
:boolean => true,
|
40
|
+
:default => false
|
41
|
+
)
|
42
|
+
|
43
|
+
def run
|
44
|
+
Chef::Config[:knife][:batali_blacklist] ||= []
|
45
|
+
config[:verbose] = config[:verbosity].to_i > 0
|
46
|
+
ui.info "#{ui.color('[Batali]', :green, :bold)}: Chef Server Batali Manifest Sync"
|
47
|
+
valid_cookbooks = run_task('Generating valid cookbook versions from manifest') do
|
48
|
+
generate_manifest_cookbooks
|
49
|
+
end
|
50
|
+
remote_cookbooks = run_task('Generating remote cookbook versions from chef server') do
|
51
|
+
generate_remote_cookbooks
|
52
|
+
end
|
53
|
+
to_remove = run_task('Building cookbook removal list') do
|
54
|
+
locate_removals(
|
55
|
+
:manifest => valid_cookbooks,
|
56
|
+
:server => remote_cookbooks
|
57
|
+
)
|
58
|
+
end
|
59
|
+
to_add = run_task('Building cookbook upload list') do
|
60
|
+
locate_additions(
|
61
|
+
:manifest => valid_cookbooks,
|
62
|
+
:server => remote_cookbooks
|
63
|
+
)
|
64
|
+
end
|
65
|
+
if(to_add.empty? && to_remove.empty?)
|
66
|
+
ui.info "#{ui.color('[Batali]', :green, :bold)}: Chef Server Batali Manifest Sync - #{ui.color('No Changes Detected!', :green, :bold)}"
|
67
|
+
else
|
68
|
+
display_sync_info(
|
69
|
+
:additions => to_add,
|
70
|
+
:removals => to_remove,
|
71
|
+
:manifest => valid_cookbooks
|
72
|
+
)
|
73
|
+
unless(config[:dry_run])
|
74
|
+
ui.confirm 'Sync remote cookbooks with Batali manifest'
|
75
|
+
remove_cookbooks(to_remove) unless to_remove.empty?
|
76
|
+
add_cookbooks(to_add) unless to_add.empty?
|
77
|
+
ui.info "#{ui.color('[Batali]', :green, :bold)}: Chef Server Batali Manifest Sync - #{ui.color('Sync Complete!', :green, :bold)}"
|
78
|
+
else
|
79
|
+
ui.warn 'Dry run requested. No action taken.'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def remove_cookbooks(ckbks)
|
85
|
+
run_task('Removing cookbooks') do
|
86
|
+
ckbks.each do |c_name, vers|
|
87
|
+
vers.each do |version|
|
88
|
+
if(config[:verbose])
|
89
|
+
ui.warn "Deleting cookbook #{c_name} @ #{version}"
|
90
|
+
end
|
91
|
+
rest.delete("/cookbooks/#{c_name}/#{version}")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def add_cookbooks(ckbks)
|
98
|
+
Batali::Command::Install.new({}, []).execute!
|
99
|
+
ui.info "#{ui.color('[Batali]', :green, :bold)}: Adding cookbooks to Chef server."
|
100
|
+
Knife::Upload.load_deps
|
101
|
+
ckbks.each do |c_name, vers|
|
102
|
+
vers.each do |version|
|
103
|
+
c_path = [
|
104
|
+
File.join('cookbooks', c_name),
|
105
|
+
File.join('cookbooks', "#{c_name}-#{version}")
|
106
|
+
].detect do |_path|
|
107
|
+
File.directory?(_path)
|
108
|
+
end
|
109
|
+
uploader = Knife::Upload.new
|
110
|
+
uploader.configure_chef
|
111
|
+
uploader.config = config
|
112
|
+
uploader.name_args = [c_path]
|
113
|
+
if(config[:verbose])
|
114
|
+
ui.warn "Unloading cookbook #{c_name} @ #{version} - `#{c_path}`"
|
115
|
+
end
|
116
|
+
uploader.run
|
117
|
+
end
|
118
|
+
end
|
119
|
+
ui.info "#{ui.color('[Batali]', :green, :bold)}: Chef server cookbook additions complete."
|
120
|
+
end
|
121
|
+
|
122
|
+
def display_sync_info(opts)
|
123
|
+
num_remove = ui.color(opts[:removals].size.to_s, :red, :bold)
|
124
|
+
num_add = ui.color(opts[:additions].size.to_s, :green, :bold)
|
125
|
+
ui.info "#{ui.color('[Batali]', :green, :bold)}: Removals - #{num_remove} Additions: #{num_add}"
|
126
|
+
if(config[:details])
|
127
|
+
unless(opts[:removals].empty?)
|
128
|
+
ui.info "#{ui.color('[Batali]', :green, :bold)}: Cookbooks to be #{ui.color('removed', :red, :bold)}:"
|
129
|
+
opts[:removals].sort.each do |name, versions|
|
130
|
+
vers = versions.map do |v|
|
131
|
+
Gem::Version.new(v)
|
132
|
+
end.sort.map(&:to_s).join(', ')
|
133
|
+
ui.info " #{ui.color(name, :red, :bold)}: #{ui.color(vers, :red)}"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
unless(opts[:additions].empty?)
|
137
|
+
ui.info "#{ui.color('[Batali]', :green, :bold)}: Cookbooks to be #{ui.color('added', :green, :bold)}:"
|
138
|
+
opts[:additions].sort.each do |name, versions|
|
139
|
+
vers = versions.map do |v|
|
140
|
+
Gem::Version.new(v)
|
141
|
+
end.sort.map(&:to_s).join(', ')
|
142
|
+
ui.info " #{ui.color(name, :green, :bold)}: #{ui.color(vers, :green)}"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
if(Chef::Config[:knife][:batali_show_remaining])
|
146
|
+
ui.info "#{ui.color('[Batali]', :green, :bold)}: Final list of cookbooks to be available on the chef server:"
|
147
|
+
opts[:manifest].sort.each do |name, versions|
|
148
|
+
vers = versions.map do |v|
|
149
|
+
Gem::Version.new(v)
|
150
|
+
end.sort.map(&:to_s).join(', ')
|
151
|
+
ui.info " #{ui.color(name, :bold)}: #{vers}"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def locate_removals(opts)
|
158
|
+
Smash.new.tap do |rm|
|
159
|
+
opts[:server].each do |c_name, c_versions|
|
160
|
+
kills = c_versions - opts[:manifest].fetch(c_name, [])
|
161
|
+
unless(kills.empty?)
|
162
|
+
rm[c_name] = kills
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def locate_additions(opts)
|
169
|
+
Smash.new.tap do |add|
|
170
|
+
opts[:manifest].each do |c_name, c_versions|
|
171
|
+
adds = c_versions - opts[:server].fetch(c_name, [])
|
172
|
+
unless(adds.empty?)
|
173
|
+
add[c_name] = adds
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def generate_manifest_cookbooks
|
180
|
+
path = File.join(Dir.pwd, 'batali.manifest')
|
181
|
+
unless(File.exists?(path))
|
182
|
+
raise "Failed to locate batali manifest at: #{path}"
|
183
|
+
end
|
184
|
+
manifest = Batali::Manifest.build(path)
|
185
|
+
Smash.new.tap do |ckbks|
|
186
|
+
manifest.cookbook.each do |c|
|
187
|
+
next if Chef::Config[:knife][:batali_blacklist].include?(c.name)
|
188
|
+
ckbks[c.name] ||= []
|
189
|
+
ckbks[c.name] << c.version.to_s
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def generate_remote_cookbooks
|
195
|
+
Smash.new.tap do |ckbks|
|
196
|
+
rest.get('cookbooks?num_versions=all').map do |c_name, meta|
|
197
|
+
next if Chef::Config[:knife][:batali_blacklist].include?(c_name)
|
198
|
+
ckbks[c_name] = []
|
199
|
+
meta['versions'].each do |info|
|
200
|
+
ckbks[c_name] << info['version']
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def run_task(task)
|
207
|
+
ui.stdout.print "#{ui.color('[Batali]', :green, :bold)}: #{task}... "
|
208
|
+
begin
|
209
|
+
value = yield if block_given?
|
210
|
+
ui.info ui.color('complete', :green)
|
211
|
+
value
|
212
|
+
rescue => e
|
213
|
+
ui.info ui.color('failed', :red, :bold)
|
214
|
+
puts e.backtrace.join("\n")
|
215
|
+
raise e
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: batali
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Roberts
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-12-
|
11
|
+
date: 2015-12-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: attribute_struct
|
@@ -214,6 +214,7 @@ files:
|
|
214
214
|
- lib/batali/unit_loader.rb
|
215
215
|
- lib/batali/utility.rb
|
216
216
|
- lib/batali/version.rb
|
217
|
+
- lib/chef/knife/batali_sync.rb
|
217
218
|
homepage: https://github.com/hw-labs/batali
|
218
219
|
licenses:
|
219
220
|
- Apache 2.0
|