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.
- 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
|