vagabond 0.2.8 → 0.2.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. data/CHANGELOG.md +16 -0
  2. data/DEVELOP.md +38 -0
  3. data/Gemfile +3 -0
  4. data/Gemfile.lock +33 -0
  5. data/README.md +55 -21
  6. data/USAGE.md +28 -3
  7. data/Vagabondfile.sample +47 -0
  8. data/Vagrantfile +17 -5
  9. data/bin/vagabond +5 -0
  10. data/lib/vagabond/Cheffile +7 -0
  11. data/lib/vagabond/Cheffile.dev +7 -0
  12. data/lib/vagabond/actions/cluster.rb +22 -8
  13. data/lib/vagabond/actions/create.rb +7 -4
  14. data/lib/vagabond/actions/destroy.rb +24 -14
  15. data/lib/vagabond/actions/freeze.rb +1 -0
  16. data/lib/vagabond/actions/init.rb +8 -11
  17. data/lib/vagabond/actions/provision.rb +16 -8
  18. data/lib/vagabond/actions/rebuild.rb +4 -9
  19. data/lib/vagabond/actions/ssh.rb +9 -1
  20. data/lib/vagabond/actions/start.rb +1 -0
  21. data/lib/vagabond/actions/status.rb +1 -0
  22. data/lib/vagabond/actions/thaw.rb +1 -0
  23. data/lib/vagabond/actions/up.rb +22 -7
  24. data/lib/vagabond/bootstraps/chef_10_compat_config.erb +62 -0
  25. data/lib/vagabond/bootstraps/no_lazy_load.erb +63 -0
  26. data/lib/vagabond/bootstraps/server-zero.erb +1 -8
  27. data/lib/vagabond/bootstraps/server.erb +9 -6
  28. data/lib/vagabond/constants.rb +1 -6
  29. data/lib/vagabond/core.rb +209 -0
  30. data/lib/vagabond/errors.rb +3 -0
  31. data/lib/vagabond/helpers.rb +11 -99
  32. data/lib/vagabond/helpers/base.rb +134 -0
  33. data/lib/vagabond/helpers/callbacks.rb +47 -0
  34. data/lib/vagabond/helpers/chains.rb +23 -0
  35. data/lib/vagabond/helpers/commands.rb +49 -0
  36. data/lib/vagabond/helpers/knife.rb +47 -0
  37. data/lib/vagabond/helpers/naming.rb +39 -0
  38. data/lib/vagabond/helpers/server.rb +30 -0
  39. data/lib/vagabond/internal_configuration.rb +186 -32
  40. data/lib/vagabond/kitchen.rb +110 -60
  41. data/lib/vagabond/knife.rb +5 -1
  42. data/lib/vagabond/layout.rb +1 -0
  43. data/lib/vagabond/monkey/kitchen_config.rb +1 -0
  44. data/lib/vagabond/notify_mash.rb +25 -0
  45. data/lib/vagabond/server.rb +81 -49
  46. data/lib/vagabond/settings.rb +17 -0
  47. data/lib/vagabond/spec.rb +125 -99
  48. data/lib/vagabond/uploader.rb +4 -1
  49. data/lib/vagabond/uploader/berkshelf.rb +2 -1
  50. data/lib/vagabond/uploader/knife.rb +3 -9
  51. data/lib/vagabond/uploader/librarian.rb +2 -5
  52. data/lib/vagabond/vagabond.rb +77 -93
  53. data/lib/vagabond/vagabondfile.rb +73 -9
  54. data/lib/vagabond/version.rb +2 -1
  55. data/vagabond.gemspec +7 -5
  56. metadata +58 -81
  57. data/lib/vagabond/cookbooks/apt/Berksfile +0 -8
  58. data/lib/vagabond/cookbooks/apt/CHANGELOG.md +0 -97
  59. data/lib/vagabond/cookbooks/apt/CONTRIBUTING +0 -29
  60. data/lib/vagabond/cookbooks/apt/LICENSE +0 -201
  61. data/lib/vagabond/cookbooks/apt/README.md +0 -243
  62. data/lib/vagabond/cookbooks/apt/TESTING.md +0 -25
  63. data/lib/vagabond/cookbooks/apt/attributes/default.rb +0 -4
  64. data/lib/vagabond/cookbooks/apt/files/default/apt-proxy-v2.conf +0 -50
  65. data/lib/vagabond/cookbooks/apt/metadata.rb +0 -30
  66. data/lib/vagabond/cookbooks/apt/providers/preference.rb +0 -61
  67. data/lib/vagabond/cookbooks/apt/providers/repository.rb +0 -132
  68. data/lib/vagabond/cookbooks/apt/recipes/cacher-client.rb +0 -59
  69. data/lib/vagabond/cookbooks/apt/recipes/cacher-ng.rb +0 -40
  70. data/lib/vagabond/cookbooks/apt/recipes/default.rb +0 -68
  71. data/lib/vagabond/cookbooks/apt/resources/preference.rb +0 -30
  72. data/lib/vagabond/cookbooks/apt/resources/repository.rb +0 -40
  73. data/lib/vagabond/cookbooks/apt/templates/debian-6.0/acng.conf.erb +0 -174
  74. data/lib/vagabond/cookbooks/apt/templates/default/01proxy.erb +0 -2
  75. data/lib/vagabond/cookbooks/apt/templates/default/acng.conf.erb +0 -276
  76. data/lib/vagabond/cookbooks/apt/templates/ubuntu-10.04/acng.conf.erb +0 -270
  77. data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/README.md +0 -1
  78. data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/files/default/tests/minitest/cacher-ng_test.rb +0 -28
  79. data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/files/default/tests/minitest/default_test.rb +0 -28
  80. data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/files/default/tests/minitest/lwrps_test.rb +0 -48
  81. data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/files/default/tests/minitest/support/helpers.rb +0 -29
  82. data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/metadata.rb +0 -6
  83. data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/recipes/cacher-ng.rb +0 -20
  84. data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/recipes/default.rb +0 -20
  85. data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/recipes/lwrps.rb +0 -66
  86. data/lib/vagabond/cookbooks/lxc/CHANGELOG.md +0 -37
  87. data/lib/vagabond/cookbooks/lxc/Gemfile +0 -4
  88. data/lib/vagabond/cookbooks/lxc/Gemfile.lock +0 -41
  89. data/lib/vagabond/cookbooks/lxc/README.md +0 -112
  90. data/lib/vagabond/cookbooks/lxc/attributes/default.rb +0 -26
  91. data/lib/vagabond/cookbooks/lxc/files/default/knife_lxc +0 -228
  92. data/lib/vagabond/cookbooks/lxc/files/default/lxc-awesome-ephemeral +0 -499
  93. data/lib/vagabond/cookbooks/lxc/libraries/lxc.rb +0 -477
  94. data/lib/vagabond/cookbooks/lxc/libraries/lxc_expanded_resources.rb +0 -40
  95. data/lib/vagabond/cookbooks/lxc/libraries/lxc_file_config.rb +0 -84
  96. data/lib/vagabond/cookbooks/lxc/libraries/monkey.rb +0 -51
  97. data/lib/vagabond/cookbooks/lxc/metadata.rb +0 -12
  98. data/lib/vagabond/cookbooks/lxc/providers/config.rb +0 -75
  99. data/lib/vagabond/cookbooks/lxc/providers/container.rb +0 -354
  100. data/lib/vagabond/cookbooks/lxc/providers/default.rb +0 -57
  101. data/lib/vagabond/cookbooks/lxc/providers/ephemeral.rb +0 -40
  102. data/lib/vagabond/cookbooks/lxc/providers/fstab.rb +0 -30
  103. data/lib/vagabond/cookbooks/lxc/providers/interface.rb +0 -45
  104. data/lib/vagabond/cookbooks/lxc/providers/service.rb +0 -53
  105. data/lib/vagabond/cookbooks/lxc/recipes/containers.rb +0 -13
  106. data/lib/vagabond/cookbooks/lxc/recipes/default.rb +0 -58
  107. data/lib/vagabond/cookbooks/lxc/recipes/install_dependencies.rb +0 -15
  108. data/lib/vagabond/cookbooks/lxc/recipes/knife.rb +0 -37
  109. data/lib/vagabond/cookbooks/lxc/resources/config.rb +0 -19
  110. data/lib/vagabond/cookbooks/lxc/resources/container.rb +0 -54
  111. data/lib/vagabond/cookbooks/lxc/resources/default.rb +0 -12
  112. data/lib/vagabond/cookbooks/lxc/resources/ephemeral.rb +0 -13
  113. data/lib/vagabond/cookbooks/lxc/resources/fstab.rb +0 -12
  114. data/lib/vagabond/cookbooks/lxc/resources/interface.rb +0 -13
  115. data/lib/vagabond/cookbooks/lxc/resources/service.rb +0 -5
  116. data/lib/vagabond/cookbooks/lxc/templates/default/client.rb.erb +0 -13
  117. data/lib/vagabond/cookbooks/lxc/templates/default/default-lxc.erb +0 -3
  118. data/lib/vagabond/cookbooks/lxc/templates/default/file_content.erb +0 -2
  119. data/lib/vagabond/cookbooks/lxc/templates/default/fstab.erb +0 -5
  120. data/lib/vagabond/cookbooks/lxc/templates/default/interface.erb +0 -27
  121. data/lib/vagabond/cookbooks/vagabond/README.md +0 -10
  122. data/lib/vagabond/cookbooks/vagabond/attributes/default.rb +0 -18
  123. data/lib/vagabond/cookbooks/vagabond/files/default/lxc-centos +0 -460
  124. data/lib/vagabond/cookbooks/vagabond/libraries/vagabond.rb +0 -10
  125. data/lib/vagabond/cookbooks/vagabond/metadata.rb +0 -8
  126. data/lib/vagabond/cookbooks/vagabond/recipes/default.rb +0 -132
  127. data/lib/vagabond/cookbooks/vagabond/recipes/zero.rb +0 -9
  128. data/lib/vagabond/helpers/cheffile_loader.rb +0 -20
  129. data/vagabond-0.2.6.gem +0 -0
@@ -1,3 +1,4 @@
1
+ #encoding: utf-8
1
2
  require 'thor'
2
3
  require 'chef'
3
4
  require 'kitchen'
@@ -5,7 +6,7 @@ require 'kitchen/busser'
5
6
  require 'kitchen/loader/yaml'
6
7
  require 'vagabond/monkey/kitchen_config'
7
8
 
8
- %w(constants errors helpers vagabondfile vagabond server helpers/cheffile_loader actions/status).each do |dep|
9
+ %w(constants errors helpers vagabondfile vagabond server actions/status actions/ssh).each do |dep|
9
10
  require "vagabond/#{dep}"
10
11
  end
11
12
 
@@ -15,6 +16,7 @@ module Vagabond
15
16
  include Thor::Actions
16
17
  include Helpers
17
18
  include Actions::Status
19
+ include Actions::SSH
18
20
 
19
21
  class << self
20
22
  def basename
@@ -24,7 +26,11 @@ module Vagabond
24
26
 
25
27
  self.class_exec(&Vagabond::CLI_OPTIONS)
26
28
 
27
- attr_reader :kitchen
29
+ class_option(:isolate,
30
+ :type => :boolean,
31
+ :desc => 'Isolate cookbook from parent repository'
32
+ )
33
+
28
34
  attr_reader :platform_map
29
35
  attr_reader :vagabondfile
30
36
  attr_reader :ui
@@ -45,13 +51,17 @@ module Vagabond
45
51
  :type => :string,
46
52
  :desc => 'Specify suite to destroy'
47
53
  )
48
- def teardown(cookbook)
54
+ def teardown(cookbook=nil)
55
+ setup(cookbook, :teardown)
49
56
  ui.info "#{ui.color('Vagabond:', :bold)} - Kitchen teardown for cookbook #{ui.color(name, :red)}"
50
- plats = [platform || options[:platform] || platform_map.keys].flatten
57
+ plats = [options[:platform] || platform_map.keys].flatten
51
58
  plats.each do |plat|
52
59
  validate_platform!(plat)
53
60
  ui.info ui.color(" -> Tearing down platform: #{plat}", :red)
54
- vagabond_instance(:destroy, plat).send(:execute)
61
+ kitchen.suites.map(&:name).each do |suite|
62
+ inst = vagabond_instance(:destroy, plat, :suite_name => suite)
63
+ inst.destroy
64
+ end
55
65
  ui.info ui.color(" -> Teardown of platform: #{plat} - COMPLETE!", :red)
56
66
  end
57
67
  end
@@ -79,6 +89,11 @@ module Vagabond
79
89
  :type => :string,
80
90
  :desc => 'Specify suites to test [suite1,suite2,...]'
81
91
  )
92
+ method_option(:force_berkshelf,
93
+ :type => :boolean,
94
+ :default => false,
95
+ :desc => 'Force use of Berkshelf if Cheffile is also provided'
96
+ )
82
97
  def test(*args)
83
98
  cookbook = args.first
84
99
  setup(cookbook, :test)
@@ -92,14 +107,9 @@ module Vagabond
92
107
  ui.fatal "Requested cluster is not defined: #{options[:cluster]}"
93
108
  raise VagabondError::ClusterInvalid.new(cluster_name)
94
109
  end
95
- serv = Server.new
96
- if(@solo && serv.vagabondfile[:local_chef_server].empty?)
97
- serv.vagabondfile[:local_chef_server].update(:enabled => true, :zero => true)
98
- end
99
- internal_config.make_knife_config_if_required(:force)
100
- serv.options = options.update(:auto_upload => false)
101
- serv.send(:do_create)
102
- load_cookbooks(:upload)
110
+
111
+ setup_server_if_needed
112
+
103
113
  suites = kitchen.clusters[cluster_name]
104
114
  platforms.each do |platform|
105
115
  begin
@@ -109,7 +119,7 @@ module Vagabond
109
119
  @results[platform] << {
110
120
  :suite_name => suite_name,
111
121
  :result => false
112
- }
122
+ }
113
123
  raise VagabondError::HostProvisionFailed.new("#{platform}[#{suite_name}]")
114
124
  end
115
125
  end
@@ -127,7 +137,8 @@ module Vagabond
127
137
  end
128
138
  end
129
139
  end
130
- serv.destroy
140
+
141
+ destroy_server_if_needed
131
142
  else
132
143
  load_cookbooks
133
144
  suites = options[:suites] ? options[:suites].split(',') : kitchen.suites.map(&:name)
@@ -135,12 +146,15 @@ module Vagabond
135
146
  platforms.each do |platform|
136
147
  suites.each do |suite_name|
137
148
  runner = lambda do
138
- provision_node(platform, suite_name)
139
- @results[platform] << {
140
- :suite_name => suite_name,
141
- :result => test_node(platform, suite_name)
142
- }
143
- destroy_node(platform, suite_name)
149
+ begin
150
+ provision_node(platform, suite_name)
151
+ @results[platform] << {
152
+ :suite_name => suite_name,
153
+ :result => test_node(platform, suite_name)
154
+ }
155
+ ensure
156
+ destroy_node(platform, suite_name)
157
+ end
144
158
  end
145
159
  if(options[:parallel])
146
160
  runners << Thread.new{ runner.call }
@@ -162,7 +176,9 @@ module Vagabond
162
176
  @results.each do |platform, infos|
163
177
  ui.info " Platform: #{ui.color(platform, :blue, :bold)}"
164
178
  infos.each do |res|
165
- ui.info " Suite: #{res[:suite_name]} -> #{res[:result] ? ui.color('SUCCESS!', :green) : ui.color('FAILED!', :red)}"
179
+ res_out = res[:result] ? ui.color('SUCCESS!', :green) : ui.color('FAILED!', :red)
180
+ res_out = ui.color('No tests', :blue) if res[:result] == :no_tests
181
+ ui.info " Suite: #{res[:suite_name]} -> #{res_out}"
166
182
  end
167
183
  end
168
184
  raise VagabondError::KitchenTestFailed.new(@results.values.flatten.map{|res| res[:suite_name] unless res[:result]}.compact)
@@ -176,6 +192,9 @@ module Vagabond
176
192
 
177
193
  protected
178
194
 
195
+ def validate!
196
+ end
197
+
179
198
  def mappings_key
180
199
  :test_mappings
181
200
  end
@@ -184,8 +203,9 @@ module Vagabond
184
203
  run_list = generate_runlist(platform, suite_name)
185
204
  v_inst = vagabond_instance(:up, platform, :suite_name => suite_name, :run_list => run_list)
186
205
  v_inst.options[:auto_provision] = true
187
- raise "ERROR! No local chef!" unless v_inst.options[:knife_opts]
188
- v_inst.send(:execute)
206
+ v_inst.config[:no_lazy_load] = true
207
+ v_inst._create
208
+ v_inst._provision
189
209
  end
190
210
 
191
211
  # TODO: Handle failed provision!
@@ -193,7 +213,7 @@ module Vagabond
193
213
  run_list = generate_runlist(platform, suite_name)
194
214
  ui.info ui.color(" -> Provisioning suite #{suite_name} on platform: #{platform}", :cyan)
195
215
  v_inst = vagabond_instance(:create, platform, :suite_name => suite_name)
196
- v_inst.send(:execute)
216
+ v_inst.create(v_inst.name)
197
217
  directory = configure_for(v_inst.name, platform, suite_name, run_list, :dna, :cookbooks)
198
218
  v_inst.send(:provision_solo, directory)
199
219
  end
@@ -201,29 +221,39 @@ module Vagabond
201
221
  def test_node(platform, suite_name)
202
222
  v_inst = vagabond_instance(:create, platform, :suite_name => suite_name)
203
223
  busser = bus_node(v_inst, suite_name)
204
- ui.info "#{ui.color('Kitchen:', :bold)} Running tests..."
205
- cmd = busser.run_cmd
206
- res = cmd.to_s.empty? ? true : v_inst.send(:direct_container_command, cmd, :live_stream => STDOUT)
207
- ui.info "\n -> #{ui.color('Testing', :bold, :cyan)} #{name} suite #{suite_name} on platform #{platform}: #{res ? ui.color('SUCCESS!', :green, :bold) : ui.color('FAILED', :red)}"
208
- res
224
+ if(busser)
225
+ ui.info "#{ui.color('Kitchen:', :bold)} Running tests..."
226
+ cmd = busser.run_cmd
227
+ res = cmd.to_s.empty? ? true : v_inst.send(:direct_container_command, cmd, :live_stream => STDOUT)
228
+ ui.info "\n -> #{ui.color('Testing', :bold, :cyan)} #{name} suite #{suite_name} on platform #{platform}: #{res ? ui.color('SUCCESS!', :green, :bold) : ui.color('FAILED', :red)}"
229
+ res
230
+ else
231
+ ui.info "#{ui.color('Kitchen:', :bold)} No tests found."
232
+ :no_tests
233
+ end
209
234
  end
210
235
 
211
236
  def destroy_node(platform, suite_name)
212
237
  if(options[:teardown])
213
238
  v_inst = vagabond_instance(:destroy, platform, :suite_name => suite_name)
214
- v_inst.send(:execute)
239
+ v_inst.destroy(:no_setup)
215
240
  end
216
241
  end
217
242
 
218
- def setup(name, action)
219
- @solo = name.to_s.strip.empty?
220
- @options = options.dup
221
- @vagabondfile = Vagabondfile.new(options[:vagabond_file], :allow_missing)
222
- base_setup
223
- setup_ui
224
- @internal_config = InternalConfiguration.new(@vagabondfile, ui, options)
243
+ def setup(name, action, *args)
244
+ @solo = name.to_s.strip.empty? || options[:isolate]
245
+ @options = Mash.new(@options.dup)
246
+ vfile = options[:isolate] ? File.join(Dir.pwd, 'Vagabondfile') : options[:vagabond_file]
247
+ @vagabondfile = Vagabondfile.new(vfile, :allow_missing)
225
248
  @name = name || action == :status ? name : discover_name
226
- load_kitchen_yml(@name) unless action == :status
249
+ if(options[:platform])
250
+ bases = [platform_map[options[:platform]][:template]]
251
+ elsif(args.include?(:no_host_provision))
252
+ bases = []
253
+ else
254
+ bases = platform_map.values.collect{|plat| plat[:template]}
255
+ end
256
+ base_setup(:config => {:force_bases => bases})
227
257
  @action = action
228
258
  end
229
259
 
@@ -257,7 +287,7 @@ module Vagabond
257
287
 
258
288
  def write_solo_config(dir)
259
289
  File.open(File.join(dir, 'solo.rb'), 'w') do |file|
260
- file.write("cookbook_path '#{File.join(vagabondfile.store_directory, 'cookbooks')}'\n")
290
+ file.write("cookbook_path '#{File.join(vagabondfile.build_private_store, 'cookbooks')}'\n")
261
291
  end
262
292
  dir
263
293
  end
@@ -302,21 +332,26 @@ module Vagabond
302
332
  end
303
333
 
304
334
  def load_cookbooks(*args)
305
- if(File.exists?(File.join(vagabondfile.directory, 'Berksfile')))
306
- uploader = berks_vendor(args.include?(:upload))
307
- else
335
+ if(File.exists?(File.join(vagabondfile.directory, 'Cheffile')) && !options[:force_berkshelf])
308
336
  uploader = librarian_vendor(args.include?(:upload))
337
+ else
338
+ uploader = berks_vendor(args.include?(:upload))
309
339
  end
310
340
  uploader
311
341
  end
312
342
 
313
343
  def berks_vendor(upload=false)
314
344
  ui.info 'Cookbooks being vendored via berks'
345
+ if(vagabondfile[:local_chef_server][:berkshelf].is_a?(Hash))
346
+ berks_opts = vagabondfile[:local_chef_server][:berkshelf][:options]
347
+ berks_path = vagabondfile[:local_chef_server][:berkshelf][:path]
348
+ end
315
349
  berk_uploader = Uploader::Berkshelf.new(
316
- vagabondfile.generate_store_path, options.merge(
350
+ vagabondfile, vagabondfile.build_private_store, options.merge(
317
351
  :ui => ui,
318
- :berksfile => File.join(vagabondfile.directory, 'Berksfile'),
319
- :chef_server_url => options[:knife_opts].to_s.split(' ').last
352
+ :berksfile => File.join(vagabondfile.directory, berks_path || 'Berksfile'),
353
+ :chef_server_url => options[:knife_opts].to_s.split(' ').last,
354
+ :berks_opts => berks_opts
320
355
  )
321
356
  )
322
357
  upload ? berk_uploader.upload : berk_uploader.prepare
@@ -326,12 +361,13 @@ module Vagabond
326
361
  def librarian_vendor(upload=false)
327
362
  ui.info 'Cookbooks being vendored with librarian'
328
363
  unless(File.exists?(cheffile = File.join(vagabondfile.directory, 'Cheffile')))
329
- File.open(cheffile = File.join(vagabondfile.generate_store_path, 'Cheffile'), 'w') do |file|
364
+ ui.warn 'Writing custom Cheffile to provide any required dependency resolution'
365
+ File.open(cheffile = File.join(vagabondfile.build_private_store, 'Cheffile'), 'w') do |file|
330
366
  file.write custom_cheffile
331
367
  end
332
368
  end
333
369
  librarian_uploader = Uploader::Librarian.new(
334
- vagabondfile.generate_store_path,
370
+ vagabondfile, vagabondfile.build_private_store,
335
371
  options.merge(
336
372
  :ui => ui,
337
373
  :cheffile => cheffile
@@ -343,18 +379,20 @@ module Vagabond
343
379
 
344
380
  def bus_node(v_inst, suite_name)
345
381
  test_path = options[:cluster] ? 'test/cluster' : 'test/integration'
346
- unless(::Kitchen::Busser::DEFAULT_TEST_ROOT == c_path = File.join(cookbook_path, test_path))
347
- ::Kitchen::Busser.send(:remove_const, :DEFAULT_TEST_ROOT)
348
- ::Kitchen::Busser.const_set(:DEFAULT_TEST_ROOT, c_path)
349
- end
350
- busser = ::Kitchen::Busser.new(suite_name)
351
- ui.info "#{ui.color('Kitchen:', :bold)} Setting up..."
352
- %w(setup_cmd sync_cmd).each do |cmd|
353
- com = busser.send(cmd)
354
- next if com.to_s.empty?
355
- v_inst.send(:direct_container_command, com)
382
+ if(File.directory?(c_path = File.join(cookbook_path, test_path)))
383
+ unless(::Kitchen::Busser::DEFAULT_TEST_ROOT == c_path)
384
+ ::Kitchen::Busser.send(:remove_const, :DEFAULT_TEST_ROOT)
385
+ ::Kitchen::Busser.const_set(:DEFAULT_TEST_ROOT, c_path)
386
+ end
387
+ busser = ::Kitchen::Busser.new(suite_name)
388
+ ui.info "#{ui.color('Kitchen:', :bold)} Setting up..."
389
+ %w(setup_cmd sync_cmd).each do |cmd|
390
+ com = busser.send(cmd)
391
+ next if com.to_s.empty?
392
+ v_inst.send(:direct_container_command, com)
393
+ end
394
+ busser
356
395
  end
357
- busser
358
396
  end
359
397
 
360
398
  def vagabond_instance(action, platform, args={})
@@ -368,7 +406,6 @@ module Vagabond
368
406
  :ui => ui
369
407
  )
370
408
  v.vagabondfile = vagabondfile
371
- v.vagabondfile.generate_store_path
372
409
  v.internal_config.force_bases = platform_map[platform][:template]
373
410
  v.internal_config.ensure_state
374
411
  v.mappings_key = :test_mappings
@@ -382,6 +419,13 @@ module Vagabond
382
419
  v
383
420
  end
384
421
 
422
+ def kitchen
423
+ unless(@kitchen)
424
+ load_kitchen_yml(name)
425
+ end
426
+ @kitchen
427
+ end
428
+
385
429
  def load_kitchen_yml(name)
386
430
  @kitchen = ::Kitchen::Config.new(
387
431
  :kitchen_root => cookbook_path,
@@ -396,6 +440,9 @@ module Vagabond
396
440
  @platform_map ||= Mash[
397
441
  *(
398
442
  kitchen.platforms.map do |plat|
443
+ if(defined?(::Kitchen::Platform::Cheflike))
444
+ plat.extend(::Kitchen::Platform::Cheflike)
445
+ end
399
446
  [
400
447
  plat.name, Mash.new(
401
448
  :template => plat.name.gsub('.', '').gsub('-', '_'),
@@ -416,6 +463,9 @@ module Vagabond
416
463
  kitchen_suite = kitchen.suites.detect do |k_s|
417
464
  k_s.name == suite
418
465
  end
466
+ if(defined?(::Kitchen::Suite::Cheflike))
467
+ kitchen_suite.extend(::Kitchen::Suite::Cheflike)
468
+ end
419
469
  if(kitchen_suite && kitchen_suite.run_list)
420
470
  r |= kitchen_suite.run_list
421
471
  end
@@ -1,5 +1,9 @@
1
+ #encoding: utf-8
1
2
  require 'thor'
2
- require File.join(File.dirname(__FILE__), 'cookbooks/lxc/libraries/lxc.rb')
3
+ require 'elecksee/lxc'
4
+
5
+ #TODO: Remove this when elecksee gets updated
6
+ require 'chef/log'
3
7
 
4
8
  %w(helpers vagabondfile internal_configuration).each do |dep|
5
9
  require "vagabond/#{dep}"
@@ -1,3 +1,4 @@
1
+ #encoding: utf-8
1
2
  module Vagabond
2
3
  class Layout
3
4
 
@@ -1,3 +1,4 @@
1
+ #encoding: utf-8
1
2
  require 'kitchen/config'
2
3
 
3
4
  module Vagabond
@@ -0,0 +1,25 @@
1
+ require 'chef/mash'
2
+
3
+ class NotifyMash < BasicObject
4
+
5
+ def initialize(*args)
6
+ @notifications = []
7
+ @mash = ::Mash.new(*args)
8
+ end
9
+
10
+ def add_notification(&block)
11
+ @notifications << block
12
+ end
13
+
14
+ def method_missing(sym, *args)
15
+ start_state = @mash.hash
16
+ result = @mash.send(sym, *args)
17
+ if(start_state != @mash.hash)
18
+ @notifications.each do |notify|
19
+ notify.call(self)
20
+ end
21
+ end
22
+ result
23
+ end
24
+
25
+ end
@@ -1,9 +1,10 @@
1
+ #encoding: utf-8
1
2
  require 'vagabond/vagabond'
2
3
  require 'mixlib/cli'
3
4
  require 'digest/md5'
4
5
 
5
6
  module Vagabond
6
-
7
+
7
8
  class Server < Vagabond
8
9
 
9
10
  class << self
@@ -13,7 +14,7 @@ module Vagabond
13
14
  end
14
15
 
15
16
  self.class_exec(false, &Vagabond::COMMANDS)
16
-
17
+
17
18
  def initialize(*args)
18
19
  super
19
20
  @name = 'server'
@@ -50,11 +51,12 @@ module Vagabond
50
51
  def upload_roles
51
52
  am_uploading('roles') do
52
53
  if(File.directory?(File.join(base_dir, 'roles')))
53
- com = "knife role from file #{File.join(base_dir, 'roles/*')} #{options[:knife_opts]}"
54
- debug(com)
55
- cmd = Mixlib::ShellOut.new(com, :live_stream => options[:debug])
56
- cmd.run_command
57
- cmd.error!
54
+ %w(rb json js).each do |ext|
55
+ next if Dir.glob(File.join(base_dir, "roles", "*.#{ext}")).size == 0
56
+ cmd = knife_command("role from file #{File.join(base_dir, "roles/*.#{ext}")}")
57
+ cmd.run_command
58
+ cmd.error!
59
+ end
58
60
  end
59
61
  end
60
62
  end
@@ -64,13 +66,12 @@ module Vagabond
64
66
  am_uploading('data bags') do
65
67
  if(File.directory?(File.join(base_dir, 'data_bags')))
66
68
  Dir.glob(File.join(base_dir, "data_bags/*")).each do |b|
67
- next if %w(. ..).include?(b)
69
+ next if %w(. ..).include?(b) || !File.directory?(b)
68
70
  coms = [
69
- "knife data bag create #{File.basename(b)} #{options[:knife_opts]}",
70
- "knife data bag from file #{File.basename(b)} #{options[:knife_opts]} --all"
71
+ "data bag create #{File.basename(b)}",
72
+ "data bag from file #{File.basename(b)} --all"
71
73
  ].each do |com|
72
- debug(com)
73
- cmd = Mixlib::ShellOut.new(com, :live_stream => options[:debug])
74
+ cmd = knife_command(com)
74
75
  cmd.run_command
75
76
  cmd.error!
76
77
  end
@@ -83,11 +84,12 @@ module Vagabond
83
84
  def upload_environments
84
85
  am_uploading('environments') do
85
86
  if(File.directory?(File.join(base_dir, 'environments')))
86
- com = "knife environment from file #{File.join(base_dir, 'environments/*')} #{options[:knife_opts]}"
87
- debug(com)
88
- cmd = Mixlib::ShellOut.new(com, :live_stream => options[:debug])
89
- cmd.run_command
90
- cmd.error!
87
+ %w(rb json js).each do |ext|
88
+ next if Dir.glob(File.join(base_dir, "environments", "*.#{ext}")).size == 0
89
+ cmd = knife_command("environment from file #{File.join(base_dir, "environments/*.#{ext}")}")
90
+ cmd.run_command
91
+ cmd.error!
92
+ end
91
93
  end
92
94
  end
93
95
  end
@@ -100,7 +102,13 @@ module Vagabond
100
102
  elsif(vagabondfile[:local_chef_server][:berkshelf])
101
103
  berks_upload
102
104
  else
103
- raw_upload
105
+ if(File.exists?(File.join(vagabondfile.directory, 'Cheffile')))
106
+ librarian_upload
107
+ elsif(File.exists?(File.join(vagabondfile.directory, 'Berksfile')))
108
+ berks_upload
109
+ else
110
+ raw_upload
111
+ end
104
112
  end
105
113
  end
106
114
  end
@@ -113,58 +121,82 @@ module Vagabond
113
121
  def setup(action, name=nil, *args)
114
122
  super(action, 'server', *args)
115
123
  end
116
-
124
+
117
125
  def am_uploading(thing)
118
126
  ui.info "#{ui.color('Local chef server:', :bold)} Uploading #{ui.color(thing, :green)}"
119
127
  yield
120
128
  ui.info ui.color(" -> UPLOADED #{thing.upcase}", :green)
121
129
  end
122
-
123
- def do_create
124
- @lxc = Lxc.new(generated_name)
125
- unless(@lxc.exists?)
126
- com = "#{options[:sudo]}lxc-clone -n #{generated_name} -o #{@base_template}"
127
- debug(com)
128
- cmd = Mixlib::ShellOut.new(com, :live_stream => options[:debug])
129
- cmd.run_command
130
- cmd.error!
130
+
131
+ def server_base
132
+ if(vagabondfile[:local_chef_server][:zero] || options[:force_zero])
133
+ base = 'vb-zero-server'
131
134
  else
132
- ui.warn 'Found server instance not if configuration. Adding and moving on.'
135
+ version = vagabondfile[:local_chef_server][:version]
136
+ unless(version)
137
+ # TODO: Bad magic. Make configurable!
138
+ matches = Dir.new('/var/lib/lxc').find_all{|i| i.match(/^vb-server-\d+_\d+_\d+$/)}
139
+ matches.map!{|i| i.sub('vb-server-', '').gsub('_', '.')}
140
+ version = matches.sort{|x,y| Gem::Version.new(x) <=> Gem::Version.new(y)}.last
141
+ end
142
+ base = "vb-server-#{version.gsub('.', '_')}"
143
+ unless(Lxc.new(base).exists?)
144
+ raise VagabondError::ErchefBaseMissing.new("Required base container is missing: #{base}")
145
+ end
133
146
  end
134
- @internal_config[:mappings][name] = generated_name
135
- @internal_config.save
136
- ui.info ui.color(' -> Chef Server container created!', :cyan)
137
- lxc.start
138
- ui.info ui.color(' -> Chef Server CREATED!', :green)
139
- do_provision
140
- auto_upload if vagabondfile[:local_chef_server][:auto_upload]
147
+ base
148
+ end
149
+
150
+ def do_create
151
+ config = Mash.new
152
+ # TODO: Pull custom IP option if provided
153
+ config[:daemon] = true
154
+ config[:original] = server_base
155
+
156
+ ephemeral = Lxc::Ephemeral.new(config)
157
+ e_name = ephemeral.name
158
+ internal_config[mappings_key][name] = e_name
159
+ ephemeral.start!(:fork)
160
+ @lxc = Lxc.new(e_name)
161
+ @lxc.wait_for_state(:running)
141
162
  end
142
163
 
143
164
  def do_provision
144
- if(vagabondfile[:local_chef_server][:zero])
165
+ if(vagabondfile[:local_chef_server][:zero] || options[:force_zero])
145
166
  ui.info ui.color(' -> Bootstrapping chef-zero...', :cyan)
146
167
  tem_file = File.expand_path(File.join(File.dirname(__FILE__), 'bootstraps/server-zero.erb'))
147
- options[:knife_opts] = " --server-url http://#{lxc.container_ip(20, true)}"
168
+ knife_config :server_url => "http://#{lxc.container_ip(20, true)}"
148
169
  else
149
170
  ui.info ui.color(' -> Bootstrapping erchef...', :cyan)
150
171
  tem_file = File.expand_path(File.join(File.dirname(__FILE__), 'bootstraps/server.erb'))
151
- options[:knife_opts] = " --server-url https://#{lxc.container_ip(20, true)}"
172
+ knife_config :server_url => "https://#{lxc.container_ip(20, true)}"
152
173
  end
153
- com = "#{options[:sudo]}knife bootstrap #{lxc.container_ip(10, true)} --template-file #{tem_file} -i /opt/hw-lxc-config/id_rsa"
154
- cmd = Mixlib::ShellOut.new(com, :live_stream => options[:debug], :timeout => 1200)
155
- debug(com)
174
+ # Scrub before bootstrap
175
+ direct_container_command('rm -rf /var/chef-host/cookbooks')
176
+ # And bootstrap
177
+ cmd = knife_command(
178
+ "bootstrap #{lxc.container_ip(10, true)} --sync-directory " <<
179
+ "\"#{internal_config.cookbook_path}:/var/chef-host/cookbooks\" --template-file " <<
180
+ "#{tem_file} -i #{Settings[:ssh_key]}"
181
+ )
156
182
  cmd.run_command
157
183
  cmd.error!
184
+ ui.info ui.color(' -> COMPLETE', :green)
185
+ auto_upload if vagabondfile[:local_chef_server][:auto_upload]
158
186
  end
159
-
187
+
160
188
  def berks_upload
161
189
  ui.info 'Cookbooks being uploaded via berks'
190
+ if(vagabondfile[:local_chef_server][:berkshelf].is_a?(Hash))
191
+ berks_opts = vagabondfile[:local_chef_server][:berkshelf][:options]
192
+ berks_path = vagabondfile[:local_chef_server][:berkshelf][:path]
193
+ end
162
194
  berk_uploader = Uploader::Berkshelf.new(
163
- vagabondfile.directory, options.merge(
195
+ vagabondfile, vagabondfile.build_private_store, options.merge(
164
196
  :ui => ui,
165
- :berksfile => File.join(vagabondfile.directory, vagabondfile[:local_chef_server][:berkshelf][:path] || 'Berksfile'),
197
+ :berksfile => File.join(vagabondfile.directory, berks_path || 'Berksfile'),
166
198
  :chef_server_url => options[:knife_opts].to_s.split(' ').last,
167
- :berks_opts => vagabondfile[:local_chef_server][:berkshelf][:options]
199
+ :berks_opts => berks_opts
168
200
  )
169
201
  )
170
202
  berk_uploader.upload
@@ -173,17 +205,17 @@ module Vagabond
173
205
  def librarian_upload
174
206
  ui.info 'Cookbooks being uploaded with librarian'
175
207
  librarian_uploader = Uploader::Librarian.new(
176
- vagabondfile.generate_store_path, options.merge(
208
+ vagabondfile, vagabondfile.build_private_store, options.merge(
177
209
  :ui => ui,
178
210
  :cheffile => File.join(vagabondfile.directory, 'Cheffile')
179
211
  )
180
212
  )
181
213
  librarian_uploader.upload
182
214
  end
183
-
215
+
184
216
  def raw_upload
185
217
  ui.info 'Cookbooks being uploaded via knife'
186
- knife_uploader = Uploader::Knife.new(vagabondfile.directory, options.merge(:ui => ui))
218
+ knife_uploader = Uploader::Knife.new(vagabondfile, vagabondfile.directory, options.merge(:ui => ui))
187
219
  knife_uploader.upload
188
220
  end
189
221