cucumber-chef 2.1.0.rc.11 → 2.1.0.rc.12
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/cucumber-chef +10 -24
- data/chef_repo/cookbooks/cucumber-chef/recipes/lxc.rb +1 -65
- data/chef_repo/cookbooks/cucumber-chef/recipes/test_lab.rb +1 -41
- data/cucumber-chef.gemspec +1 -2
- data/lib/cucumber/chef/client.rb +50 -60
- data/lib/cucumber/chef/containers.rb +519 -0
- data/lib/cucumber/chef/providers/aws.rb +0 -2
- data/lib/cucumber/chef/providers/vagrant.rb +1 -1
- data/lib/cucumber/chef/steps/provision_steps.rb +11 -13
- data/lib/cucumber/chef/test_lab.rb +15 -40
- data/lib/cucumber/chef/version.rb +1 -1
- data/lib/cucumber/chef.rb +1 -4
- metadata +4 -17
- data/bin/cc-push +0 -49
- data/bin/cc-server +0 -84
- data/chef_repo/cookbooks/cucumber-chef/templates/default/gemrc.erb +0 -10
- data/lib/cucumber/chef/helpers/chef_client.rb +0 -167
- data/lib/cucumber/chef/helpers/chef_server.rb +0 -42
- data/lib/cucumber/chef/helpers/command.rb +0 -60
- data/lib/cucumber/chef/helpers/container.rb +0 -187
- data/lib/cucumber/chef/helpers/minitest.rb +0 -35
- data/lib/cucumber/chef/helpers/server.rb +0 -115
- data/lib/cucumber/chef/helpers/test_lab.rb +0 -52
- data/lib/cucumber/chef/helpers/utility.rb +0 -71
- data/lib/cucumber/chef/helpers.rb +0 -50
@@ -0,0 +1,519 @@
|
|
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 ContainersError < Error; end
|
26
|
+
|
27
|
+
class Containers
|
28
|
+
################################################################################
|
29
|
+
|
30
|
+
def initialize(ui=ZTK::UI.new, test_lab=nil)
|
31
|
+
@ui, @test_lab = ui, test_lab
|
32
|
+
end
|
33
|
+
|
34
|
+
################################################################################
|
35
|
+
|
36
|
+
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
|
54
|
+
end
|
55
|
+
|
56
|
+
################################################################################
|
57
|
+
|
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
|
+
################################################################################
|
78
|
+
|
79
|
+
def create(name)
|
80
|
+
init(name)
|
81
|
+
|
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
|
+
:arch => detect_arch(attributes[:distro] || "ubuntu")
|
93
|
+
}.merge(attributes)
|
94
|
+
|
95
|
+
if running?(name)
|
96
|
+
@ui.logger.info { "Container '#{name}' is already running." }
|
97
|
+
else
|
98
|
+
@ui.logger.info { "Please wait, creating container {#{name.inspect} => #{tag(name)}}." }
|
99
|
+
bm = ::Benchmark.realtime do
|
100
|
+
test_lab_config_dhcpd
|
101
|
+
config_network(name)
|
102
|
+
_create(name, @containers[name][:distro], @containers[name][:release], @containers[name][:arch])
|
103
|
+
end
|
104
|
+
@ui.logger.info { "Container '#{name}' creation took %0.4f seconds." % bm }
|
105
|
+
|
106
|
+
# bm = ::Benchmark.realtime do
|
107
|
+
# ZTK::TCPSocketCheck.new(:host => @containers[name][:ip], :port => 22).wait
|
108
|
+
# end
|
109
|
+
# @ui.logger.info { "Container '#{name}' SSHD responded after %0.4f seconds." % bm }
|
110
|
+
end
|
111
|
+
|
112
|
+
save
|
113
|
+
end
|
114
|
+
|
115
|
+
################################################################################
|
116
|
+
|
117
|
+
def destroy(name)
|
118
|
+
if exists?(name)
|
119
|
+
@test_lab.knife_cli("node delete #{name} --yes", :ignore_exit_status => true)
|
120
|
+
@test_lab.knife_cli("client delete #{name} --yes", :ignore_exit_status => true)
|
121
|
+
stop(name)
|
122
|
+
@test_lab.bootstrap_ssh.exec("sudo lxc-destroy -n #{name}", :silence => true)
|
123
|
+
@ui.logger.info { "Destroyed container '#{name}'." }
|
124
|
+
test_lab_config_dhcpd
|
125
|
+
@containers.delete(name)
|
126
|
+
save
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
################################################################################
|
131
|
+
|
132
|
+
def set_attributes(name, attributes={})
|
133
|
+
@containers[name].merge!(attributes)
|
134
|
+
end
|
135
|
+
|
136
|
+
################################################################################
|
137
|
+
|
138
|
+
def chef_set_client_config(config={})
|
139
|
+
@chef_client_config = (@chef_client_config || {
|
140
|
+
:log_level => :info,
|
141
|
+
:log_location => "/var/log/chef/client.log",
|
142
|
+
:chef_server_url => "https://api.opscode.com/organizations/#{config[:orgname]}",
|
143
|
+
:validation_client_name => "#{config[:orgname]}-validator",
|
144
|
+
:ssl_verify_mode => :verify_none,
|
145
|
+
:environment => nil # use default; i.e. set no value
|
146
|
+
}).merge(config)
|
147
|
+
|
148
|
+
@ui.logger.info { "Setting chef client config '#{@chef_client_config.inspect}'." }
|
149
|
+
|
150
|
+
true
|
151
|
+
end
|
152
|
+
|
153
|
+
################################################################################
|
154
|
+
|
155
|
+
def chef_set_client_attributes(name, attributes={})
|
156
|
+
@containers[name] ||= Hash.new
|
157
|
+
@containers[name][:chef_client] = (@containers[name][:chef_client] || {}).merge(attributes) { |k,o,n| (k = (o + n).uniq) }
|
158
|
+
|
159
|
+
@ui.logger.info { "Setting chef client attributes to '#{@containers[name][:chef_client].inspect}' for container '#{name}'." }
|
160
|
+
|
161
|
+
true
|
162
|
+
end
|
163
|
+
|
164
|
+
################################################################################
|
165
|
+
|
166
|
+
def chef_run_client(name, *args)
|
167
|
+
chef_config_client(name)
|
168
|
+
|
169
|
+
@ui.logger.info { "Removing artifacts #{Cucumber::Chef::Config[:artifacts].values.collect{|z| "'#{z}'" }.join(' ')}." }
|
170
|
+
(@test_lab.proxy_ssh(name).exec("/bin/rm -fv #{Cucumber::Chef::Config[:artifacts].values.join(' ')}", :silence => true) rescue nil)
|
171
|
+
|
172
|
+
@ui.logger.info { "Running chef client on container '#{name}'." }
|
173
|
+
|
174
|
+
arguments = {
|
175
|
+
"--node-name" => name,
|
176
|
+
"--json-attributes" => File.join("/etc", "chef", "attributes.json").to_s,
|
177
|
+
"--log_level" => @chef_client_config[:log_level],
|
178
|
+
"--logfile" => @chef_client_config[:log_location],
|
179
|
+
"--server" => @chef_client_config[:chef_server_url],
|
180
|
+
"--environment" => @chef_client_config[:environment]
|
181
|
+
}.reject{ |k,v| v.nil? }.sort
|
182
|
+
|
183
|
+
output = nil
|
184
|
+
bm = ::Benchmark.realtime do
|
185
|
+
output = @test_lab.proxy_ssh(name).exec(["/usr/bin/chef-client", arguments, args, "--once"].flatten.join(" "), :silence => true)
|
186
|
+
end
|
187
|
+
@ui.logger.info { "Chef client run on container '#{name}' took %0.4f seconds." % bm }
|
188
|
+
|
189
|
+
chef_client_artifacts(name)
|
190
|
+
|
191
|
+
output
|
192
|
+
end
|
193
|
+
|
194
|
+
################################################################################
|
195
|
+
|
196
|
+
def enable_minitest(name)
|
197
|
+
@chef_client_attributes[:run_list].unshift("recipe[minitest-handler]")
|
198
|
+
end
|
199
|
+
|
200
|
+
def run_minitests(name)
|
201
|
+
chef_run = chef_run_client(name, "-l info")
|
202
|
+
test_result = chef_run.drop_while {|e| e !~ /^# Running tests/}.take_while {|e| e !~ /^[.*] INFO/}
|
203
|
+
puts test_result
|
204
|
+
test_result
|
205
|
+
end
|
206
|
+
|
207
|
+
################################################################################
|
208
|
+
private
|
209
|
+
################################################################################
|
210
|
+
|
211
|
+
def _create(name, distro, release, arch)
|
212
|
+
unless exists?(name)
|
213
|
+
cache_rootfs = cache_root(name, distro, release, arch)
|
214
|
+
if !File.exists?(cache_rootfs)
|
215
|
+
@ui.logger.warn { "'#{name}' has triggered building the lxc file cache for '#{distro}'." }
|
216
|
+
@ui.logger.warn { "This one time process per distro can take up to 10 minutes or longer depending on the test lab." }
|
217
|
+
end
|
218
|
+
|
219
|
+
@test_lab.bootstrap_ssh.exec(create_command(name, distro, release, arch), :silence => true)
|
220
|
+
|
221
|
+
commands = Array.new
|
222
|
+
|
223
|
+
# install omnibus into the distro/release file cache if it's not already there
|
224
|
+
omnibus_chef_client = File.join("/", "opt", "chef", "bin", "chef-client")
|
225
|
+
omnibus_cache = File.join(cache_rootfs, omnibus_chef_client)
|
226
|
+
@ui.logger.info { "looking for omnibus cache in #{omnibus_cache}" }
|
227
|
+
if @test_lab.bootstrap_ssh.exec(%Q{sudo /bin/bash -c '[[ -f #{omnibus_cache} ]] ; echo $? ; true'}, :silence => true).output.chomp =~ /1/
|
228
|
+
case distro.downcase
|
229
|
+
when "ubuntu" then
|
230
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo chroot #{cache_rootfs} /bin/bash -c 'DEBIAN_FRONTEND=noninteractive apt-get -y --force-yes install wget'}, :silence => true)
|
231
|
+
when "fedora" then
|
232
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo yum --nogpgcheck --installroot=#{cache_rootfs} -y install wget openssh-server}, :silence => true)
|
233
|
+
end
|
234
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo chroot #{cache_rootfs} /bin/bash -c 'locale-gen'}, :silence => true)
|
235
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo chroot #{cache_rootfs} /bin/bash -c 'locale-gen en_US'}, :silence => true)
|
236
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo chroot #{cache_rootfs} /bin/bash -c 'wget http://www.opscode.com/chef/install.sh'}, :silence => true)
|
237
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo chroot #{cache_rootfs} /bin/bash -c 'bash install.sh -v #{Cucumber::Chef::Config.chef[:version]}'}, :silence => true)
|
238
|
+
if distro.downcase == "fedora"
|
239
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo chroot #{cache_rootfs} /bin/bash -c 'rpm -Uvh --nodeps /tmp/*rpm'}, :silence => true)
|
240
|
+
end
|
241
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo lxc-destroy -n #{name}}, :silence => true)
|
242
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo #{create_command(name, distro, release, arch)}}, :silence => true)
|
243
|
+
end
|
244
|
+
|
245
|
+
lab_ssh_path = File.join(Cucumber::Chef.lab_user_home_dir, ".ssh")
|
246
|
+
ssh_path = File.join(root(name), Cucumber::Chef.lxc_user_home_dir, ".ssh")
|
247
|
+
motd_path = File.join(root(name), "etc", "motd")
|
248
|
+
|
249
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo mkdir -vp #{ssh_path}}, :silence => true)
|
250
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo chmod 0700 #{ssh_path}}, :silence => true)
|
251
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo cat #{File.join(lab_ssh_path, "id_rsa.pub")} | sudo tee -a #{File.join(ssh_path, "authorized_keys")}}, :silence => true)
|
252
|
+
|
253
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo rm -vf #{motd_path}}, :silence => true)
|
254
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo cp -v /etc/motd #{motd_path}}, :silence => true)
|
255
|
+
@test_lab.bootstrap_ssh.exec(%Q{echo " You are now logged in to the "#{name}" container!\n" | sudo tee -a #{motd_path}}, :silence => true)
|
256
|
+
@test_lab.bootstrap_ssh.exec(%Q{echo "127.0.0.1 #{name}.#{Cucumber::Chef::Config.test_lab[:tld]} #{name}" | sudo tee -a #{File.join(root(name), "etc", "hosts")}}, :silence => true)
|
257
|
+
@test_lab.bootstrap_ssh.exec(%Q{echo "#{name}.test-lab" | sudo tee #{File.join(root(name), "etc", "hostname")}}, :silence => true)
|
258
|
+
end
|
259
|
+
start(name)
|
260
|
+
end
|
261
|
+
|
262
|
+
################################################################################
|
263
|
+
|
264
|
+
def start(name)
|
265
|
+
status = @test_lab.bootstrap_ssh.exec("sudo lxc-info -n #{name}", :silence => true).output
|
266
|
+
if status.include?("STOPPED")
|
267
|
+
@test_lab.bootstrap_ssh.exec("sudo lxc-start -d -n #{name}", :silence => true)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
def stop(name)
|
272
|
+
status = @test_lab.bootstrap_ssh.exec("sudo lxc-info -n #{name}", :silence => true).output
|
273
|
+
if status.include?("RUNNING")
|
274
|
+
@test_lab.bootstrap_ssh.exec("sudo lxc-stop -n #{name}", :silence => true)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
################################################################################
|
279
|
+
|
280
|
+
def chef_config_client(name)
|
281
|
+
tempfile = Tempfile.new(name)
|
282
|
+
client_rb = File.join("/", root(name), "etc/chef/client.rb")
|
283
|
+
|
284
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo mkdir -pv #{File.dirname(client_rb)}}, :silence => true)
|
285
|
+
|
286
|
+
if Cucumber::Chef::Config.chef[:render_client_rb]
|
287
|
+
max_key_size = @chef_client_config.keys.collect{ |z| z.to_s.size }.max
|
288
|
+
|
289
|
+
File.open(tempfile, 'w') do |f|
|
290
|
+
f.puts(Cucumber::Chef.generate_do_not_edit_warning("Chef Client Configuration"))
|
291
|
+
f.puts
|
292
|
+
@chef_client_config.merge(:node_name => name).each do |(key,value)|
|
293
|
+
next if value.nil?
|
294
|
+
f.puts("%-#{max_key_size}s %s" % [key, value.inspect])
|
295
|
+
end
|
296
|
+
f.puts
|
297
|
+
f.puts("Mixlib::Log::Formatter.show_time = true")
|
298
|
+
end
|
299
|
+
@test_lab.bootstrap_ssh.upload(tempfile.path, File.basename(tempfile.path))
|
300
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo mv -v #{File.basename(tempfile.path)} #{client_rb}}, :silence => true)
|
301
|
+
else
|
302
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo /bin/bash -c '[[ -f #{client_rb} ]] && rm -fv #{client_rb}'}, :silence => true, :ignore_exit_status => true)
|
303
|
+
end
|
304
|
+
|
305
|
+
tempfile = Tempfile.new(name)
|
306
|
+
attributes_json = File.join("/", root(name), "etc", "chef", "attributes.json")
|
307
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo mkdir -pv #{File.dirname(attributes_json)}}, :silence => true)
|
308
|
+
File.open(tempfile, 'w') do |f|
|
309
|
+
f.puts((@containers[name][:chef_client] || {}).to_json)
|
310
|
+
end
|
311
|
+
@test_lab.bootstrap_ssh.upload(tempfile.path, File.basename(tempfile.path))
|
312
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo mv -v #{File.basename(tempfile.path)} #{attributes_json}}, :silence => true)
|
313
|
+
|
314
|
+
# make sure our log location is there
|
315
|
+
log_location = File.join("/", root(name), @chef_client_config[:log_location])
|
316
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo mkdir -pv #{File.dirname(log_location)}}, :silence => true)
|
317
|
+
|
318
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo cp /etc/chef/validation.pem #{root(name)}/etc/chef/}, :silence => true)
|
319
|
+
|
320
|
+
true
|
321
|
+
end
|
322
|
+
|
323
|
+
################################################################################
|
324
|
+
|
325
|
+
def chef_client_artifacts(name)
|
326
|
+
# this is messy and needs to be refactored into a more configurable
|
327
|
+
# solution; but for now this should do the trick
|
328
|
+
|
329
|
+
ssh = @test_lab.proxy_ssh(name)
|
330
|
+
|
331
|
+
feature_file = $scenario.file_colon_line.split(":").first
|
332
|
+
feature_line = $scenario.file_colon_line.split(":").last
|
333
|
+
scenario_tag = $scenario.name.gsub(" ", "_")
|
334
|
+
|
335
|
+
feature_name = File.basename(feature_file, ".feature")
|
336
|
+
feature_dir = feature_file.split("/")[-2]
|
337
|
+
|
338
|
+
Cucumber::Chef::Config[:artifacts].each do |label, remote_path|
|
339
|
+
result = ssh.exec("sudo /bin/bash -c '[[ -f #{remote_path} ]] ; echo $? ; true'", :silence => true)
|
340
|
+
if (result.output =~ /0/)
|
341
|
+
@ui.logger.info { "Retrieving artifact '#{remote_path}' from container '#{name}'." }
|
342
|
+
|
343
|
+
local_path = File.join(Cucumber::Chef.artifacts_dir, feature_dir, "#{feature_name}.txt")
|
344
|
+
tmp_path = File.join("/tmp", label)
|
345
|
+
|
346
|
+
FileUtils.mkdir_p(File.dirname(local_path))
|
347
|
+
ssh.download(remote_path, tmp_path)
|
348
|
+
data = IO.read(tmp_path).chomp
|
349
|
+
|
350
|
+
message = "#{$scenario.name} (#{File.basename(feature_file)}:#{feature_line}:#{label})"
|
351
|
+
header = ("-" * message.length)
|
352
|
+
|
353
|
+
f = File.open(local_path, "a")
|
354
|
+
f.write("#{header}\n")
|
355
|
+
f.write("#{message}\n")
|
356
|
+
f.write("#{header}\n")
|
357
|
+
f.write("#{data}\n")
|
358
|
+
|
359
|
+
File.chmod(0644, local_path)
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
true
|
364
|
+
end
|
365
|
+
|
366
|
+
################################################################################
|
367
|
+
|
368
|
+
def config_network(name)
|
369
|
+
tempfile = Tempfile.new(name)
|
370
|
+
lxc_network_config = File.join("/etc/lxc", name)
|
371
|
+
File.open(tempfile, 'w') do |f|
|
372
|
+
f.puts(Cucumber::Chef.generate_do_not_edit_warning("LXC Container Configuration"))
|
373
|
+
f.puts("")
|
374
|
+
f.puts("lxc.network.type = veth")
|
375
|
+
f.puts("lxc.network.flags = up")
|
376
|
+
f.puts("lxc.network.link = br0")
|
377
|
+
f.puts("lxc.network.name = eth0")
|
378
|
+
f.puts("lxc.network.hwaddr = #{@containers[name][:mac]}")
|
379
|
+
f.puts("lxc.network.ipv4 = 0.0.0.0")
|
380
|
+
end
|
381
|
+
@test_lab.bootstrap_ssh.upload(tempfile.path, File.basename(tempfile.path))
|
382
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo mv -v #{File.basename(tempfile.path)} #{lxc_network_config}}, :silence => true)
|
383
|
+
end
|
384
|
+
|
385
|
+
################################################################################
|
386
|
+
|
387
|
+
def test_lab_config_dhcpd
|
388
|
+
tempfile = Tempfile.new("dhcpd")
|
389
|
+
dhcpd_config = File.join("/etc/dhcp/test-lab.conf")
|
390
|
+
File.open(tempfile, 'w') do |f|
|
391
|
+
f.puts(Cucumber::Chef.generate_do_not_edit_warning("DHCPD Configuration"))
|
392
|
+
@containers.each do |key, value|
|
393
|
+
next if [:mac, :ip].any?{ |z| value[z].nil? }
|
394
|
+
|
395
|
+
f.puts
|
396
|
+
f.puts("host #{key} {")
|
397
|
+
f.puts(" hardware ethernet #{value[:mac]};")
|
398
|
+
f.puts(" fixed-address #{value[:ip]};")
|
399
|
+
f.puts(" ddns-hostname \"#{key}\";")
|
400
|
+
f.puts("}")
|
401
|
+
end
|
402
|
+
f.flush
|
403
|
+
f.close
|
404
|
+
end
|
405
|
+
@test_lab.bootstrap_ssh.upload(tempfile.path, File.basename(tempfile.path))
|
406
|
+
@test_lab.bootstrap_ssh.exec(%Q{sudo mv -v #{File.basename(tempfile.path)} #{dhcpd_config}}, :silence => true)
|
407
|
+
|
408
|
+
@test_lab.bootstrap_ssh.exec("sudo service isc-dhcp-server restart", :silence => true)
|
409
|
+
@test_lab.bootstrap_ssh.exec("sudo service bind9 restart", :silence => true)
|
410
|
+
end
|
411
|
+
|
412
|
+
################################################################################
|
413
|
+
|
414
|
+
def tag(name)
|
415
|
+
@containers[name].inspect.to_s
|
416
|
+
end
|
417
|
+
|
418
|
+
def detect_arch(distro)
|
419
|
+
@arch ||= @test_lab.bootstrap_ssh.exec("uname -m", :silence => true).output.chomp
|
420
|
+
case distro.downcase
|
421
|
+
when "ubuntu" then
|
422
|
+
((@arch =~ /x86_64/) ? "amd64" : "i386")
|
423
|
+
when "fedora" then
|
424
|
+
((@arch =~ /x86_64/) ? "amd64" : "i686")
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
################################################################################
|
429
|
+
|
430
|
+
def containers
|
431
|
+
@test_lab.bootstrap_ssh.exec("sudo lxc-ls 2>&1", :silence => true).output.split("\n").uniq
|
432
|
+
end
|
433
|
+
|
434
|
+
################################################################################
|
435
|
+
|
436
|
+
def running?(name)
|
437
|
+
status = @test_lab.bootstrap_ssh.exec("sudo lxc-info -n #{name}", :silence => true).output.chomp
|
438
|
+
status.include?("RUNNING")
|
439
|
+
end
|
440
|
+
|
441
|
+
################################################################################
|
442
|
+
|
443
|
+
def exists?(name)
|
444
|
+
(@test_lab.bootstrap_ssh.exec("sudo /bin/bash -c '[[ -d #{root(name)} ]] ; echo $? ; true'", :silence => true).output.chomp =~ /0/)
|
445
|
+
end
|
446
|
+
|
447
|
+
################################################################################
|
448
|
+
|
449
|
+
def root(name)
|
450
|
+
File.join("/", "var", "lib", "lxc", name, "rootfs")
|
451
|
+
end
|
452
|
+
|
453
|
+
################################################################################
|
454
|
+
|
455
|
+
def cache_root(name, distro, release, arch)
|
456
|
+
case distro.downcase
|
457
|
+
when "ubuntu" then
|
458
|
+
cache_root = File.join("/", "var", "cache", "lxc", release, "rootfs-#{arch}")
|
459
|
+
when "fedora" then
|
460
|
+
cache_root = File.join("/", "var", "cache", "lxc", distro, arch, release, "rootfs")
|
461
|
+
end
|
462
|
+
end
|
463
|
+
|
464
|
+
################################################################################
|
465
|
+
|
466
|
+
def create_command(name, distro, release, arch)
|
467
|
+
case distro.downcase
|
468
|
+
when "ubuntu" then
|
469
|
+
"sudo DEBIAN_FRONTEND=noninteractive lxc-create -n #{name} -f /etc/lxc/#{name} -t #{distro} -- --release #{release} --arch #{arch}"
|
470
|
+
when "fedora" then
|
471
|
+
"sudo lxc-create -n #{name} -f /etc/lxc/#{name} -t #{distro} -- --release #{release}"
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
################################################################################
|
476
|
+
|
477
|
+
def generate_ip
|
478
|
+
octets = [ 192..192,
|
479
|
+
168..168,
|
480
|
+
0..254,
|
481
|
+
1..254 ]
|
482
|
+
ip = Array.new
|
483
|
+
for x in 1..4 do
|
484
|
+
ip << octets[x-1].to_a[rand(octets[x-1].count)].to_s
|
485
|
+
end
|
486
|
+
ip.join(".")
|
487
|
+
end
|
488
|
+
|
489
|
+
################################################################################
|
490
|
+
|
491
|
+
def generate_mac
|
492
|
+
digits = [ %w(0),
|
493
|
+
%w(0),
|
494
|
+
%w(0),
|
495
|
+
%w(0),
|
496
|
+
%w(5),
|
497
|
+
%w(e),
|
498
|
+
%w(0 1 2 3 4 5 6 7 8 9 a b c d e f),
|
499
|
+
%w(0 1 2 3 4 5 6 7 8 9 a b c d e f),
|
500
|
+
%w(5 6 7 8 9 a b c d e f),
|
501
|
+
%w(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
|
+
%w(0 1 2 3 4 5 6 7 8 9 a b c d e f) ]
|
504
|
+
mac = ""
|
505
|
+
for x in 1..12 do
|
506
|
+
mac += digits[x-1][rand(digits[x-1].count)]
|
507
|
+
mac += ":" if (x.modulo(2) == 0) && (x != 12)
|
508
|
+
end
|
509
|
+
mac
|
510
|
+
end
|
511
|
+
|
512
|
+
################################################################################
|
513
|
+
|
514
|
+
end
|
515
|
+
|
516
|
+
end
|
517
|
+
end
|
518
|
+
|
519
|
+
################################################################################
|
@@ -240,12 +240,10 @@ module Cucumber
|
|
240
240
|
security_group.authorize_port_range(22..22) if port_ranges.none?{ |port_range| port_range === 22 }
|
241
241
|
security_group.authorize_port_range(4000..4000) if port_ranges.none?{ |port_range| port_range === 4000 }
|
242
242
|
security_group.authorize_port_range(4040..4040) if port_ranges.none?{ |port_range| port_range === 4040 }
|
243
|
-
security_group.authorize_port_range(8787..8787) if port_ranges.none?{ |port_range| port_range === 8787 }
|
244
243
|
elsif (security_group = @connection.security_groups.new(:name => security_group_name, :description => "cucumber-chef test lab")).save
|
245
244
|
security_group.authorize_port_range(22..22)
|
246
245
|
security_group.authorize_port_range(4000..4000)
|
247
246
|
security_group.authorize_port_range(4040..4040)
|
248
|
-
security_group.authorize_port_range(8787..8787)
|
249
247
|
else
|
250
248
|
raise AWSError, "Could not find an existing or create a new AWS security group."
|
251
249
|
end
|
@@ -20,47 +20,45 @@
|
|
20
20
|
################################################################################
|
21
21
|
|
22
22
|
Given /^I have a server called "([^\"]*)"$/ do |name|
|
23
|
-
$test_lab.
|
23
|
+
$test_lab.containers.init(name)
|
24
24
|
end
|
25
25
|
|
26
26
|
And /^"([^\"]*)" is running "([^\"]*)" "([^\"]*)"$/ do |name, distro, release|
|
27
|
-
$test_lab.
|
27
|
+
$test_lab.containers.set_attributes(name, :distro => distro, :release => release)
|
28
28
|
end
|
29
29
|
|
30
30
|
And /^"([^\"]*)" has "([^\"]*)" architecture$/ do |name, arch|
|
31
|
-
$test_lab.
|
31
|
+
$test_lab.containers.set_attributes(name, :arch => arch)
|
32
32
|
end
|
33
33
|
|
34
34
|
And /^"([^\"]*)" should( not)? be persist[ae]nt$/ do |name, boolean|
|
35
|
-
$test_lab.
|
35
|
+
$test_lab.containers.set_attributes(name, :persist => (!boolean ? true : false))
|
36
36
|
end
|
37
37
|
|
38
38
|
And /^"([^\"]*)" has an IP address of "([^\"]*)"$/ do |name, ip|
|
39
|
-
$test_lab.
|
39
|
+
$test_lab.containers.set_attributes(name, :ip => ip)
|
40
40
|
end
|
41
41
|
|
42
42
|
And /^"([^\"]*)" has a MAC address of "([^\"]*)"$/ do |name, mac|
|
43
|
-
$test_lab.
|
43
|
+
$test_lab.containers.set_attributes(name, :mac => mac)
|
44
44
|
end
|
45
45
|
|
46
46
|
And /^"([^\"]*)" has been provisioned$/ do |name|
|
47
|
-
$test_lab.
|
47
|
+
$test_lab.containers.create(name)
|
48
48
|
end
|
49
49
|
|
50
50
|
And /^the "([^\"]*)" role has been added to the "([^\"]*)" run list$/ do |role, name|
|
51
|
-
$test_lab.
|
51
|
+
$test_lab.containers.chef_set_client_attributes(name, :run_list => ["role[#{role}]"])
|
52
52
|
end
|
53
53
|
|
54
54
|
And /^the "([^\"]*)" recipe has been added to the "([^\"]*)" run list$/ do |recipe, name|
|
55
|
-
$test_lab.
|
55
|
+
$test_lab.containers.chef_set_client_attributes(name, :run_list => ["recipe[#{recipe}]"])
|
56
56
|
end
|
57
57
|
|
58
58
|
And /^"([^\"]*)" is in the "([^\"]*)" environment$/ do |name, environment|
|
59
|
-
$test_lab.
|
59
|
+
$test_lab.containers.chef_set_client_config(:environment => environment)
|
60
60
|
end
|
61
61
|
|
62
62
|
And /^the chef-client has been run on "([^\"]*)"$/ do |name|
|
63
|
-
$test_lab.
|
64
|
-
$test_lab.drb.chef_run_client(name)
|
65
|
-
chef_client_artifacts(name)
|
63
|
+
$test_lab.containers.chef_run_client(name)
|
66
64
|
end
|