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.
- data/bin/cc-knife +1 -9
- data/bin/cucumber-chef +27 -15
- data/chef_repo/cookbooks/cucumber-chef/recipes/test_lab.rb +7 -7
- data/cucumber-chef.gemspec +1 -4
- data/lib/cucumber-chef/rake/task.rb +55 -36
- data/lib/cucumber/chef.rb +3 -3
- data/lib/cucumber/chef/container.rb +44 -0
- data/lib/cucumber/chef/containers.rb +108 -181
- data/lib/cucumber/chef/ecosystem.rb +37 -0
- data/lib/cucumber/chef/labfile.rb +34 -0
- data/lib/cucumber/chef/provisioner.rb +5 -42
- data/lib/cucumber/chef/steps.rb +0 -1
- data/lib/cucumber/chef/steps/ssh_steps.rb +2 -2
- data/lib/cucumber/chef/templates/bootstrap/ubuntu-precise-test-lab.erb +4 -1
- data/lib/cucumber/chef/templates/cucumber-chef/cucumber-yml.erb +1 -1
- data/lib/cucumber/chef/templates/cucumber/cc-hooks.rb +34 -33
- data/lib/cucumber/chef/test_lab.rb +4 -1
- data/lib/cucumber/chef/utility.rb +22 -32
- data/lib/cucumber/chef/version.rb +1 -1
- metadata +7 -22
- data/lib/cucumber/chef/steps/provision_steps.rb +0 -64
- data/lib/cucumber/chef/templates/cucumber-chef/knife-rb.erb +0 -18
data/bin/cc-knife
CHANGED
@@ -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)
|
data/bin/cucumber-chef
CHANGED
@@ -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, :
|
318
|
-
results = ZTK::Report.new.spreadsheet(
|
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 #{
|
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 =>
|
328
|
-
:mac =>
|
329
|
-
: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 =>
|
334
|
-
:chef_attributes =>
|
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
|
-
"
|
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
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
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
|
data/cucumber-chef.gemspec
CHANGED
@@ -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.
|
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
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
20
|
+
def run_feature(feature_file)
|
21
|
+
puts("=" * 80)
|
22
|
+
puts("run_feature(#{feature_file.inspect})")
|
23
|
+
puts("=" * 80)
|
31
24
|
|
32
|
-
|
33
|
-
|
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
|
-
|
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
|
-
|
44
|
-
|
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
|
-
|
47
|
-
|
48
|
-
|
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
|
-
|
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
|
-
|
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
|
|
data/lib/cucumber/chef.rb
CHANGED
@@ -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
|
-
|
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
|
59
|
-
|
60
|
-
|
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
|
-
|
80
|
-
|
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
|
-
|
83
|
-
|
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
|
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(
|
101
|
-
_create(name,
|
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
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
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
|
155
|
-
|
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(
|
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(
|
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((
|
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(
|
325
|
-
|
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,
|
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
|
-
|
350
|
-
|
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(
|
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 = #{
|
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
|
-
|
392
|
-
next if [
|
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 #{
|
396
|
-
f.puts(" hardware ethernet #{
|
397
|
-
f.puts(" fixed-address #{
|
398
|
-
f.puts(" ddns-hostname \"#{
|
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
|