yyuu-capistrano-chef-solo 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -35,8 +35,12 @@ set(:chef_solo_version, "11.4.0")
35
35
  set(:rbenv_ruby_version, "1.9.3-p392")
36
36
  ```
37
37
 
38
- And then, now you can start using `chef-solo` via Capistrano.
39
- This task will deploy cookbooks from `./config/cookbooks`, and then invoke `chef-solo`.
38
+ Then, create directories for your cookbooks and data bags. By default, `capistrano-chef-solo` searches them from `./config`.
39
+ (see examples of [cookbooks](#using-cookbooks) and [data bags](#using-data-bags) for details)
40
+
41
+ $ mkdir -p config/cookbooks config/data_bags
42
+
43
+ Now you can start using `chef-solo` via Capistrano.
40
44
 
41
45
  $ cap chef-solo
42
46
 
@@ -137,6 +141,21 @@ set(:chef_solo_cookbooks) {{
137
141
  ```
138
142
 
139
143
 
144
+ ### Using data bags
145
+
146
+ #### Using data bags in local path
147
+
148
+ You can manage your data bags as similar as [cookbooks](#using-cookbooks).
149
+
150
+ By default, `capistrano-chef-solo` searches data bags from local path of `config/data_bags`.
151
+ You can specify the data bags directory with using `chef_solo_data_bags_subdir`.
152
+
153
+ ```ruby
154
+ set(:chef_solo_data_bags_scm, :none)
155
+ set(:chef_solo_data_bags_subdir, "config/data_bags")
156
+ ```
157
+
158
+
140
159
  ### Attributes configuration
141
160
 
142
161
  By default, the Chef attributes will be generated by following order.
@@ -211,17 +230,19 @@ You can check generated attributes with using `chef-solo:attributes` task.
211
230
 
212
231
  Following options are available to manage your `chef-solo`.
213
232
 
214
- * `:chef_solo_version` - the version of chef.
215
- * `:chef_solo_cookbooks` - the definition of cookbooks. by default, copy cookbooks from `./config/cookbooks`.
216
- * `:chef_solo_attributes` - the `attributes` of chef-solo. must be a `Hash<String,String>`. will be converted into JSON.
217
- * `:chef_solo_run_list` - the `run_list` of chef-solo. must be an `Array<String>`. will be merged into `:chef_solo_attributes`.
218
- * `:chef_solo_role_attributes` - the per-roles `attributes` of chef-solo. must be a `Hash<Symbol,Hash<String,String>>`.
219
- * `:chef_solo_role_run_list` - the per-roles `run_list` of chef-solo. must be a `Hash<Symbol,Array<String>>`.
220
- * `:chef_solo_host_attributes` - the per-hosts `attributes` of chef-solo. must be a `Hash<String,Hash<String,String>>`.
221
- * `:chef_solo_host_run_list` - the per-hosts `run_list` of chef-solo. must be a `Hash<String,Array<String>>`.
222
- * `:chef_solo_capistrano_attributes` - the Capistrano variables to use as Chef attributes.
223
- * `:chef_solo_capistrano_attributes_exclude` - the black list for `:chef_solo_capistrano_attributes`
224
- * `:chef_solo_capistrano_attributes_include` - the white list for `:chef_solo_capistrano_attributes`
233
+ * `:chef_solo_version` - The version of Chef.
234
+ * `:chef_solo_use_bunler` - Use bundler to install Chef. Set `true` by default.
235
+ * `:chef_solo_cookbooks` - The definition of cookbooks. By default, use cookbooks in `./config/cookbooks`.
236
+ * `:chef_solo_data_bags` - The definition of data bags. By default, use data bags in `./config/data_bags`.
237
+ * `:chef_solo_attributes` - The `attributes` of chef-solo. must be a `Hash<String,String>`. This will be converted into JSON.
238
+ * `:chef_solo_run_list` - The `run_list` of chef-solo. must be an `Array<String>`. This will be merged into `:chef_solo_attributes`.
239
+ * `:chef_solo_role_attributes` - The per-roles `attributes` of chef-solo. This must be a `Hash<Symbol,Hash<String,String>>`.
240
+ * `:chef_solo_role_run_list` - The per-roles `run_list` of chef-solo. This must be a `Hash<Symbol,Array<String>>`.
241
+ * `:chef_solo_host_attributes` - The per-hosts `attributes` of chef-solo. This must be a `Hash<String,Hash<String,String>>`.
242
+ * `:chef_solo_host_run_list` - The per-hosts `run_list` of chef-solo. This must be a `Hash<String,Array<String>>`.
243
+ * `:chef_solo_capistrano_attributes` - The Capistrano variables to use as Chef attributes.
244
+ * `:chef_solo_capistrano_attributes_exclude` - The black list for `:chef_solo_capistrano_attributes`
245
+ * `:chef_solo_capistrano_attributes_include` - The white list for `:chef_solo_capistrano_attributes`
225
246
 
226
247
 
227
248
  ## Contributing
@@ -18,8 +18,5 @@ Gem::Specification.new do |gem|
18
18
 
19
19
  gem.add_dependency("capistrano", ">= 2.10.0")
20
20
  gem.add_dependency("capistrano-copy-subdir", ">= 0.1.0")
21
- gem.add_dependency("capistrano-rbenv", ">= 1.0.0")
22
- gem.add_development_dependency("net-scp", "~> 1.0.4")
23
- gem.add_development_dependency("net-ssh", "~> 2.2.2")
24
- gem.add_development_dependency("vagrant", "~> 1.0.6")
21
+ gem.add_dependency("capistrano-rbenv", ">= 1.0.1")
25
22
  end
@@ -15,6 +15,11 @@ module Capistrano
15
15
  find_and_execute_task("chef_solo:setup")
16
16
  }
17
17
 
18
+ desc("Uninstall chef-solo. (an alias of chef_solo:purge)")
19
+ task(:purge, :except => { :no_release => true }) {
20
+ find_and_execute_task("chef_solo:purge")
21
+ }
22
+
18
23
  desc("Run chef-solo. (an alias of chef_solo)")
19
24
  task(:default, :except => { :no_release => true }) {
20
25
  find_and_execute_task("chef_solo:default")
@@ -32,11 +37,13 @@ module Capistrano
32
37
  }
33
38
 
34
39
  namespace(:chef_solo) {
40
+ _cset(:chef_solo_use_bundler, true)
35
41
  _cset(:chef_solo_version, "11.4.0")
36
42
  _cset(:chef_solo_path) { capture("echo $HOME/chef").strip }
37
43
  _cset(:chef_solo_cache_path) { File.join(chef_solo_path, "cache") }
38
44
  _cset(:chef_solo_config_path) { File.join(chef_solo_path, "config") }
39
45
  _cset(:chef_solo_cookbooks_path) { File.join(chef_solo_path, "cookbooks") }
46
+ _cset(:chef_solo_data_bags_path) { File.join(chef_solo_path, "data_bags") }
40
47
  _cset(:chef_solo_config_file) { File.join(chef_solo_config_path, "solo.rb") }
41
48
  _cset(:chef_solo_attributes_file) { File.join(chef_solo_config_path, "solo.json") }
42
49
 
@@ -130,7 +137,11 @@ module Capistrano
130
137
  # initialized without bootstrap settings during `on :load`.
131
138
  # Is there any way to avoid this without setting `:rbenv_setup_default_environment`
132
139
  # as false?
133
- set(:rbenv_setup_default_environment, false)
140
+ on(:load) do
141
+ before("rbenv:setup_default_environment") do
142
+ set(:rbenv_setup_default_environment, false) if chef_solo_bootstrap
143
+ end
144
+ end
134
145
 
135
146
  desc("Setup chef-solo.")
136
147
  task(:setup, :except => { :no_release => true }) {
@@ -141,6 +152,15 @@ module Capistrano
141
152
  end
142
153
  }
143
154
 
155
+ desc("Uninstall chef-solo.")
156
+ task(:purge, :except => { :no_release => true }) {
157
+ connect_with_settings do
158
+ transaction do
159
+ uninstall
160
+ end
161
+ end
162
+ }
163
+
144
164
  desc("Run chef-solo.")
145
165
  task(:default, :except => { :no_release => true }) {
146
166
  connect_with_settings do
@@ -157,8 +177,8 @@ module Capistrano
157
177
  connect_with_settings do
158
178
  setup
159
179
  transaction do
160
- update(:run_list => recipes)
161
- invoke
180
+ update
181
+ invoke(:run_list => recipes)
162
182
  end
163
183
  end
164
184
  end
@@ -168,7 +188,7 @@ module Capistrano
168
188
  desc("Show chef-solo version.")
169
189
  task(:version, :except => { :no_release => true }) {
170
190
  connect_with_settings do
171
- run("cd #{chef_solo_path.dump} && #{bundle_cmd} exec #{chef_solo_cmd} --version")
191
+ execute("--version")
172
192
  end
173
193
  }
174
194
 
@@ -181,106 +201,182 @@ module Capistrano
181
201
  STDOUT.puts(_json_attributes(attributes))
182
202
  }
183
203
 
184
- task(:install, :except => { :no_release => true }) {
185
- install_ruby
186
- install_chef
187
- }
188
-
189
- task(:install_ruby, :except => { :no_release => true }) {
190
- set(:rbenv_install_bundler, true)
191
- find_and_execute_task("rbenv:setup")
192
- }
193
-
204
+ _cset(:chef_solo_gem_dependencies) {{
205
+ fetch(:chef_solo_gem, "chef") => chef_solo_version,
206
+ }}
194
207
  _cset(:chef_solo_gemfile) {
195
- (<<-EOS).gsub(/^\s*/, "")
196
- source "https://rubygems.org"
197
- gem "chef", #{chef_solo_version.to_s.dump}
198
- EOS
208
+ gemfile = []
209
+ gemfile << %{source "https://rubygems.org"}
210
+ chef_solo_gem_dependencies.each do |name, options|
211
+ if options.nil?
212
+ gemfile << %{gem #{name.dump}}
213
+ else
214
+ gemfile << %{gem #{name.dump}, #{options.inspect}}
215
+ end
216
+ end
217
+ gemfile.join("\n")
199
218
  }
200
- task(:install_chef, :except => { :no_release => true }) {
219
+ task(:install, :except => { :no_release => true }) {
220
+ set(:rbenv_install_bundler, true) if chef_solo_use_bundler
221
+ find_and_execute_task("rbenv:setup")
201
222
  begin
202
- version = capture("cd #{chef_solo_path.dump} && #{bundle_cmd} exec #{chef_solo_cmd} --version")
223
+ version = execute("--version", :via => :capture)
203
224
  installed = Regexp.new(Regexp.escape(chef_solo_version)) =~ version
204
225
  rescue
205
226
  installed = false
206
227
  end
207
228
  unless installed
208
- dirs = [ chef_solo_path, chef_solo_cache_path, chef_solo_config_path, chef_solo_cookbooks_path ].uniq
229
+ dirs = [ chef_solo_path, chef_solo_cache_path, chef_solo_config_path ].uniq
209
230
  run("mkdir -p #{dirs.map { |x| x.dump }.join(" ")}")
210
- top.put(chef_solo_gemfile, File.join(chef_solo_path, "Gemfile"))
211
- args = fetch(:chef_solo_bundle_options, [])
212
- args << "--path=#{File.join(chef_solo_path, "bundle").dump}"
213
- args << "--quiet"
214
- run("cd #{chef_solo_path.dump} && #{bundle_cmd} install #{args.join(" ")}")
231
+ if chef_solo_use_bundler
232
+ top.put(chef_solo_gemfile, File.join(chef_solo_path, "Gemfile"))
233
+ args = fetch(:chef_solo_bundle_options, [])
234
+ args << "--path=#{File.join(chef_solo_path, "bundle").dump}"
235
+ args << "--quiet"
236
+ run("cd #{chef_solo_path.dump} && #{bundle_cmd} install #{args.join(" ")}")
237
+ else
238
+ chef_solo_gem_dependencies.each do |name, options|
239
+ args = String === options ? "-v #{options.dump}" : "" # options must be a version string
240
+ rbenv.exec("gem install #{args} #{name.dump}", :path => chef_solo_path)
241
+ end
242
+ rbenv.rehash
243
+ end
215
244
  end
216
245
  }
217
246
 
247
+ task(:uninstall, :except => { :no_release => true }) {
248
+ if chef_solo_use_bundler
249
+ run("rm -f #{File.join(chef_solo_path, "Gemfile").dump} #{File.join(chef_solo_path, "Gemfile.lock").dump}")
250
+ run("rm -rf #{File.join(chef_solo_path, "bundle").dump}")
251
+ else
252
+ chef_solo_gem_dependencies.each do |name, options|
253
+ args = String === options ? "-v #{options.dump}" : "" # options must be a version string
254
+ rbenv.exec("gem uninstall -I -x #{args} #{name.dump}", :path => chef_solo_path)
255
+ end
256
+ end
257
+ }
258
+
218
259
  def update(options={})
219
260
  update_cookbooks(options)
261
+ update_data_bags(options)
220
262
  update_attributes(options)
221
263
  update_config(options)
222
264
  end
223
265
 
224
266
  def update_cookbooks(options={})
225
- _normalize_cookbooks(chef_solo_cookbooks).each do |name, variables|
267
+ repos = _normalize_cookbooks(chef_solo_cookbooks)
268
+ _install_repos(:cookbooks, repos, chef_solo_cookbooks_path, options) do |name, tmpdir, variables|
269
+ deploy_cookbooks(name, tmpdir, variables, options)
270
+ end
271
+ end
272
+
273
+ def update_data_bags(options={})
274
+ repos = _normalize_data_bags(chef_solo_data_bags)
275
+ _install_repos(:data_bags, repos, chef_solo_data_bags_path, options) do |name, tmpdir, variables|
276
+ deploy_data_bags(name, tmpdir, variables, options)
277
+ end
278
+ end
279
+
280
+ def _install_repos(t, repos, destination, options={}, &block)
281
+ # (0) remove existing old data
282
+ run("rm -rf #{destination.dump} && mkdir -p #{destination.dump}", options)
283
+ repos.each do |name, variables|
226
284
  begin
227
- tmpdir = capture("mktemp -d /tmp/cookbooks.XXXXXXXXXX", options).strip
285
+ tmpdir = capture("mktemp -d #{File.join("/tmp", "#{t}.XXXXXXXXXX").dump}", options).strip
228
286
  run("rm -rf #{tmpdir.dump} && mkdir -p #{tmpdir.dump}", options)
229
- deploy_cookbooks(name, tmpdir, variables, options)
230
- install_cookbooks(name, tmpdir, chef_solo_cookbooks_path, options)
287
+ # (1) caller deploys the repository to tmpdir
288
+ yield name, tmpdir, variables
289
+ # (2) then deploy it to actual destination
290
+ logger.debug("installing #{t} `#{name}' from #{tmpdir} to #{destination}.")
291
+ run("rsync -lrpt #{(tmpdir + "/").dump} #{destination.dump}", options)
231
292
  ensure
232
293
  run("rm -rf #{tmpdir.dump}", options)
233
294
  end
234
295
  end
235
296
  end
236
297
 
237
- #
238
- # The definition of cookbooks.
239
- # By default, load cookbooks from local path of "config/cookbooks".
240
- #
241
- _cset(:chef_solo_cookbooks_exclude, %w(.hg .git .svn))
242
- _cset(:chef_solo_cookbooks_default_variables) {{
298
+ _cset(:chef_solo_repository_cache) { File.expand_path("tmp") }
299
+ _cset(:chef_solo_repository_exclude, %w(.hg .git .svn))
300
+ _cset(:chef_solo_repository_variables) {{
243
301
  :scm => :none,
244
302
  :deploy_via => :copy_subdir,
245
303
  :deploy_subdir => nil,
246
304
  :repository => ".",
247
- :cookbooks_exclude => chef_solo_cookbooks_exclude,
248
305
  :copy_cache => nil,
249
306
  }}
250
- _cset(:chef_solo_cookbooks) {
251
- variables = chef_solo_cookbooks_default_variables.dup
252
- variables[:scm] = fetch(:chef_solo_cookbooks_scm) if exists?(:chef_solo_cookbooks_scm)
253
- variables[:deploy_subdir] = fetch(:chef_solo_cookbooks_subdir, "config/cookbooks")
254
- variables[:repository] = fetch(:chef_solo_cookbooks_repository) if exists?("chef_solo_cookbooks_repository")
255
- variables[:revision] = fetch(:chef_solo_cookbooks_revision) if exists?(:chef_solo_cookbooks_revision)
256
- if exists?(:chef_solo_cookbook_name)
257
- # deploy as single cookbook
258
- name = fetch(:chef_solo_cookbook_name)
259
- { name => variables.merge(:cookbook_name => name) }
307
+
308
+ #
309
+ # The definition of cookbooks.
310
+ # By default, load cookbooks from local path of "config/cookbooks".
311
+ #
312
+ _cset(:chef_solo_cookbooks_exclude) { chef_solo_repository_exclude }
313
+ _cset(:chef_solo_cookbooks_variables) { chef_solo_repository_variables.merge(:copy_exclude => chef_solo_cookbooks_exclude) }
314
+ _cset(:chef_solo_cookbooks) { _default_repos(:cookbook, chef_solo_cookbooks_variables) }
315
+ _cset(:chef_solo_cookbooks_cache) { File.join(chef_solo_repository_cache, "cookbooks-cache") }
316
+ def _normalize_cookbooks(repos)
317
+ _normalize_repos(repos, chef_solo_cookbooks_cache, chef_solo_cookbooks_variables) { |name, variables|
318
+ variables[:deploy_subdir] ||= variables[:cookbooks] # use :cookbooks as :deploy_subdir for backward compatibility with prior than 0.1.2
319
+ variables[:copy_exclude] ||= variables[:cookbooks_exclude]
320
+ }
321
+ end
322
+
323
+ #
324
+ # The definition of data_bags.
325
+ # By default, load data_bags from local path of "config/data_bags".
326
+ #
327
+ _cset(:chef_solo_data_bags_exclude) { chef_solo_repository_exclude }
328
+ _cset(:chef_solo_data_bags_variables) { chef_solo_repository_variables.merge(:copy_exclude => chef_solo_data_bags_exclude) }
329
+ _cset(:chef_solo_data_bags) { _default_repos(:data_bag, chef_solo_data_bags_variables) }
330
+ _cset(:chef_solo_data_bags_cache) { File.join(chef_solo_repository_cache, "data_bags-cache") }
331
+ def _normalize_data_bags(repos)
332
+ _normalize_repos(repos, chef_solo_data_bags_cache, chef_solo_data_bags_variables) { |name, variables|
333
+ variables[:deploy_subdir] ||= variables[:data_bags] # use :data_bags as :deploy_subdir for backward compatibility with prior than 0.1.2
334
+ variables[:copy_exclude] ||= variables[:data_bags_exclude]
335
+ }
336
+ end
337
+
338
+ def _default_repos(singular, variables={}, &block)
339
+ plural = "#{singular}s"
340
+ variables = variables.dup
341
+ variables[:scm] = fetch("chef_solo_#{plural}_scm".to_sym) if exists?("chef_solo_#{plural}_scm".to_sym)
342
+ variables[:deploy_subdir] = fetch("chef_solo_#{plural}_subdir".to_sym, File.join("config", plural))
343
+ variables[:repository] = fetch("chef_solo_#{plural}_repository".to_sym) if exists?("chef_solo_#{plural}_repository".to_sym)
344
+ variables[:revision] = fetch("chef_solo_#{plural}_revision".to_sym) if exists?("chef_solo_#{plural}_revision".to_sym)
345
+ if exists?("chef_solo_#{singular}_name".to_sym)
346
+ name = fetch("chef_solo_#{singular}_name".to_sym) # deploy as single cookbook
347
+ variables["#{singular}_name".to_sym] = name
260
348
  else
261
- # deploy as multiple cookbooks
262
- name = fetch(:chef_solo_cookbooks_name, application)
263
- { name => variables }
349
+ name = fetch("chef_solo_#{plural}_name".to_sym, application) # deploy as multiple cookbooks
264
350
  end
265
- }
351
+ { name => variables }
352
+ end
266
353
 
267
- _cset(:chef_solo_repository_cache) { File.expand_path("tmp/cookbooks-cache") }
268
- def _normalize_cookbooks(cookbooks)
269
- xs = cookbooks.map { |name, variables|
270
- variables = chef_solo_cookbooks_default_variables.merge(variables)
354
+ def _normalize_repos(repos, cache_path, default_variables={}, &block)
355
+ normalized = repos.map { |name, variables|
356
+ variables = default_variables.merge(variables)
271
357
  variables[:application] ||= name
272
- # use :cookbooks as :deploy_subdir for backward compatibility with prior than 0.1.2
273
- variables[:deploy_subdir] ||= variables[:cookbooks]
274
358
  if variables[:scm] != :none
275
- variables[:copy_cache] ||= File.expand_path(name, chef_solo_repository_cache)
359
+ variables[:copy_cache] ||= File.expand_path(name, cache_path)
276
360
  end
361
+ yield name, variables
277
362
  [name, variables]
278
363
  }
279
- Hash[xs]
364
+ Hash[normalized]
280
365
  end
281
366
 
282
367
  def deploy_cookbooks(name, destination, variables={}, options={})
283
- logger.debug("retrieving cookbooks `#{name}' from #{variables[:repository]} via #{variables[:deploy_via]}.")
368
+ # deploy as single cookbook, or deploy as multiple cookbooks
369
+ final_destination = variables.key?(:cookbook_name) ? File.join(destination, variables[:cookbook_name]) : destination
370
+ _deploy_repo(:cookbooks, name, final_destination, variables, options)
371
+ end
372
+
373
+ def deploy_data_bags(name, destination, variables={}, options={})
374
+ # deploy as single data_bag, or deploy as multiple data_bags
375
+ final_destination = variables.key?(:data_bag_name) ? File.join(destination, variables[:data_bag_name]) : destination
376
+ _deploy_repo(:data_bags, name, final_destination, variables, options)
377
+ end
378
+
379
+ def _deploy_repo(t, name, destination, variables={}, options={})
284
380
  begin
285
381
  releases_path = capture("mktemp -d /tmp/releases.XXXXXXXXXX", options).strip
286
382
  release_path = File.join(releases_path, release_name)
@@ -295,18 +391,18 @@ module Capistrano
295
391
  set(:real_revision) { source.local.query_revision(revision) { |cmd| with_env("LC_ALL", "C") { run_locally(cmd) } } }
296
392
  set(:strategy) { ::Capistrano::Deploy::Strategy.new(deploy_via, self) }
297
393
  variables.each do |key, val|
298
- set(key, val)
394
+ if val.nil?
395
+ unset(key)
396
+ else
397
+ set(key, val)
398
+ end
299
399
  end
400
+ from = File.join(repository, fetch(:deploy_subdir, "/"))
401
+ to = destination
402
+ logger.debug("retrieving #{t} `#{name}' from #{from} (scm=#{scm}, via=#{deploy_via}) to #{to}.")
300
403
  strategy.deploy!
301
404
  end
302
- if variables.key?(:cookbook_name)
303
- # deploy as single cookbook
304
- final_destination = File.join(destination, variables[:cookbook_name])
305
- else
306
- # deploy as multiple cookbooks
307
- final_destination = destination
308
- end
309
- run("rsync -lrpt #{(release_path + "/").dump} #{final_destination.dump}", options)
405
+ run("rsync -lrpt #{(release_path + "/").dump} #{destination.dump}", options)
310
406
  ensure
311
407
  run("rm -rf #{releases_path.dump}", options)
312
408
  end
@@ -321,16 +417,11 @@ module Capistrano
321
417
  o
322
418
  end
323
419
 
324
- def install_cookbooks(name, source, destination, options={})
325
- logger.debug("installing cookbooks `#{name}' to #{destination}.")
326
- run("mkdir -p #{source.dump} #{destination.dump}", options)
327
- run("rsync -lrpt #{(source + "/").dump} #{destination.dump}", options)
328
- end
329
-
330
420
  _cset(:chef_solo_config) {
331
421
  (<<-EOS).gsub(/^\s*/, "")
332
422
  file_cache_path #{chef_solo_cache_path.dump}
333
423
  cookbook_path #{chef_solo_cookbooks_path.dump}
424
+ data_bag_path #{chef_solo_data_bags_path.dump}
334
425
  EOS
335
426
  }
336
427
  def update_config(options={})
@@ -386,7 +477,6 @@ module Capistrano
386
477
  def _generate_attributes(options={})
387
478
  hosts = [ options.delete(:hosts) ].flatten.compact.uniq
388
479
  roles = [ options.delete(:roles) ].flatten.compact.uniq
389
- run_list = [ options.delete(:run_list) ].flatten.compact.uniq
390
480
  #
391
481
  # By default, the Chef attributes will be generated by following order.
392
482
  #
@@ -404,43 +494,46 @@ module Capistrano
404
494
  _merge_attributes!(attributes, chef_solo_host_attributes.fetch(host, {}))
405
495
  end
406
496
  #
407
- # The Chef `run_list` will be generated by following rules.
497
+ # The Chef `run_list` will be generated from `:chef_solo_role_run_list` and
498
+ # `:chef_solo_host_run_list`.
408
499
  #
409
- # * If `:run_list` was given as argument, just use it.
410
- # * Otherwise, generate it from `:chef_solo_role_run_list`, `:chef_solo_role_run_list`
411
- # and `:chef_solo_host_run_list`.
412
- #
413
- if run_list.empty?
414
- _merge_attributes!(attributes, {"run_list" => chef_solo_run_list})
415
- roles.each do |role|
416
- _merge_attributes!(attributes, {"run_list" => chef_solo_role_run_list.fetch(role, [])})
417
- end
418
- hosts.each do |host|
419
- _merge_attributes!(attributes, {"run_list" => chef_solo_host_run_list.fetch(host, [])})
420
- end
421
- else
422
- attributes["run_list"] = [] # ignore run_list not from argument
423
- _merge_attributes!(attributes, {"run_list" => run_list})
500
+ _merge_attributes!(attributes, {"run_list" => chef_solo_run_list})
501
+ roles.each do |role|
502
+ _merge_attributes!(attributes, {"run_list" => chef_solo_role_run_list.fetch(role, [])})
503
+ end
504
+ hosts.each do |host|
505
+ _merge_attributes!(attributes, {"run_list" => chef_solo_host_run_list.fetch(host, [])})
424
506
  end
425
507
  attributes
426
508
  end
427
509
 
428
510
  def update_attributes(options={})
429
- run_list = options.delete(:run_list)
430
511
  servers = find_servers_for_task(current_task)
431
512
  servers.each do |server|
432
513
  logger.debug("updating chef-solo attributes for #{server.host}.")
433
- attributes = _generate_attributes(:hosts => server.host, :roles => role_names_for_host(server), :run_list => run_list)
514
+ attributes = _generate_attributes(:hosts => server.host, :roles => role_names_for_host(server))
434
515
  top.put(_json_attributes(attributes), chef_solo_attributes_file, options.merge(:hosts => server.host))
435
516
  end
436
517
  end
437
518
 
438
519
  def invoke(options={})
520
+ options = options.dup
521
+ run_list = [ options.delete(:run_list) ].flatten.compact
439
522
  logger.debug("invoking chef-solo.")
440
523
  args = fetch(:chef_solo_options, [])
441
- args << "-c #{chef_solo_config_file.dump}"
442
- args << "-j #{chef_solo_attributes_file.dump}"
443
- run("cd #{chef_solo_path.dump} && #{sudo} #{bundle_cmd} exec #{chef_solo_cmd} #{args.join(" ")}", options)
524
+ args += ["-c", chef_solo_config_file]
525
+ args += ["-j", chef_solo_attributes_file]
526
+ args += ["-o", run_list.join(",")] unless run_list.empty?
527
+ execute(args, options.merge(:via => :sudo))
528
+ end
529
+
530
+ def execute(args, options={})
531
+ if chef_solo_use_bundler
532
+ command = "bundle exec #{chef_solo_cmd}"
533
+ else
534
+ command = chef_solo_cmd
535
+ end
536
+ rbenv.exec("#{command} #{[ args ].flatten.compact.map { |x| x.dump }.join(" ")}", options.merge(:path => chef_solo_path))
444
537
  end
445
538
  }
446
539
  }
@@ -1,5 +1,5 @@
1
1
  module Capistrano
2
2
  module ChefSolo
3
- VERSION = "0.1.3"
3
+ VERSION = "0.1.4"
4
4
  end
5
5
  end
@@ -1,5 +1,5 @@
1
1
  /.bundle
2
- /.vagrant
2
+ /.vagrant*
3
3
  /known_hosts
4
4
  /tmp
5
5
  /vendor
@@ -1,7 +1,7 @@
1
1
  #!/bin/sh -e
2
2
 
3
- bundle exec vagrant up
3
+ vagrant up
4
4
  bundle exec cap test_all
5
- bundle exec vagrant halt
5
+ vagrant halt
6
6
 
7
7
  # vim:set ft=sh :
@@ -2,6 +2,7 @@ file "/tmp/single" do
2
2
  owner "root"
3
3
  group "root"
4
4
  mode "0644"
5
+ content data_bag_item("single", "data")["value"]
5
6
  end
6
7
 
7
8
  # vim:set ft=ruby sw=2 ts=2 :
@@ -2,6 +2,7 @@ file "/tmp/one" do
2
2
  owner "root"
3
3
  group "root"
4
4
  mode "0644"
5
+ content data_bag_item("one", "data")["value"]
5
6
  end
6
7
 
7
8
  # vim:set ft=ruby sw=2 ts=2 :
@@ -2,6 +2,7 @@ file "/tmp/three" do
2
2
  owner "root"
3
3
  group "root"
4
4
  mode "0644"
5
+ content data_bag_item("three", "data")["value"]
5
6
  end
6
7
 
7
8
  # vim:set ft=ruby sw=2 ts=2 :
@@ -2,6 +2,7 @@ file "/tmp/two" do
2
2
  owner "root"
3
3
  group "root"
4
4
  mode "0644"
5
+ content data_bag_item("two", "data")["value"]
5
6
  end
6
7
 
7
8
  # vim:set ft=ruby sw=2 ts=2 :
@@ -2,6 +2,7 @@ file "/tmp/bar" do
2
2
  owner "root"
3
3
  group "root"
4
4
  mode "0644"
5
+ content data_bag_item("bar", "data")["value"]
5
6
  end
6
7
 
7
8
  # vim:set ft=ruby sw=2 ts=2 :
@@ -2,6 +2,7 @@ file "/tmp/baz" do
2
2
  owner "root"
3
3
  group "root"
4
4
  mode "0644"
5
+ content data_bag_item("baz", "data")["value"]
5
6
  end
6
7
 
7
8
  # vim:set ft=ruby sw=2 ts=2 :
@@ -2,6 +2,7 @@ file "/tmp/foo" do
2
2
  owner "root"
3
3
  group "root"
4
4
  mode "0644"
5
+ content data_bag_item("foo", "data")["value"]
5
6
  end
6
7
 
7
8
  # vim:set ft=ruby sw=2 ts=2 :
@@ -0,0 +1 @@
1
+ {"id": "data", "value": "SINGLE"}
@@ -0,0 +1 @@
1
+ {"id": "data", "value": "ONE"}
@@ -0,0 +1 @@
1
+ {"id": "data", "value": "THREE"}
@@ -0,0 +1 @@
1
+ {"id": "data", "value": "TWO"}
@@ -0,0 +1 @@
1
+ {"id": "data", "value": "BAR"}
@@ -0,0 +1 @@
1
+ {"id": "data", "value": "BAZ"}
@@ -0,0 +1 @@
1
+ {"id": "data", "value": "FOO"}
@@ -25,6 +25,7 @@ require "tempfile"
25
25
 
26
26
  task(:test_all) {
27
27
  find_and_execute_task("test_default")
28
+ find_and_execute_task("test_without_bundler")
28
29
  find_and_execute_task("test_with_local_cookbooks")
29
30
  find_and_execute_task("test_with_remote_cookbooks")
30
31
  find_and_execute_task("test_with_multiple_cookbooks")
@@ -32,14 +33,18 @@ task(:test_all) {
32
33
  find_and_execute_task("test_without_bootstrap")
33
34
  }
34
35
 
35
- def download_attributes()
36
- tempfile = Tempfile.new("attributes")
37
- download(chef_solo_attributes_file, tempfile.path)
38
- JSON.load(tempfile.read)
36
+ def get_file(file, options={})
37
+ tempfile = Tempfile.new("capistrano-chef-solo")
38
+ top.get(file, tempfile.path, options)
39
+ tempfile.read
39
40
  end
40
41
 
41
- def assert_attributes(expected)
42
- found = download_attributes
42
+ def get_attributes(options={})
43
+ JSON.load(get_file(chef_solo_attributes_file, options))
44
+ end
45
+
46
+ def assert_attributes(expected, options={})
47
+ found = get_attributes(options)
43
48
  expected.each do |key, value|
44
49
  if found[key] != value
45
50
  abort("invalid attribute: #{key.inspect} (expected:#{value.inspect} != found:#{found[key].inspect})")
@@ -47,19 +52,48 @@ def assert_attributes(expected)
47
52
  end
48
53
  end
49
54
 
50
- def assert_run_list(expected)
51
- found = download_attributes["run_list"]
55
+ def assert_run_list(expected, options={})
56
+ found = get_attributes(options)["run_list"]
52
57
  abort("invalid run_list (expected:#{expected.inspect} != found:#{found.inspect})") if found != expected
53
58
  end
54
59
 
55
- def check_applied_recipes!(expected)
56
- files = expected.map { |recipe| /^recipe\[(\w+)\]$/ =~ recipe; File.join("/tmp", $1) }
57
- begin
58
- files.each do |file|
59
- run("test -f #{file.dump}")
60
+ def assert_file_exists(file, options={})
61
+ run("test -f #{file.dump}", options)
62
+ rescue
63
+ abort("assert_file_exists(#{file}) failed.")
64
+ end
65
+
66
+ def assert_file_content(file, content, options={})
67
+ remote_content = get_file(file, options)
68
+ abort("assert_file_content(#{file}) failed. (expected=#{content.inspect}, got=#{remote_content.inspect})") if content != remote_content
69
+ end
70
+
71
+ def recipe_name(recipe)
72
+ if /^recipe\[(\w+)\]$/ =~ recipe
73
+ $1
74
+ else
75
+ abort("not a recipe: #{recipe}")
76
+ end
77
+ end
78
+
79
+ def recipe_filename(recipe)
80
+ File.join("/tmp", recipe_name(recipe))
81
+ end
82
+
83
+ def recipe_content(recipe)
84
+ recipe_name(recipe).upcase
85
+ end
86
+
87
+ def _test_recipes(recipes, options={})
88
+ recipes.each do |recipe|
89
+ file = recipe_filename(recipe)
90
+ body = recipe_content(recipe)
91
+ begin
92
+ assert_file_exists(file, options)
93
+ assert_file_content(file, body, options)
94
+ ensure
95
+ sudo("rm -f #{file.dump}", options) rescue nil
60
96
  end
61
- ensure
62
- sudo("rm -f #{files.map { |x| x.dump }.join(" ")}") rescue nil
63
97
  end
64
98
  end
65
99
 
@@ -86,6 +120,7 @@ namespace(:test_default) {
86
120
 
87
121
  task(:setup) {
88
122
  reset_chef_solo!
123
+ set(:chef_solo_use_bundler, true)
89
124
  set(:chef_solo_attributes, {"aaa" => "AAA"})
90
125
  set(:chef_solo_role_attributes, {:app => {"bbb" => "BBB"}})
91
126
  set(:chef_solo_host_attributes, {"192.168.33.10" => {"ccc" => "CCC"}})
@@ -93,6 +128,12 @@ namespace(:test_default) {
93
128
  set(:chef_solo_role_run_list, {:app => %w(recipe[bar])})
94
129
  set(:chef_solo_host_run_list, {"192.168.33.10" => %w(recipe[baz])})
95
130
  set(:chef_solo_capistrano_attributes_include, [:application, :deploy_to])
131
+ set(:chef_solo_cookbooks_scm, :none)
132
+ set(:chef_solo_cookbooks_repository, File.expand_path("..", File.dirname(__FILE__)))
133
+ set(:chef_solo_cookbooks_subdir, "config/cookbooks")
134
+ set(:chef_solo_data_bags_scm, :none)
135
+ set(:chef_solo_data_bags_repository, File.expand_path("..", File.dirname(__FILE__)))
136
+ set(:chef_solo_data_bags_subdir, "config/data_bags")
96
137
  }
97
138
 
98
139
  task(:teardown) {
@@ -113,6 +154,53 @@ namespace(:test_default) {
113
154
  }
114
155
  }
115
156
 
157
+ namespace(:test_without_bundler) {
158
+ task(:default) {
159
+ methods.grep(/^test_/).each do |m|
160
+ send(m)
161
+ end
162
+ }
163
+ before "test_without_bundler", "test_without_bundler:setup"
164
+ after "test_without_bundler", "test_without_bundler:teardown"
165
+
166
+ task(:setup) {
167
+ reset_chef_solo!
168
+ set(:chef_solo_use_bundler, false)
169
+ set(:chef_solo_run_list, %w(recipe[foo] recipe[bar]))
170
+ set(:chef_solo_cookbooks_scm, :none)
171
+ set(:chef_solo_cookbooks_repository, File.expand_path("..", File.dirname(__FILE__)))
172
+ set(:chef_solo_cookbooks_subdir, "config/cookbooks")
173
+ set(:chef_solo_data_bags_scm, :none)
174
+ set(:chef_solo_data_bags_repository, File.expand_path("..", File.dirname(__FILE__)))
175
+ set(:chef_solo_data_bags_subdir, "config/data_bags")
176
+ }
177
+
178
+ task(:teardown) {
179
+ }
180
+
181
+ task(:test_setup) {
182
+ find_and_execute_task("chef-solo:setup")
183
+ }
184
+
185
+ task(:test_version) {
186
+ find_and_execute_task("chef-solo:version")
187
+ }
188
+
189
+ task(:test_invoke) {
190
+ expected = chef_solo_run_list
191
+ find_and_execute_task("chef-solo")
192
+ assert_run_list(expected)
193
+ _test_recipes(expected)
194
+ }
195
+
196
+ task(:test_run_list) {
197
+ expected = %w(recipe[baz])
198
+ chef_solo.run_list expected
199
+ # assert_run_list(expected) # arguments of chef_solo.run_list will not be written to attributes file
200
+ _test_recipes(expected)
201
+ }
202
+ }
203
+
116
204
  namespace(:test_with_local_cookbooks) {
117
205
  task(:default) {
118
206
  methods.grep(/^test_/).each do |m|
@@ -124,10 +212,14 @@ namespace(:test_with_local_cookbooks) {
124
212
 
125
213
  task(:setup) {
126
214
  reset_chef_solo!
215
+ set(:chef_solo_use_bundler, true)
127
216
  set(:chef_solo_run_list, %w(recipe[foo] recipe[bar]))
128
217
  set(:chef_solo_cookbooks_scm, :none)
129
218
  set(:chef_solo_cookbooks_repository, File.expand_path("..", File.dirname(__FILE__)))
130
219
  set(:chef_solo_cookbooks_subdir, "config/cookbooks")
220
+ set(:chef_solo_data_bags_scm, :none)
221
+ set(:chef_solo_data_bags_repository, File.expand_path("..", File.dirname(__FILE__)))
222
+ set(:chef_solo_data_bags_subdir, "config/data_bags")
131
223
  }
132
224
 
133
225
  task(:teardown) {
@@ -137,14 +229,14 @@ namespace(:test_with_local_cookbooks) {
137
229
  expected = chef_solo_run_list
138
230
  find_and_execute_task("chef-solo")
139
231
  assert_run_list(expected)
140
- check_applied_recipes!(expected)
232
+ _test_recipes(expected)
141
233
  }
142
234
 
143
235
  task(:test_run_list) {
144
236
  expected = %w(recipe[baz])
145
237
  chef_solo.run_list expected
146
- assert_run_list(expected)
147
- check_applied_recipes!(expected)
238
+ # assert_run_list(expected) # arguments of chef_solo.run_list will not be written to attributes file
239
+ _test_recipes(expected)
148
240
  }
149
241
  }
150
242
 
@@ -159,11 +251,16 @@ namespace(:test_with_remote_cookbooks) {
159
251
 
160
252
  task(:setup) {
161
253
  reset_chef_solo!
254
+ set(:chef_solo_use_bundler, true)
162
255
  set(:chef_solo_run_list, %w(recipe[one] recipe[two]))
163
256
  set(:chef_solo_cookbooks_scm, :git)
164
257
  set(:chef_solo_cookbooks_repository, "git://github.com/yyuu/capistrano-chef-solo.git")
165
258
  set(:chef_solo_cookbooks_revision, "develop")
166
259
  set(:chef_solo_cookbooks_subdir, "test/config/cookbooks-ext")
260
+ set(:chef_solo_data_bags_scm, :git)
261
+ set(:chef_solo_data_bags_repository, "git://github.com/yyuu/capistrano-chef-solo.git")
262
+ set(:chef_solo_data_bags_revision, "develop")
263
+ set(:chef_solo_data_bags_subdir, "test/config/data_bags-ext")
167
264
  }
168
265
 
169
266
  task(:teardown) {
@@ -173,14 +270,14 @@ namespace(:test_with_remote_cookbooks) {
173
270
  expected = chef_solo_run_list
174
271
  find_and_execute_task("chef-solo")
175
272
  assert_run_list(expected)
176
- check_applied_recipes!(expected)
273
+ _test_recipes(expected)
177
274
  }
178
275
 
179
276
  task(:test_run_list) {
180
277
  expected = %w(recipe[three])
181
278
  chef_solo.run_list expected
182
- assert_run_list(expected)
183
- check_applied_recipes!(expected)
279
+ # assert_run_list(expected) # arguments of chef_solo.run_list will not be written to attributes file
280
+ _test_recipes(expected)
184
281
  }
185
282
  }
186
283
 
@@ -195,6 +292,7 @@ namespace(:test_with_multiple_cookbooks) {
195
292
 
196
293
  task(:setup) {
197
294
  reset_chef_solo!
295
+ set(:chef_solo_use_bundler, true)
198
296
  set(:chef_solo_run_list, %w(recipe[bar] recipe[baz] recipe[two] recipe[three]))
199
297
  set(:chef_solo_cookbooks) {{
200
298
  "local" => {
@@ -215,6 +313,25 @@ namespace(:test_with_multiple_cookbooks) {
215
313
  :cookbooks => "test/config/cookbooks-ext",
216
314
  },
217
315
  }}
316
+ set(:chef_solo_data_bags) {{
317
+ "local" => {
318
+ :scm => :none,
319
+ :repository => File.expand_path("..", File.dirname(__FILE__)),
320
+ :data_bags => "config/data_bags",
321
+ },
322
+ "single" => {
323
+ :data_bag_name => "single",
324
+ :scm => :none,
325
+ :repository => File.expand_path("..", File.dirname(__FILE__)),
326
+ :data_bags => "config/data_bag",
327
+ },
328
+ application => {
329
+ :scm => :git,
330
+ :repository => "git://github.com/yyuu/capistrano-chef-solo.git",
331
+ :revision => "develop",
332
+ :data_bags => "test/config/data_bags-ext",
333
+ },
334
+ }}
218
335
  }
219
336
 
220
337
  task(:teardown) {
@@ -224,14 +341,14 @@ namespace(:test_with_multiple_cookbooks) {
224
341
  expected = chef_solo_run_list
225
342
  find_and_execute_task("chef-solo")
226
343
  assert_run_list(expected)
227
- check_applied_recipes!(expected)
344
+ _test_recipes(expected)
228
345
  }
229
346
 
230
347
  task(:test_run_list) {
231
348
  expected = %w(recipe[foo] recipe[single] recipe[one])
232
349
  chef_solo.run_list expected
233
- assert_run_list(expected)
234
- check_applied_recipes!(expected)
350
+ # assert_run_list(expected) # arguments of chef_solo.run_list will not be written to attributes file
351
+ _test_recipes(expected)
235
352
  }
236
353
  }
237
354
 
@@ -245,11 +362,12 @@ namespace(:test_with_bootstrap) {
245
362
  after "test_with_bootstrap", "test_with_bootstrap:teardown"
246
363
 
247
364
  task(:setup) {
365
+ set(:chef_solo_use_bundler, true)
248
366
  set(:chef_solo_bootstrap, true)
249
367
  set(:chef_solo_bootstrap_user, "bootstrap")
250
368
  set(:chef_solo_bootstrap_password, "bootstrap")
251
369
  set(:chef_solo_bootstrap_ssh_options, {
252
- # :auth_methods => %w(password), #==> setting :auth_methods throws Net::SSH::AuthenticationFailed (capistrano bug?)
370
+ # :auth_methods => %w(password), #==> FIXME: setting :auth_methods throws Net::SSH::AuthenticationFailed (capistrano bug?)
253
371
  :user_known_hosts_file => "/dev/null",
254
372
  })
255
373
  run("getent passwd #{chef_solo_bootstrap_user.dump} || " +
@@ -292,6 +410,7 @@ namespace(:test_without_bootstrap) {
292
410
  after "test_without_bootstrap", "test_without_bootstrap:teardown"
293
411
 
294
412
  task(:setup) {
413
+ set(:chef_solo_use_bundler, true)
295
414
  set(:chef_solo_bootstrap, false)
296
415
  set(:chef_solo_bootstrap_user, "bootstrap")
297
416
  set(:chef_solo_bootstrap_password, "bootstrap")
@@ -1,5 +1,5 @@
1
1
  /.bundle
2
- /.vagrant
2
+ /.vagrant*
3
3
  /known_hosts
4
4
  /tmp
5
5
  /vendor
@@ -1,7 +1,7 @@
1
1
  #!/bin/sh -e
2
2
 
3
- bundle exec vagrant up
3
+ vagrant up
4
4
  bundle exec cap test_all
5
- bundle exec vagrant halt
5
+ vagrant halt
6
6
 
7
7
  # vim:set ft=sh :
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yyuu-capistrano-chef-solo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-08 00:00:00.000000000 Z
12
+ date: 2013-04-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: capistrano
@@ -50,7 +50,7 @@ dependencies:
50
50
  requirements:
51
51
  - - ! '>='
52
52
  - !ruby/object:Gem::Version
53
- version: 1.0.0
53
+ version: 1.0.1
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
@@ -58,55 +58,7 @@ dependencies:
58
58
  requirements:
59
59
  - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
- version: 1.0.0
62
- - !ruby/object:Gem::Dependency
63
- name: net-scp
64
- requirement: !ruby/object:Gem::Requirement
65
- none: false
66
- requirements:
67
- - - ~>
68
- - !ruby/object:Gem::Version
69
- version: 1.0.4
70
- type: :development
71
- prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
- requirements:
75
- - - ~>
76
- - !ruby/object:Gem::Version
77
- version: 1.0.4
78
- - !ruby/object:Gem::Dependency
79
- name: net-ssh
80
- requirement: !ruby/object:Gem::Requirement
81
- none: false
82
- requirements:
83
- - - ~>
84
- - !ruby/object:Gem::Version
85
- version: 2.2.2
86
- type: :development
87
- prerelease: false
88
- version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
- requirements:
91
- - - ~>
92
- - !ruby/object:Gem::Version
93
- version: 2.2.2
94
- - !ruby/object:Gem::Dependency
95
- name: vagrant
96
- requirement: !ruby/object:Gem::Requirement
97
- none: false
98
- requirements:
99
- - - ~>
100
- - !ruby/object:Gem::Version
101
- version: 1.0.6
102
- type: :development
103
- prerelease: false
104
- version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
- requirements:
107
- - - ~>
108
- - !ruby/object:Gem::Version
109
- version: 1.0.6
61
+ version: 1.0.1
110
62
  description: a capistrano recipe to invoke chef-solo.
111
63
  email:
112
64
  - yamashita@geishatokyo.com
@@ -141,6 +93,13 @@ files:
141
93
  - test/config/cookbooks/baz/recipes/default.rb
142
94
  - test/config/cookbooks/foo/metadata.rb
143
95
  - test/config/cookbooks/foo/recipes/default.rb
96
+ - test/config/data_bag/single.json
97
+ - test/config/data_bags-ext/one/one.json
98
+ - test/config/data_bags-ext/three/three.json
99
+ - test/config/data_bags-ext/two/two.json
100
+ - test/config/data_bags/bar/bar.json
101
+ - test/config/data_bags/baz/baz.json
102
+ - test/config/data_bags/foo/foo.json
144
103
  - test/config/deploy.rb
145
104
  - test/precise64/.gitignore
146
105
  - test/precise64/Capfile
@@ -191,6 +150,13 @@ test_files:
191
150
  - test/config/cookbooks/baz/recipes/default.rb
192
151
  - test/config/cookbooks/foo/metadata.rb
193
152
  - test/config/cookbooks/foo/recipes/default.rb
153
+ - test/config/data_bag/single.json
154
+ - test/config/data_bags-ext/one/one.json
155
+ - test/config/data_bags-ext/three/three.json
156
+ - test/config/data_bags-ext/two/two.json
157
+ - test/config/data_bags/bar/bar.json
158
+ - test/config/data_bags/baz/baz.json
159
+ - test/config/data_bags/foo/foo.json
194
160
  - test/config/deploy.rb
195
161
  - test/precise64/.gitignore
196
162
  - test/precise64/Capfile