cucumber-chef 2.1.0.rc.15 → 3.0.0.rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,15 +10,7 @@ Cucumber::Chef.boot(tag)
10
10
 
11
11
  ui = ZTK::UI.new(:logger => Cucumber::Chef.logger)
12
12
  if (test_lab = Cucumber::Chef::TestLab.new(ui)) && test_lab.alive?
13
-
14
- knife_rb = Cucumber::Chef.knife_rb
15
- if File.exists?(knife_rb)
16
- test_lab.knife_cli([ARGV], :replace_current_process => true)
17
- else
18
- puts("Could not find your Cucumber-Chef 'knife.rb'. Did you setup your test lab?")
19
- exit(2)
20
- end
21
-
13
+ test_lab.knife_cli([ARGV], :replace_current_process => true)
22
14
  else
23
15
  puts("No running cucumber-chef test labs to connect to!")
24
16
  exit(1)
@@ -296,6 +296,20 @@ class CucumberChef < Thor
296
296
  fatal(e)
297
297
  end
298
298
 
299
+ desc "genmac", "Generate a private MAC address"
300
+ def genmac
301
+ boot
302
+
303
+ puts Cucumber::Chef::Containers.generate_mac
304
+ end
305
+
306
+ desc "genip", "Generate a private IP address"
307
+ def genip
308
+ boot
309
+
310
+ puts Cucumber::Chef::Containers.generate_ip
311
+ end
312
+
299
313
  ################################################################################
300
314
  # STATUS
301
315
  ################################################################################
@@ -311,27 +325,24 @@ class CucumberChef < Thor
311
325
  if @options.containers?
312
326
  if test_lab.alive?
313
327
 
314
- test_lab.containers.load
315
-
316
328
  if test_lab.containers.count > 0
317
- headers = [:name, :alive, :arch, :distro, :ip, :mac, :"chef version", :persist]
318
- results = ZTK::Report.new.spreadsheet(test_lab.containers.to_a, headers) do |name, detail|
329
+ headers = [:name, :alive, :distro, :ip, :mac, :"chef version", :persist]
330
+ results = ZTK::Report.new.spreadsheet(Cucumber::Chef::Container.all, headers) do |container|
319
331
  chef_version = "N/A"
320
- alive = (test_lab.bootstrap_ssh(:ignore_exit_status => true).exec(%Q{ping -n -c 1 -W 1 #{detail[:ip]}}, :silence => true).exit_code == 0)
332
+ alive = (test_lab.bootstrap_ssh(:ignore_exit_status => true).exec(%Q{ping -n -c 1 -W 1 #{container.ip}}, :silence => true).exit_code == 0)
321
333
  if alive
322
- chef_version = test_lab.proxy_ssh(name, :ignore_exit_status => true).exec(%Q{/usr/bin/env chef-client -v}, :silence => true).output.chomp
334
+ chef_version = test_lab.proxy_ssh(container.name, :ignore_exit_status => true).exec(%Q{/usr/bin/env chef-client -v}, :silence => true).output.chomp
323
335
  end
324
336
 
325
337
  OpenStruct.new(
326
- :name => name,
327
- :ip => detail[:ip],
328
- :mac => detail[:mac],
329
- :distro => detail[:distro],
330
- :arch => detail[:arch],
338
+ :name => container.name,
339
+ :ip => container.ip,
340
+ :mac => container.mac,
341
+ :distro => container.distro,
331
342
  :alive => alive,
332
343
  :"chef version" => chef_version,
333
- :persist => detail[:persist],
334
- :chef_attributes => detail[:chef_client]
344
+ :persist => container.persist,
345
+ :chef_attributes => container.chef_client
335
346
  )
336
347
  end
337
348
 
@@ -502,10 +513,11 @@ class CucumberChef < Thor
502
513
  "log_file" => Cucumber::Chef.log_file,
503
514
  "artifacts_dir" => Cucumber::Chef.artifacts_dir,
504
515
  "config_rb" => Cucumber::Chef.config_rb,
505
- "containers_bin" => Cucumber::Chef.containers_bin,
506
- "knife_rb" => Cucumber::Chef.knife_rb,
516
+ "labfile" => Cucumber::Chef.labfile,
507
517
  "chef_repo" => Cucumber::Chef.chef_repo,
508
518
  "bootstrap_identity" => Cucumber::Chef.bootstrap_identity,
519
+ "chef_user" => Cucumber::Chef.chef_user,
520
+ "chef_identity" => Cucumber::Chef.chef_identity,
509
521
  "lab_user" => Cucumber::Chef.lab_user,
510
522
  "lab_user_home_dir" => Cucumber::Chef.lab_user_home_dir,
511
523
  "lab_identity" => Cucumber::Chef.lab_identity,
@@ -117,10 +117,10 @@ end
117
117
  # CHEF-SOLR / APACHE SOLR
118
118
  ################################################################################
119
119
 
120
- template "install custom solr config" do
121
- path "/var/lib/chef/solr/conf/solrconfig.xml"
122
- source "solrconfig.erb"
123
- owner "chef"
124
- group "chef"
125
- mode "0644"
126
- end
120
+ # template "install custom solr config" do
121
+ # path "/var/lib/chef/solr/conf/solrconfig.xml"
122
+ # source "solrconfig.erb"
123
+ # owner "chef"
124
+ # group "chef"
125
+ # mode "0644"
126
+ # end
@@ -34,9 +34,6 @@ Gem::Specification.new do |s|
34
34
  s.required_rubygems_version = ">= 1.3.6"
35
35
  s.licenses = ["Apache 2.0"]
36
36
 
37
- # Chef
38
- s.add_dependency("chef", ">= 0.10.0")
39
-
40
37
  # Providers
41
38
  s.add_dependency("fog", ">= 1.3.1")
42
39
 
@@ -49,7 +46,7 @@ Gem::Specification.new do |s|
49
46
  s.add_dependency("rake", ">= 0.9.2")
50
47
  s.add_dependency("thor", ">= 0.15.2")
51
48
  s.add_dependency("ubuntu_ami", ">= 0.4.0")
52
- s.add_dependency("ztk", ">= 1.0.2")
49
+ s.add_dependency("ztk", ">= 1.0.3")
53
50
 
54
51
  s.add_development_dependency("simplecov", ">= 0.6.4")
55
52
  s.add_development_dependency("pry", ">= 0")
@@ -6,54 +6,73 @@ namespace :cc do
6
6
 
7
7
  desc "Run features in a style suitable for Continuous Integration"
8
8
  task :ci do |t|
9
- pushed = false
10
- exit_codes = Array.new
11
9
 
12
- puts("Cleaning up...")
13
- system(%Q{rm -rfv artifacts})
14
- system(%Q{rm -rfv public})
15
- system(%Q{mkdir -v public})
16
- system(%Q{echo "<html><head><title>Cucumber-Chef Report</title></head><body>" | tee public/index.html})
17
- system(%Q{echo "<h2>Cucumber-Chef Report</h2><ul>" | tee -a public/index.html})
10
+ def feature_dir(dir, &block)
11
+ puts("=" * 80)
12
+ puts("feature_dir(#{dir.inspect})")
13
+ puts("=" * 80)
18
14
 
19
- puts("Generating Cucumber-Chef html reports...")
20
- Dir.glob("features/*").each do |feature_dir|
21
- found_features = false
22
- Dir.glob("#{feature_dir}/*.feature") do |feature|
23
- if found_features == false
24
- found_features = true
25
- system(%Q{echo "<li /><p>#{File.basename(feature_dir)}<ul>" | tee -a public/index.html})
26
- end
27
- filename = feature.gsub(/(\w*).feature/, '\1.html')
28
- puts("#{feature} -> public/#{filename}")
15
+ system(%Q{echo "<li /><p>#{File.basename(dir)}<ul>" | tee -a #{@index_html}})
16
+ block.call
17
+ system(%Q{echo "</p></ul>" | tee -a #{@index_html}})
18
+ end
29
19
 
30
- system(%Q{mkdir -pv #{File.dirname("public/#{filename}")}})
20
+ def run_feature(feature_file)
21
+ puts("=" * 80)
22
+ puts("run_feature(#{feature_file.inspect})")
23
+ puts("=" * 80)
31
24
 
32
- push = (pushed ? nil : %Q{PUSH="YES"})
33
- command = [push, "bundle exec cucumber", "features/support", feature, ENV['EXTRA_CUCUMBER_ARGS'], "--format html", "--out public/#{filename}"].flatten.compact.join(" ")
34
- pushed = true if !pushed
35
- puts("command=#{command.inspect}")
36
- system(command)
37
- exit_codes << $?.exitstatus
25
+ filename = feature_file.gsub(/(\w*).feature/, '\1.html')
26
+ puts("#{feature_file} -> public/#{filename}")
38
27
 
39
- passed = "<font style='font-weight: bold; color: green;'>PASSED</font>"
40
- failed = "<font style='font-weight: bold; color: red;'>FAILED</font>"
41
- status = ((exit_codes[-1] == 0) ? passed : failed)
28
+ system(%Q{mkdir -pv #{File.dirname("public/#{filename}")}})
42
29
 
43
- system(%Q{echo "<li /><a href='#{filename}'>#{File.basename(filename.gsub('.html', ''))}</a> (#{status})" | tee -a public/index.html})
44
- end
30
+ push = (@pushed ? nil : %Q{SETUP="YES"})
31
+ output_file = File.join(@output_dir, filename)
32
+ command = [push, "bundle exec cucumber", "features/support", feature_file, ENV['EXTRA_CUCUMBER_ARGS'], "--format html", "--out", output_file].flatten.compact.join(" ")
33
+ @pushed = true if !@pushed
34
+ puts("command=#{command.inspect}")
35
+ system(command)
36
+ @exit_codes << $?.exitstatus
45
37
 
46
- if found_features
47
- system(%Q{echo "</p></ul>" | tee -a public/index.html})
48
- end
38
+ passed = "<font style='font-weight: bold; color: green;'>PASSED</font>"
39
+ failed = "<font style='font-weight: bold; color: red;'>FAILED</font>"
40
+ status = ((@exit_codes[-1] == 0) ? passed : failed)
41
+
42
+ system(%Q{echo "<li /><a href='#{filename}'>#{File.basename(filename.gsub('.html', ''))}</a> (#{status})" | tee -a #{@index_html}})
49
43
  end
50
44
 
51
- system(%Q{echo "</ul></body></html>" | tee -a public/index.html})
45
+ @output_dir = File.join(Dir.pwd, "public")
46
+ @index_html = File.join(@output_dir, "index.html")
47
+ @pushed = false
48
+ @exit_codes = Array.new
52
49
 
53
- system(%Q{/bin/bash -c '[[ -d $CUCUMBER_CHEF_HOME/aws/artifacts ]] && mv -v $CUCUMBER_CHEF_HOME/aws/artifacts .'})
50
+ puts("Cleaning up...")
51
+ system(%Q{rm -rfv .cucumber-chef/aws/artifacts})
52
+ system(%Q{rm -rfv public})
53
+ system(%Q{mkdir -v public})
54
+
55
+ puts("Generating Cucumber-Chef html reports...")
56
+
57
+ system(%Q{echo "<html><head><title>Cucumber-Chef Report</title></head><body>" | tee public/index.html})
58
+ system(%Q{echo "<h2>Cucumber-Chef Report</h2><ul>" | tee -a public/index.html})
59
+ Dir.glob("features/*").each do |fdir|
60
+ if File.directory?(fdir)
61
+ if (ffiles = Dir.glob("#{fdir}/*.feature")).count > 0
62
+ feature_dir(fdir) do
63
+ ffiles.each do |ffile|
64
+ run_feature(ffile)
65
+ end
66
+ end
67
+ end
68
+ else
69
+ run_feature(fdir)
70
+ end
71
+ end
72
+ system(%Q{echo "</ul></body></html>" | tee -a public/index.html})
54
73
 
55
74
  # If we had a failure be sure to surface it
56
- exit_code = (exit_codes.any?{ |ec| ec != 0 } ? 1 : 0)
75
+ exit_code = (@exit_codes.any?{ |ec| ec != 0 } ? 1 : 0)
57
76
  exit(exit_code)
58
77
  end
59
78
 
@@ -23,9 +23,6 @@ require 'benchmark'
23
23
 
24
24
  ################################################################################
25
25
 
26
- require 'chef'
27
- require 'chef/cookbook_uploader'
28
-
29
26
  require 'fog'
30
27
 
31
28
  require 'json'
@@ -44,7 +41,10 @@ module Cucumber
44
41
 
45
42
  autoload :Client, 'cucumber/chef/client'
46
43
  autoload :Config, 'cucumber/chef/config'
44
+ autoload :Container, 'cucumber/chef/container'
47
45
  autoload :Containers, 'cucumber/chef/containers'
46
+ autoload :Ecosystem, 'cucumber/chef/ecosystem'
47
+ autoload :Labfile, 'cucumber/chef/labfile'
48
48
  autoload :Provider, 'cucumber/chef/provider'
49
49
  autoload :Provisioner, 'cucumber/chef/provisioner'
50
50
  autoload :TestLab, 'cucumber/chef/test_lab'
@@ -0,0 +1,44 @@
1
+ ################################################################################
2
+ #
3
+ # Author: Stephen Nelson-Smith <stephen@atalanta-systems.com>
4
+ # Author: Zachary Patten <zachary@jovelabs.com>
5
+ # Copyright: Copyright (c) 2011-2013 Atalanta Systems Ltd
6
+ # License: Apache License, Version 2.0
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+ ################################################################################
21
+
22
+ module Cucumber
23
+ module Chef
24
+
25
+ class ContainerError < Error; end
26
+
27
+ class Container < ZTK::DSL::Base
28
+ belongs_to :ecosystem, :class_name => "Cucumber::Chef:Ecosystem"
29
+
30
+ attribute :name
31
+ attribute :ip
32
+ attribute :mac
33
+ attribute :persist
34
+ attribute :distro
35
+ attribute :release
36
+ attribute :arch
37
+ attribute :roles
38
+ attribute :chef_client
39
+ end
40
+
41
+ end
42
+ end
43
+
44
+ ################################################################################
@@ -18,6 +18,7 @@
18
18
  # limitations under the License.
19
19
  #
20
20
  ################################################################################
21
+ require 'tempfile'
21
22
 
22
23
  module Cucumber
23
24
  module Chef
@@ -25,6 +26,7 @@ module Cucumber
25
26
  class ContainersError < Error; end
26
27
 
27
28
  class Containers
29
+
28
30
  ################################################################################
29
31
 
30
32
  def initialize(ui=ZTK::UI.new, test_lab=nil)
@@ -34,104 +36,59 @@ module Cucumber
34
36
  ################################################################################
35
37
 
36
38
  def count
37
- @containers.count
38
- end
39
-
40
- def to_a
41
- @containers
42
- end
43
-
44
- ################################################################################
45
-
46
- def load
47
- @ui.logger.debug { "Reading '#{Cucumber::Chef.containers_bin}'." }
48
- @containers = ((Marshal.load(IO.read(Cucumber::Chef.containers_bin)) rescue Hash.new) || Hash.new)
49
-
50
- @ui.logger.info { "-" * 8 }
51
- @containers.each do |key, value|
52
- @ui.logger.info { "LOAD CONTAINER: #{key.inspect} => #{value.inspect}" }
53
- end
39
+ Container.count
54
40
  end
55
41
 
56
42
  ################################################################################
57
43
 
58
- def save
59
- @ui.logger.debug { "Writing '#{Cucumber::Chef.containers_bin}'." }
60
- @ui.logger.info { "-" * 8 }
61
- @containers.each do |key, value|
62
- @ui.logger.info { "SAVE CONTAINER: #{key.inspect} => #{value.inspect}" }
63
- end
64
-
65
- File.open(Cucumber::Chef.containers_bin, 'w') do |f|
66
- f.puts(Marshal.dump(@containers))
67
- end
68
- end
69
-
70
- ################################################################################
71
-
72
- def init(name)
73
- @containers[name] ||= Hash.new
74
- @containers[name][:chef_client] = nil
75
- end
76
-
77
- ################################################################################
44
+ def create(container)
45
+ # if this is a new or non-persistent container destroy it
46
+ destroy(container.name) if !container.persist
78
47
 
79
- def create(name)
80
- init(name)
48
+ container.ip ||= self.generate_ip
49
+ container.mac ||= self.generate_mac
50
+ container.persist ||= false
51
+ container.distro ||= "ubuntu"
52
+ container.release ||= "lucid"
53
+ container.arch = detect_arch(container.distro || "ubuntu")
81
54
 
82
- # if this is a new or non-persistent container destroy it
83
- destroy(name) if !@containers[name][:persist]
84
-
85
- attributes = @containers[name]
86
- @containers[name] = {
87
- :ip => generate_ip,
88
- :mac => generate_mac,
89
- :persist => true,
90
- :distro => "ubuntu",
91
- :release => "lucid",
92
- }.merge(attributes).merge(:arch => detect_arch(attributes[:distro] || "ubuntu"))
93
-
94
- if running?(name)
95
- @ui.logger.info { "Container '#{name}' is already running." }
55
+ if running?(container.name)
56
+ @ui.logger.info { "Container '#{container.name}' is already running." }
96
57
  else
97
- @ui.logger.info { "Please wait, creating container {#{name.inspect} => #{tag(name)}}." }
58
+ @ui.logger.info { "Please wait, creating container #{container.inspect}." }
98
59
  bm = ::Benchmark.realtime do
99
60
  test_lab_config_dhcpd
100
- config_network(name)
101
- _create(name, @containers[name][:distro], @containers[name][:release], @containers[name][:arch])
61
+ config_network(container)
62
+ _create(container.name, container.distro, container.release, container.arch)
102
63
  end
103
- @ui.logger.info { "Container '#{name}' creation took %0.4f seconds." % bm }
64
+ @ui.logger.info { "Container '#{container.name}' creation took %0.4f seconds." % bm }
104
65
 
105
- # bm = ::Benchmark.realtime do
106
- # ZTK::TCPSocketCheck.new(:host => @containers[name][:ip], :port => 22).wait
107
- # end
108
- # @ui.logger.info { "Container '#{name}' SSHD responded after %0.4f seconds." % bm }
66
+ bm = ::Benchmark.realtime do
67
+ ZTK::RescueRetry.try(:tries => 32) do
68
+ @test_lab.ssh.exec("host #{container.name}", :silence => true)
69
+ end
70
+ ZTK::RescueRetry.try(:tries => 32) do
71
+ @test_lab.proxy_ssh(container.name).exec("uptime", :silence => true)
72
+ end
73
+ end
74
+ @ui.logger.info { "Container '#{container.name}' SSHD responded after %0.4f seconds." % bm }
109
75
  end
110
-
111
- save
112
76
  end
113
77
 
114
78
  ################################################################################
115
79
 
116
80
  def destroy(name)
81
+ @test_lab.knife_cli("node delete #{name}", :ignore_exit_status => true)
82
+ @test_lab.knife_cli("client delete #{name}", :ignore_exit_status => true)
83
+
117
84
  if exists?(name)
118
- @test_lab.knife_cli("node delete #{name} --yes", :ignore_exit_status => true)
119
- @test_lab.knife_cli("client delete #{name} --yes", :ignore_exit_status => true)
120
85
  stop(name)
121
86
  @test_lab.bootstrap_ssh.exec("sudo lxc-destroy -n #{name}", :silence => true)
122
87
  @ui.logger.info { "Destroyed container '#{name}'." }
123
88
  test_lab_config_dhcpd
124
- @containers.delete(name)
125
- save
126
89
  end
127
90
  end
128
91
 
129
- ################################################################################
130
-
131
- def set_attributes(name, attributes={})
132
- @containers[name].merge!(attributes)
133
- end
134
-
135
92
  ################################################################################
136
93
 
137
94
  def chef_set_client_config(config={})
@@ -151,41 +108,30 @@ module Cucumber
151
108
 
152
109
  ################################################################################
153
110
 
154
- def chef_set_client_attributes(name, attributes={})
155
- @containers[name] ||= Hash.new
156
- @containers[name][:chef_client] = (@containers[name][:chef_client] || {}).merge(attributes) { |k,o,n| (k = (o + n).uniq) }
157
-
158
- @ui.logger.info { "Setting chef client attributes to '#{@containers[name][:chef_client].inspect}' for container '#{name}'." }
159
-
160
- true
161
- end
162
-
163
- ################################################################################
164
-
165
- def chef_run_client(name, *args)
166
- chef_config_client(name)
111
+ def chef_run_client(container, *args)
112
+ chef_config_client(container)
167
113
 
168
114
  @ui.logger.info { "Removing artifacts #{Cucumber::Chef::Config[:artifacts].values.collect{|z| "'#{z}'" }.join(' ')}." }
169
- (@test_lab.proxy_ssh(name).exec("/bin/rm -fv #{Cucumber::Chef::Config[:artifacts].values.join(' ')}", :silence => true) rescue nil)
115
+ (@test_lab.proxy_ssh(container.name).exec("/bin/rm -fv #{Cucumber::Chef::Config[:artifacts].values.join(' ')}", :silence => true) rescue nil)
170
116
 
171
- @ui.logger.info { "Running chef client on container '#{name}'." }
117
+ @ui.logger.info { "Running chef client on container '#{container.name}'." }
172
118
 
173
119
  arguments = {
174
- "--node-name" => name,
120
+ "--node-name" => container.name,
175
121
  "--json-attributes" => File.join("/etc", "chef", "attributes.json").to_s,
176
122
  "--log_level" => @chef_client_config[:log_level],
177
123
  "--logfile" => @chef_client_config[:log_location],
178
124
  "--server" => @chef_client_config[:chef_server_url],
179
- "--environment" => @chef_client_config[:environment]
125
+ "--environment" => (container.chef_client[:environment] || @chef_client_config[:environment])
180
126
  }.reject{ |k,v| v.nil? }.sort
181
127
 
182
128
  output = nil
183
129
  bm = ::Benchmark.realtime do
184
- output = @test_lab.proxy_ssh(name).exec(["/usr/bin/chef-client", arguments, args, "--once"].flatten.join(" "), :silence => true)
130
+ output = @test_lab.proxy_ssh(container.name).exec(["/usr/bin/chef-client", arguments, args, "--once"].flatten.join(" "), :silence => true)
185
131
  end
186
- @ui.logger.info { "Chef client run on container '#{name}' took %0.4f seconds." % bm }
132
+ @ui.logger.info { "Chef client run on container '#{container.name}' took %0.4f seconds." % bm }
187
133
 
188
- chef_client_artifacts(name)
134
+ chef_client_artifacts(container)
189
135
 
190
136
  output
191
137
  end
@@ -203,6 +149,50 @@ module Cucumber
203
149
  test_result
204
150
  end
205
151
 
152
+ ################################################################################
153
+ class << self
154
+
155
+ def generate_ip
156
+ octets = [ 192..192,
157
+ 168..168,
158
+ 0..254,
159
+ 1..254 ]
160
+ ip = Array.new
161
+ for x in 1..4 do
162
+ ip << octets[x-1].to_a[rand(octets[x-1].count)].to_s
163
+ end
164
+ ip.join(".")
165
+ end
166
+
167
+ def generate_mac
168
+ digits = [ %w(0),
169
+ %w(0),
170
+ %w(0),
171
+ %w(0),
172
+ %w(5),
173
+ %w(e),
174
+ %w(0 1 2 3 4 5 6 7 8 9 a b c d e f),
175
+ %w(0 1 2 3 4 5 6 7 8 9 a b c d e f),
176
+ %w(5 6 7 8 9 a b c d e f),
177
+ %w(3 4 5 6 7 8 9 a b c d e f),
178
+ %w(0 1 2 3 4 5 6 7 8 9 a b c d e f),
179
+ %w(0 1 2 3 4 5 6 7 8 9 a b c d e f) ]
180
+ mac = ""
181
+ for x in 1..12 do
182
+ mac += digits[x-1][rand(digits[x-1].count)]
183
+ mac += ":" if (x.modulo(2) == 0) && (x != 12)
184
+ end
185
+ mac
186
+ end
187
+
188
+ end
189
+
190
+ ################################################################################
191
+
192
+ def list
193
+ @test_lab.bootstrap_ssh.exec("sudo lxc-ls 2>&1", :silence => true).output.split("\n").uniq
194
+ end
195
+
206
196
  ################################################################################
207
197
  private
208
198
  ################################################################################
@@ -276,9 +266,9 @@ module Cucumber
276
266
 
277
267
  ################################################################################
278
268
 
279
- def chef_config_client(name)
280
- tempfile = Tempfile.new(name)
281
- client_rb = File.join("/", root(name), "etc/chef/client.rb")
269
+ def chef_config_client(container)
270
+ tempfile = Tempfile.new(container.name)
271
+ client_rb = File.join("/", root(container.name), "etc/chef/client.rb")
282
272
 
283
273
  @test_lab.bootstrap_ssh.exec(%Q{sudo mkdir -pv #{File.dirname(client_rb)}}, :silence => true)
284
274
 
@@ -288,7 +278,7 @@ module Cucumber
288
278
  File.open(tempfile, 'w') do |f|
289
279
  f.puts(Cucumber::Chef.generate_do_not_edit_warning("Chef Client Configuration"))
290
280
  f.puts
291
- @chef_client_config.merge(:node_name => name).each do |(key,value)|
281
+ @chef_client_config.merge(:node_name => container.name).each do |(key,value)|
292
282
  next if value.nil?
293
283
  f.puts("%-#{max_key_size}s %s" % [key, value.inspect])
294
284
  end
@@ -301,59 +291,43 @@ module Cucumber
301
291
  @test_lab.bootstrap_ssh.exec(%Q{sudo /bin/bash -c '[[ -f #{client_rb} ]] && rm -fv #{client_rb}'}, :silence => true, :ignore_exit_status => true)
302
292
  end
303
293
 
304
- tempfile = Tempfile.new(name)
305
- attributes_json = File.join("/", root(name), "etc", "chef", "attributes.json")
294
+ tempfile = Tempfile.new(container.name)
295
+ attributes_json = File.join("/", root(container.name), "etc", "chef", "attributes.json")
306
296
  @test_lab.bootstrap_ssh.exec(%Q{sudo mkdir -pv #{File.dirname(attributes_json)}}, :silence => true)
307
297
  File.open(tempfile, 'w') do |f|
308
- f.puts((@containers[name][:chef_client] || {}).to_json)
298
+ f.puts((container.chef_client || {}).to_json)
309
299
  end
310
300
  @test_lab.bootstrap_ssh.upload(tempfile.path, File.basename(tempfile.path))
311
301
  @test_lab.bootstrap_ssh.exec(%Q{sudo mv -v #{File.basename(tempfile.path)} #{attributes_json}}, :silence => true)
312
302
 
313
303
  # make sure our log location is there
314
- log_location = File.join("/", root(name), @chef_client_config[:log_location])
304
+ log_location = File.join("/", root(container.name), @chef_client_config[:log_location])
315
305
  @test_lab.bootstrap_ssh.exec(%Q{sudo mkdir -pv #{File.dirname(log_location)}}, :silence => true)
316
306
 
317
- @test_lab.bootstrap_ssh.exec(%Q{sudo cp /etc/chef/validation.pem #{root(name)}/etc/chef/}, :silence => true)
307
+ @test_lab.bootstrap_ssh.exec(%Q{sudo cp /etc/chef/validation.pem #{root(container.name)}/etc/chef/}, :silence => true)
318
308
 
319
309
  true
320
310
  end
321
311
 
322
312
  ################################################################################
323
313
 
324
- def chef_client_artifacts(name)
325
- # this is messy and needs to be refactored into a more configurable
326
- # solution; but for now this should do the trick
327
-
328
- ssh = @test_lab.proxy_ssh(name)
329
-
330
- feature_file = $scenario.file_colon_line.split(":").first
331
- feature_line = $scenario.file_colon_line.split(":").last
332
- scenario_tag = $scenario.name.gsub(" ", "_")
333
-
334
- feature_name = File.basename(feature_file, ".feature")
335
- feature_dir = feature_file.split("/")[-2]
314
+ def chef_client_artifacts(container)
315
+ ssh = @test_lab.proxy_ssh(container.name)
336
316
 
337
317
  Cucumber::Chef::Config[:artifacts].each do |label, remote_path|
338
318
  result = ssh.exec("sudo /bin/bash -c '[[ -f #{remote_path} ]] ; echo $? ; true'", :silence => true)
339
319
  if (result.output =~ /0/)
340
- @ui.logger.info { "Retrieving artifact '#{remote_path}' from container '#{name}'." }
320
+ @ui.logger.info { "Retrieving artifact '#{remote_path}' from container '#{container.name}'." }
341
321
 
342
- local_path = File.join(Cucumber::Chef.artifacts_dir, feature_dir, "#{feature_name}.txt")
322
+ local_path = File.join(Cucumber::Chef.artifacts_dir, "#{container.name}.log")
343
323
  tmp_path = File.join("/tmp", label)
344
324
 
345
325
  FileUtils.mkdir_p(File.dirname(local_path))
346
326
  ssh.download(remote_path, tmp_path)
347
327
  data = IO.read(tmp_path).chomp
348
328
 
349
- message = "#{$scenario.name} (#{File.basename(feature_file)}:#{feature_line}:#{label})"
350
- header = ("-" * message.length)
351
-
352
- f = File.open(local_path, "a")
353
- f.write("#{header}\n")
354
- f.write("#{message}\n")
355
- f.write("#{header}\n")
356
- f.write("#{data}\n")
329
+ f = File.open(local_path, "w")
330
+ f.write(data)
357
331
 
358
332
  File.chmod(0644, local_path)
359
333
  end
@@ -364,9 +338,9 @@ module Cucumber
364
338
 
365
339
  ################################################################################
366
340
 
367
- def config_network(name)
368
- tempfile = Tempfile.new(name)
369
- lxc_network_config = File.join("/etc/lxc", name)
341
+ def config_network(container)
342
+ tempfile = Tempfile.new(container.name)
343
+ lxc_network_config = File.join("/etc/lxc", container.name)
370
344
  File.open(tempfile, 'w') do |f|
371
345
  f.puts(Cucumber::Chef.generate_do_not_edit_warning("LXC Container Configuration"))
372
346
  f.puts("")
@@ -374,7 +348,7 @@ module Cucumber
374
348
  f.puts("lxc.network.flags = up")
375
349
  f.puts("lxc.network.link = br0")
376
350
  f.puts("lxc.network.name = eth0")
377
- f.puts("lxc.network.hwaddr = #{@containers[name][:mac]}")
351
+ f.puts("lxc.network.hwaddr = #{container.mac}")
378
352
  f.puts("lxc.network.ipv4 = 0.0.0.0")
379
353
  end
380
354
  @test_lab.bootstrap_ssh.upload(tempfile.path, File.basename(tempfile.path))
@@ -388,14 +362,14 @@ module Cucumber
388
362
  dhcpd_config = File.join("/etc/dhcp/test-lab.conf")
389
363
  File.open(tempfile, 'w') do |f|
390
364
  f.puts(Cucumber::Chef.generate_do_not_edit_warning("DHCPD Configuration"))
391
- @containers.each do |key, value|
392
- next if [:mac, :ip].any?{ |z| value[z].nil? }
365
+ Container.all.each do |container|
366
+ next if [container.mac, container.ip].any?{ |z| z.nil? }
393
367
 
394
368
  f.puts
395
- f.puts("host #{key} {")
396
- f.puts(" hardware ethernet #{value[:mac]};")
397
- f.puts(" fixed-address #{value[:ip]};")
398
- f.puts(" ddns-hostname \"#{key}\";")
369
+ f.puts("host #{container.name} {")
370
+ f.puts(" hardware ethernet #{container.mac};")
371
+ f.puts(" fixed-address #{container.ip};")
372
+ f.puts(" ddns-hostname \"#{container.name}\";")
399
373
  f.puts("}")
400
374
  end
401
375
  f.flush
@@ -410,10 +384,6 @@ module Cucumber
410
384
 
411
385
  ################################################################################
412
386
 
413
- def tag(name)
414
- @containers[name].inspect.to_s
415
- end
416
-
417
387
  def detect_arch(distro)
418
388
  @arch ||= @test_lab.bootstrap_ssh.exec("uname -m", :silence => true).output.chomp
419
389
  case distro.downcase
@@ -424,12 +394,6 @@ module Cucumber
424
394
  end
425
395
  end
426
396
 
427
- ################################################################################
428
-
429
- def containers
430
- @test_lab.bootstrap_ssh.exec("sudo lxc-ls 2>&1", :silence => true).output.split("\n").uniq
431
- end
432
-
433
397
  ################################################################################
434
398
 
435
399
  def running?(name)
@@ -471,43 +435,6 @@ module Cucumber
471
435
  end
472
436
  end
473
437
 
474
- ################################################################################
475
-
476
- def generate_ip
477
- octets = [ 192..192,
478
- 168..168,
479
- 0..254,
480
- 1..254 ]
481
- ip = Array.new
482
- for x in 1..4 do
483
- ip << octets[x-1].to_a[rand(octets[x-1].count)].to_s
484
- end
485
- ip.join(".")
486
- end
487
-
488
- ################################################################################
489
-
490
- def generate_mac
491
- digits = [ %w(0),
492
- %w(0),
493
- %w(0),
494
- %w(0),
495
- %w(5),
496
- %w(e),
497
- %w(0 1 2 3 4 5 6 7 8 9 a b c d e f),
498
- %w(0 1 2 3 4 5 6 7 8 9 a b c d e f),
499
- %w(5 6 7 8 9 a b c d e f),
500
- %w(3 4 5 6 7 8 9 a b c d e f),
501
- %w(0 1 2 3 4 5 6 7 8 9 a b c d e f),
502
- %w(0 1 2 3 4 5 6 7 8 9 a b c d e f) ]
503
- mac = ""
504
- for x in 1..12 do
505
- mac += digits[x-1][rand(digits[x-1].count)]
506
- mac += ":" if (x.modulo(2) == 0) && (x != 12)
507
- end
508
- mac
509
- end
510
-
511
438
  ################################################################################
512
439
 
513
440
  end