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

Sign up to get free protection for your applications and to get access to all the features.
@@ -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