beaker 1.16.0 → 1.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/CONTRIBUTING.md +90 -0
- data/HISTORY.md +654 -2
- data/beaker.gemspec +1 -0
- data/lib/beaker/answers/version34.rb +4 -0
- data/lib/beaker/cli.rb +49 -2
- data/lib/beaker/dsl/helpers.rb +356 -196
- data/lib/beaker/dsl/install_utils.rb +135 -16
- data/lib/beaker/dsl/patterns.rb +37 -0
- data/lib/beaker/dsl/roles.rb +29 -0
- data/lib/beaker/dsl.rb +2 -1
- data/lib/beaker/host/unix.rb +14 -10
- data/lib/beaker/host/windows.rb +2 -0
- data/lib/beaker/host.rb +96 -1
- data/lib/beaker/host_prebuilt_steps.rb +41 -51
- data/lib/beaker/hypervisor/aws_sdk.rb +80 -16
- data/lib/beaker/hypervisor/ec2_helper.rb +1 -1
- data/lib/beaker/logger.rb +17 -0
- data/lib/beaker/options/command_line_parser.rb +3 -0
- data/lib/beaker/options/hosts_file_parser.rb +7 -4
- data/lib/beaker/options/options_hash.rb +2 -2
- data/lib/beaker/options/parser.rb +1 -1
- data/lib/beaker/options/presets.rb +128 -83
- data/lib/beaker/perf.rb +58 -0
- data/lib/beaker/shared/host_manager.rb +81 -0
- data/lib/beaker/shared.rb +2 -2
- data/lib/beaker/ssh_connection.rb +14 -7
- data/lib/beaker/test_case.rb +13 -0
- data/lib/beaker/test_suite.rb +23 -5
- data/lib/beaker/version.rb +1 -1
- data/lib/beaker.rb +1 -1
- data/spec/beaker/answers_spec.rb +13 -8
- data/spec/beaker/dsl/ezbake_utils_spec.rb +8 -9
- data/spec/beaker/dsl/helpers_spec.rb +299 -51
- data/spec/beaker/dsl/install_utils_spec.rb +75 -10
- data/spec/beaker/dsl/roles_spec.rb +36 -1
- data/spec/beaker/host_prebuilt_steps_spec.rb +21 -5
- data/spec/beaker/host_spec.rb +187 -23
- data/spec/beaker/hypervisor/ec2_helper_spec.rb +4 -4
- data/spec/beaker/hypervisor/vagrant_spec.rb +1 -1
- data/spec/beaker/options/hosts_file_parser_spec.rb +5 -0
- data/spec/beaker/options/options_hash_spec.rb +2 -2
- data/spec/beaker/options/parser_spec.rb +6 -0
- data/spec/beaker/options/presets_spec.rb +18 -2
- data/spec/beaker/perf_spec.rb +87 -0
- data/spec/beaker/shared/{host_role_parser_spec.rb → host_manager_spec.rb} +36 -5
- data/spec/beaker/test_suite_spec.rb +4 -3
- data/spec/matchers.rb +31 -3
- data/spec/mocks.rb +31 -25
- metadata +24 -5
- data/lib/beaker/shared/host_role_parser.rb +0 -36
@@ -1,16 +1,19 @@
|
|
1
|
-
[ 'command' ].each do |lib|
|
1
|
+
[ 'command', "dsl/patterns" ].each do |lib|
|
2
2
|
require "beaker/#{lib}"
|
3
3
|
end
|
4
4
|
|
5
5
|
module Beaker
|
6
6
|
#Provides convienience methods for commonly run actions on hosts
|
7
7
|
module HostPrebuiltSteps
|
8
|
+
include Beaker::DSL::Patterns
|
9
|
+
|
8
10
|
NTPSERVER = 'pool.ntp.org'
|
9
11
|
SLEEPWAIT = 5
|
10
12
|
TRIES = 5
|
11
13
|
UNIX_PACKAGES = ['curl', 'ntpdate']
|
12
14
|
WINDOWS_PACKAGES = ['curl']
|
13
15
|
SLES_PACKAGES = ['curl', 'ntp']
|
16
|
+
DEBIAN_PACKAGES = ['curl', 'ntpdate', 'lsb-release']
|
14
17
|
ETC_HOSTS_PATH = "/etc/hosts"
|
15
18
|
ETC_HOSTS_PATH_SOLARIS = "/etc/inet/hosts"
|
16
19
|
ROOT_KEYS_SCRIPT = "https://raw.githubusercontent.com/puppetlabs/puppetlabs-sshkeys/master/templates/scripts/manage_root_authorized_keys"
|
@@ -19,14 +22,12 @@ module Beaker
|
|
19
22
|
IPS_PKG_REPO="http://solaris-11-internal-repo.delivery.puppetlabs.net"
|
20
23
|
|
21
24
|
#Run timesync on the provided hosts
|
22
|
-
# @param [Host, Array<Host
|
25
|
+
# @param [Host, Array<Host>] host One or more hosts to act upon
|
23
26
|
# @param [Hash{Symbol=>String}] opts Options to alter execution.
|
24
27
|
# @option opts [Beaker::Logger] :logger A {Beaker::Logger} object
|
25
28
|
def timesync host, opts
|
26
29
|
logger = opts[:logger]
|
27
|
-
|
28
|
-
host.map { |h| timesync(h, opts) }
|
29
|
-
else
|
30
|
+
block_on host do |host|
|
30
31
|
logger.notify "Update system time sync for '#{host.name}'"
|
31
32
|
if host['platform'].include? 'windows'
|
32
33
|
# The exit code of 5 is for Windows 2008 systems where the w32tm /register command
|
@@ -68,16 +69,19 @@ module Beaker
|
|
68
69
|
|
69
70
|
#Validate that hosts are prepared to be used as SUTs, if packages are missing attempt to
|
70
71
|
#install them. Verifies the presence of #{HostPrebuiltSteps::UNIX_PACKAGES} on unix platform hosts,
|
71
|
-
#{HostPrebuiltSteps::SLES_PACKAGES} on SUSE platform hosts
|
72
|
+
#{HostPrebuiltSteps::SLES_PACKAGES} on SUSE platform hosts, #{HostPrebuiltSteps::DEBIAN_PACKAGES on debian platform
|
73
|
+
#hosts and {HostPrebuiltSteps::WINDOWS_PACKAGES} on windows
|
72
74
|
#platforms.
|
73
75
|
# @param [Host, Array<Host>, String, Symbol] host One or more hosts to act upon
|
74
76
|
# @param [Hash{Symbol=>String}] opts Options to alter execution.
|
75
77
|
# @option opts [Beaker::Logger] :logger A {Beaker::Logger} object
|
76
78
|
def validate_host host, opts
|
77
79
|
logger = opts[:logger]
|
78
|
-
if
|
79
|
-
|
80
|
-
|
80
|
+
if opts[:collect_perf_data]
|
81
|
+
UNIX_PACKAGES << "sysstat" if !UNIX_PACKAGES.include? "sysstat"
|
82
|
+
SLES_PACKAGES << "sysstat" if !SLES_PACKAGES.include? "sysstat"
|
83
|
+
end
|
84
|
+
block_on host do |host|
|
81
85
|
case
|
82
86
|
when host['platform'] =~ /sles-/
|
83
87
|
SLES_PACKAGES.each do |pkg|
|
@@ -85,13 +89,19 @@ module Beaker
|
|
85
89
|
host.install_package pkg
|
86
90
|
end
|
87
91
|
end
|
92
|
+
when host['platform'] =~ /debian/
|
93
|
+
DEBIAN_PACKAGES.each do |pkg|
|
94
|
+
if not host.check_for_package pkg
|
95
|
+
host.install_package pkg
|
96
|
+
end
|
97
|
+
end
|
88
98
|
when host['platform'] =~ /windows/
|
89
99
|
WINDOWS_PACKAGES.each do |pkg|
|
90
100
|
if not host.check_for_package pkg
|
91
101
|
host.install_package pkg
|
92
102
|
end
|
93
103
|
end
|
94
|
-
when host['platform'] !~ /aix|solaris|windows|sles-|osx-/
|
104
|
+
when host['platform'] !~ /debian|aix|solaris|windows|sles-|osx-/
|
95
105
|
UNIX_PACKAGES.each do |pkg|
|
96
106
|
if not host.check_for_package pkg
|
97
107
|
host.install_package pkg
|
@@ -106,7 +116,7 @@ module Beaker
|
|
106
116
|
#Install a set of authorized keys using {HostPrebuiltSteps::ROOT_KEYS_SCRIPT}. This is a
|
107
117
|
#convenience method to allow for easy login to hosts after they have been provisioned with
|
108
118
|
#Beaker.
|
109
|
-
# @param [Host, Array<Host
|
119
|
+
# @param [Host, Array<Host>] host One or more hosts to act upon
|
110
120
|
# @param [Hash{Symbol=>String}] opts Options to alter execution.
|
111
121
|
# @option opts [Beaker::Logger] :logger A {Beaker::Logger} object
|
112
122
|
def sync_root_keys host, opts
|
@@ -115,9 +125,7 @@ module Beaker
|
|
115
125
|
# but we're deliberately taking the approach of "assume it will work, fix it
|
116
126
|
# when reality dictates otherwise"
|
117
127
|
logger = opts[:logger]
|
118
|
-
|
119
|
-
host.map { |h| sync_root_keys(h, opts) }
|
120
|
-
else
|
128
|
+
block_on host do |host|
|
121
129
|
logger.notify "Sync root authorized_keys from github on #{host.name}"
|
122
130
|
# Allow all exit code, as this operation is unlikely to cause problems if it fails.
|
123
131
|
if host['platform'].include? 'solaris'
|
@@ -154,11 +162,9 @@ module Beaker
|
|
154
162
|
|
155
163
|
#Run 'apt-get update' on the provided host or hosts. If the platform of the provided host is not
|
156
164
|
#ubuntu or debian do nothing.
|
157
|
-
# @param [Host, Array<Host
|
158
|
-
def apt_get_update
|
159
|
-
|
160
|
-
host.map { |h| apt_get_update(h) }
|
161
|
-
else
|
165
|
+
# @param [Host, Array<Host>] hosts One or more hosts to act upon
|
166
|
+
def apt_get_update hosts
|
167
|
+
block_on hosts do |host|
|
162
168
|
if host[:platform] =~ /(ubuntu)|(debian)/
|
163
169
|
host.exec(Command.new("apt-get update"))
|
164
170
|
end
|
@@ -166,13 +172,11 @@ module Beaker
|
|
166
172
|
end
|
167
173
|
|
168
174
|
#Create a file on host or hosts at the provided file path with the provided file contents.
|
169
|
-
# @param [Host, Array<Host
|
175
|
+
# @param [Host, Array<Host>] host One or more hosts to act upon
|
170
176
|
# @param [String] file_path The path at which the new file will be created on the host or hosts.
|
171
177
|
# @param [String] file_content The contents of the file to be created on the host or hosts.
|
172
178
|
def copy_file_to_remote(host, file_path, file_content)
|
173
|
-
|
174
|
-
host.map { |h| copy_file_to_remote(h, file_path, file_contents) }
|
175
|
-
else
|
179
|
+
block_on host do |host|
|
176
180
|
Tempfile.open 'beaker' do |tempfile|
|
177
181
|
File.open(tempfile.path, 'w') {|file| file.puts file_content }
|
178
182
|
|
@@ -185,16 +189,14 @@ module Beaker
|
|
185
189
|
# proxy {HostPrebuiltSteps::APT_CFG} proxy, alter pkg on solaris-11 host or hosts
|
186
190
|
# to point to interal Puppetlabs proxy {HostPrebuiltSteps::IPS_PKG_REPO}. Do nothing
|
187
191
|
# on non-ubuntu, debian or solaris-11 platform host or hosts.
|
188
|
-
# @param [Host, Array<Host
|
192
|
+
# @param [Host, Array<Host>] host One or more hosts to act upon
|
189
193
|
# @param [Hash{Symbol=>String}] opts Options to alter execution.
|
190
194
|
# @option opts [Beaker::Logger] :logger A {Beaker::Logger} object
|
191
195
|
def proxy_config( host, opts )
|
192
196
|
# repo_proxy
|
193
197
|
# supports ubuntu, debian and solaris platforms
|
194
198
|
logger = opts[:logger]
|
195
|
-
|
196
|
-
host.map { |h| proxy_config(h, opts) }
|
197
|
-
else
|
199
|
+
block_on host do |host|
|
198
200
|
case
|
199
201
|
when host['platform'] =~ /ubuntu/
|
200
202
|
host.exec(Command.new("if test -f /etc/apt/apt.conf; then mv /etc/apt/apt.conf /etc/apt/apt.conf.bk; fi"))
|
@@ -216,7 +218,7 @@ module Beaker
|
|
216
218
|
end
|
217
219
|
|
218
220
|
#Install EPEL on host or hosts with platform = /el-(5|6)/. Do nothing on host or hosts of other platforms.
|
219
|
-
# @param [Host, Array<Host
|
221
|
+
# @param [Host, Array<Host>] host One or more hosts to act upon
|
220
222
|
# @param [Hash{Symbol=>String}] opts Options to alter execution.
|
221
223
|
# @option opts [Boolean] :debug If true, print verbose rpm information when installing EPEL
|
222
224
|
# @option opts [Beaker::Logger] :logger A {Beaker::Logger} object
|
@@ -225,9 +227,7 @@ module Beaker
|
|
225
227
|
#only supports el-* platforms
|
226
228
|
logger = opts[:logger]
|
227
229
|
debug_opt = opts[:debug] ? 'vh' : ''
|
228
|
-
|
229
|
-
host.map { |h| add_el_extras(h, opts) }
|
230
|
-
else
|
230
|
+
block_on host do |host|
|
231
231
|
case
|
232
232
|
when host['platform'] =~ /el-(5|6)/
|
233
233
|
result = host.exec(Command.new('rpm -qa | grep epel-release'), :acceptable_exit_codes => [0,1])
|
@@ -276,14 +276,12 @@ module Beaker
|
|
276
276
|
end
|
277
277
|
|
278
278
|
#Make it possible to log in as root by copying the current users ssh keys to the root account
|
279
|
-
# @param [Host, Array<Host
|
279
|
+
# @param [Host, Array<Host>] host One or more hosts to act upon
|
280
280
|
# @param [Hash{Symbol=>String}] opts Options to alter execution.
|
281
281
|
# @option opts [Beaker::Logger] :logger A {Beaker::Logger} object
|
282
282
|
def copy_ssh_to_root host, opts
|
283
283
|
logger = opts[:logger]
|
284
|
-
|
285
|
-
host.map { |h| copy_ssh_to_root(h, opts) }
|
286
|
-
else
|
284
|
+
block_on host do |host|
|
287
285
|
logger.debug "Give root a copy of current user's keys, on #{host.name}"
|
288
286
|
if host['platform'] =~ /windows/
|
289
287
|
host.exec(Command.new('cp -r .ssh /cygdrive/c/Users/Administrator/.'))
|
@@ -296,7 +294,7 @@ module Beaker
|
|
296
294
|
|
297
295
|
#Update /etc/hosts to make it possible for each provided host to reach each other host by name.
|
298
296
|
#Assumes that each provided host has host[:ip] set.
|
299
|
-
# @param [Host, Array<Host
|
297
|
+
# @param [Host, Array<Host>] hosts An array of hosts to act upon
|
300
298
|
# @param [Hash{Symbol=>String}] opts Options to alter execution.
|
301
299
|
# @option opts [Beaker::Logger] :logger A {Beaker::Logger} object
|
302
300
|
def hack_etc_hosts hosts, opts
|
@@ -310,14 +308,12 @@ module Beaker
|
|
310
308
|
end
|
311
309
|
|
312
310
|
#Update sshd_config on debian, ubuntu, centos, el, redhat and fedora boxes to allow for root login, does nothing on other platfoms
|
313
|
-
# @param [Host, Array<Host
|
311
|
+
# @param [Host, Array<Host>] host One or more hosts to act upon
|
314
312
|
# @param [Hash{Symbol=>String}] opts Options to alter execution.
|
315
313
|
# @option opts [Beaker::Logger] :logger A {Beaker::Logger} object
|
316
314
|
def enable_root_login host, opts
|
317
315
|
logger = opts[:logger]
|
318
|
-
|
319
|
-
host.map { |h| copy_ssh_to_root(h, opts) }
|
320
|
-
else
|
316
|
+
block_on host do |host|
|
321
317
|
logger.debug "Update /etc/ssh/sshd_config to allow root login"
|
322
318
|
host.exec(Command.new("sudo su -c \"sed -i 's/PermitRootLogin no/PermitRootLogin yes/' /etc/ssh/sshd_config\""), {:pty => true}
|
323
319
|
)
|
@@ -333,14 +329,12 @@ module Beaker
|
|
333
329
|
end
|
334
330
|
|
335
331
|
#Disable SELinux on centos, does nothing on other platforms
|
336
|
-
# @param [Host, Array<Host
|
332
|
+
# @param [Host, Array<Host>] host One or more hosts to act upon
|
337
333
|
# @param [Hash{Symbol=>String}] opts Options to alter execution.
|
338
334
|
# @option opts [Beaker::Logger] :logger A {Beaker::Logger} object
|
339
335
|
def disable_se_linux host, opts
|
340
336
|
logger = opts[:logger]
|
341
|
-
|
342
|
-
host.map { |h| copy_ssh_to_root(h, opts) }
|
343
|
-
else
|
337
|
+
block_on host do |host|
|
344
338
|
if host['platform'] =~ /centos|el-|redhat|fedora/
|
345
339
|
@logger.debug("Disabling se_linux on #{host.name}")
|
346
340
|
host.exec(Command.new("sudo su -c \"setenforce 0\""), {:pty => true})
|
@@ -351,14 +345,12 @@ module Beaker
|
|
351
345
|
end
|
352
346
|
|
353
347
|
#Disable iptables on centos, does nothing on other platforms
|
354
|
-
# @param [Host, Array<Host
|
348
|
+
# @param [Host, Array<Host>] host One or more hosts to act upon
|
355
349
|
# @param [Hash{Symbol=>String}] opts Options to alter execution.
|
356
350
|
# @option opts [Beaker::Logger] :logger A {Beaker::Logger} object
|
357
351
|
def disable_iptables host, opts
|
358
352
|
logger = opts[:logger]
|
359
|
-
|
360
|
-
host.map { |h| copy_ssh_to_root(h, opts) }
|
361
|
-
else
|
353
|
+
block_on host do |host|
|
362
354
|
if host['platform'] =~ /centos|el-|redhat|fedora/
|
363
355
|
logger.debug("Disabling iptables on #{host.name}")
|
364
356
|
host.exec(Command.new("sudo su -c \"/etc/init.d/iptables stop\""), {:pty => true})
|
@@ -377,9 +369,7 @@ module Beaker
|
|
377
369
|
def package_proxy host, opts
|
378
370
|
logger = opts[:logger]
|
379
371
|
|
380
|
-
|
381
|
-
host.map { |h| package_proxy(h, opts) }
|
382
|
-
else
|
372
|
+
block_on host do |host|
|
383
373
|
logger.debug("enabling proxy support on #{host.name}")
|
384
374
|
case host['platform']
|
385
375
|
when /ubuntu/, /debian/
|
@@ -10,6 +10,8 @@ module Beaker
|
|
10
10
|
# It is built for full control, to reduce any other layers beyond the pure
|
11
11
|
# vendor API.
|
12
12
|
class AwsSdk < Beaker::Hypervisor
|
13
|
+
ZOMBIE = 3 #anything older than 3 hours is considered a zombie
|
14
|
+
|
13
15
|
# Initialize AwsSdk hypervisor driver
|
14
16
|
#
|
15
17
|
# @param [Array<Beaker::Host>] hosts Array of Beaker::Host objects
|
@@ -47,6 +49,9 @@ module Beaker
|
|
47
49
|
# Wait for each node to reach status :running
|
48
50
|
wait_for_status(:running)
|
49
51
|
|
52
|
+
# Add metadata tags to each instance
|
53
|
+
add_tags()
|
54
|
+
|
50
55
|
# Grab the ip addresses and dns from EC2 for each instance to use for ssh
|
51
56
|
populate_dns()
|
52
57
|
|
@@ -83,6 +88,43 @@ module Beaker
|
|
83
88
|
nil #void
|
84
89
|
end
|
85
90
|
|
91
|
+
#Shutdown and destroy ec2 instances idenfitied by key that have been alive longer than ZOMBIE hours.
|
92
|
+
#@param [Integer] max_age The age in hours that a machine needs to be older than to be considered a zombie
|
93
|
+
#@param [String] key The key_name to match for
|
94
|
+
def kill_zombies(max_age = ZOMBIE, key = key_name)
|
95
|
+
@logger.notify("aws-sdk: Kill Zombies!")
|
96
|
+
#examine all available regions
|
97
|
+
@ec2.regions.each do |region|
|
98
|
+
@logger.debug "Reviewing: #{region.name}"
|
99
|
+
@ec2.regions[region.name].instances.each do |instance|
|
100
|
+
if (instance.key_name =~ /#{key}/) and (instance.launch_time + (ZOMBIE*60*60)) < Time.now and instance.status.to_s !~ /terminated/
|
101
|
+
@logger.debug "Kill! #{instance.id}: #{instance.key_name} (Current status: #{instance.status})"
|
102
|
+
begin
|
103
|
+
instance.terminate()
|
104
|
+
rescue AWS::EC2::Errors => e
|
105
|
+
@logger.debug "Failed to remove instance: #{instance.id}, #{e}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
# Occasionaly, tearing down ec2 instances leaves orphaned EBS volumes behind -- these stack up quickly.
|
110
|
+
# This simply looks for EBS volumes that are not in use
|
111
|
+
# Note: don't use volumes.each here as that funtion doesn't allow proper rescue from error states
|
112
|
+
volumes = @ec2.regions[region.name].volumes.map { |vol| vol.id }
|
113
|
+
volumes.each do |vol|
|
114
|
+
begin
|
115
|
+
vol = @ec2.regions[region.name].volumes[vol]
|
116
|
+
if ( vol.status.to_s =~ /available/ )
|
117
|
+
@logger.debug "Tear down available volume: #{vol.id}"
|
118
|
+
vol.delete()
|
119
|
+
end
|
120
|
+
rescue AWS::EC2::Errors::InvalidVolume::NotFound => e
|
121
|
+
@logger.debug "Failed to remove volume: #{vol.id}, #{e}"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
86
128
|
# Launch all nodes
|
87
129
|
#
|
88
130
|
# This is where the main launching work occurs for each node. Here we take
|
@@ -157,13 +199,6 @@ module Beaker
|
|
157
199
|
# manipulated by 'cleanup' for example.
|
158
200
|
host['instance'] = instance
|
159
201
|
|
160
|
-
# Define tags for the instance
|
161
|
-
@logger.notify("aws-sdk: Add tags")
|
162
|
-
instance.add_tag("jenkins_build_url", :value => @options[:jenkins_build_url])
|
163
|
-
instance.add_tag("Name", :value => host.name)
|
164
|
-
instance.add_tag("department", :value => @options[:department])
|
165
|
-
instance.add_tag("project", :value => @options[:project])
|
166
|
-
|
167
202
|
@logger.notify("aws-sdk: Launched #{host.name} (#{amitype}:#{amisize}) using snapshot/image_type #{image_type}")
|
168
203
|
end
|
169
204
|
|
@@ -198,23 +233,41 @@ module Beaker
|
|
198
233
|
backoff_sleep(tries)
|
199
234
|
end
|
200
235
|
|
201
|
-
# Set the IP to be the dns_name of the host, yes I know its not an IP.
|
202
|
-
host['ip'] = instance.dns_name
|
203
236
|
end
|
204
237
|
end
|
205
238
|
|
206
|
-
#
|
239
|
+
#Add metadata tags to all instances
|
240
|
+
#
|
241
|
+
# @return [void]
|
242
|
+
# @api private
|
243
|
+
def add_tags
|
244
|
+
@hosts.each do |host|
|
245
|
+
instance = host['instance']
|
246
|
+
|
247
|
+
# Define tags for the instance
|
248
|
+
@logger.notify("aws-sdk: Add tags for #{host.name}")
|
249
|
+
instance.add_tag("jenkins_build_url", :value => @options[:jenkins_build_url])
|
250
|
+
instance.add_tag("Name", :value => host.name)
|
251
|
+
instance.add_tag("department", :value => @options[:department])
|
252
|
+
instance.add_tag("project", :value => @options[:project])
|
253
|
+
end
|
254
|
+
|
255
|
+
nil
|
256
|
+
end
|
257
|
+
|
258
|
+
# Populate the hosts IP address from the EC2 dns_name
|
207
259
|
#
|
208
260
|
# @return [void]
|
209
261
|
# @api private
|
210
262
|
def populate_dns
|
211
263
|
# Obtain the IP addresses and dns_name for each host
|
212
264
|
@hosts.each do |host|
|
265
|
+
@logger.notify("aws-sdk: Populate DNS for #{host.name}")
|
213
266
|
instance = host['instance']
|
214
|
-
host['vmhostname'] = instance.dns_name
|
215
267
|
host['ip'] = instance.ip_address
|
216
268
|
host['private_ip'] = instance.private_ip_address
|
217
|
-
|
269
|
+
host['dns_name'] = instance.dns_name
|
270
|
+
@logger.notify("aws-sdk: name: #{host.name} ip: #{host['ip']} private_ip: #{host['private_ip']} dns_name: #{instance.dns_name}")
|
218
271
|
end
|
219
272
|
|
220
273
|
nil
|
@@ -225,10 +278,21 @@ module Beaker
|
|
225
278
|
# @return [void]
|
226
279
|
# @api private
|
227
280
|
def configure_hosts
|
228
|
-
base = "127.0.0.1\tlocalhost localhost.localdomain\n"
|
229
281
|
@hosts.each do |host|
|
230
|
-
|
231
|
-
|
282
|
+
etc_hosts = "127.0.0.1\tlocalhost localhost.localdomain\n"
|
283
|
+
name = host.name
|
284
|
+
domain = get_domain_name(host)
|
285
|
+
ip = host['private_ip']
|
286
|
+
etc_hosts += "#{ip}\t#{name} #{name}.#{domain} #{host['dns_name']}\n"
|
287
|
+
@hosts.each do |neighbor|
|
288
|
+
if neighbor == host
|
289
|
+
next
|
290
|
+
end
|
291
|
+
name = neighbor.name
|
292
|
+
domain = get_domain_name(neighbor)
|
293
|
+
ip = neighbor['ip']
|
294
|
+
etc_hosts += "#{ip}\t#{name} #{name}.#{domain} #{neighbor['dns_name']}\n"
|
295
|
+
end
|
232
296
|
set_etc_hosts(host, etc_hosts)
|
233
297
|
end
|
234
298
|
end
|
@@ -240,7 +304,7 @@ module Beaker
|
|
240
304
|
# @api private
|
241
305
|
def set_hostnames
|
242
306
|
@hosts.each do |host|
|
243
|
-
host.exec(Command.new("hostname #{host
|
307
|
+
host.exec(Command.new("hostname #{host.name}"))
|
244
308
|
end
|
245
309
|
end
|
246
310
|
|
data/lib/beaker/logger.rb
CHANGED
@@ -4,6 +4,10 @@ module Beaker
|
|
4
4
|
# to a given destination (be it a string or file)
|
5
5
|
#
|
6
6
|
class Logger
|
7
|
+
|
8
|
+
#The results of the most recently run command
|
9
|
+
attr_accessor :last_result
|
10
|
+
|
7
11
|
NORMAL = "\e[00;00m"
|
8
12
|
BRIGHT_NORMAL = "\e[00;01m"
|
9
13
|
BLACK = "\e[00;30m"
|
@@ -65,6 +69,9 @@ module Beaker
|
|
65
69
|
else
|
66
70
|
@log_level = :verbose
|
67
71
|
end
|
72
|
+
|
73
|
+
@last_result = nil
|
74
|
+
|
68
75
|
@destinations = []
|
69
76
|
|
70
77
|
dests = args
|
@@ -164,6 +171,16 @@ module Beaker
|
|
164
171
|
optionally_color GREY, string, false
|
165
172
|
end
|
166
173
|
|
174
|
+
# Custom reporting for performance/sysstat messages
|
175
|
+
# Will not print unless we are at {LOG_LEVELS} 'debug' or higher.
|
176
|
+
# @param args[Array<String>] Strings to be reported
|
177
|
+
def perf_output *args
|
178
|
+
return unless is_debug?
|
179
|
+
strings = strip_colors_from args
|
180
|
+
string = strings.join
|
181
|
+
optionally_color MAGENTA, string, false
|
182
|
+
end
|
183
|
+
|
167
184
|
# Report a debug message.
|
168
185
|
# Will not print unless we are at {LOG_LEVELS} 'debug' or higher.
|
169
186
|
# @param args[Array<String>] Strings to be reported
|
@@ -12,12 +12,16 @@ module Beaker
|
|
12
12
|
#
|
13
13
|
# @return [OptionsHash] The contents of the hosts file as an OptionsHash
|
14
14
|
# @raise [ArgumentError] Raises if hosts_file_path is not a path to a file, or is not a valid YAML file
|
15
|
-
def self.parse_hosts_file(hosts_file_path)
|
15
|
+
def self.parse_hosts_file(hosts_file_path = nil)
|
16
|
+
host_options = Beaker::Options::OptionsHash.new
|
17
|
+
host_options['HOSTS'] ||= {}
|
18
|
+
unless hosts_file_path
|
19
|
+
return host_options
|
20
|
+
end
|
16
21
|
hosts_file_path = File.expand_path(hosts_file_path)
|
17
22
|
unless File.exists?(hosts_file_path)
|
18
|
-
raise ArgumentError, "
|
23
|
+
raise ArgumentError, "Host file '#{hosts_file_path}' does not exist!"
|
19
24
|
end
|
20
|
-
host_options = Beaker::Options::OptionsHash.new
|
21
25
|
begin
|
22
26
|
host_options = host_options.merge(YAML.load_file(hosts_file_path))
|
23
27
|
rescue Psych::SyntaxError => e
|
@@ -25,7 +29,6 @@ module Beaker
|
|
25
29
|
end
|
26
30
|
|
27
31
|
# Make sure the roles array is present for all hosts
|
28
|
-
host_options['HOSTS'] ||= {}
|
29
32
|
host_options['HOSTS'].each_key do |host|
|
30
33
|
host_options['HOSTS'][host]['roles'] ||= []
|
31
34
|
end
|
@@ -42,7 +42,7 @@ module Beaker
|
|
42
42
|
|
43
43
|
# Determine if type of ObjectHash is pe, defaults to true
|
44
44
|
#
|
45
|
-
# @example Use this method to
|
45
|
+
# @example Use this method to test if the :type setting is pe
|
46
46
|
# a['type'] = 'pe'
|
47
47
|
# a.is_pe? == true
|
48
48
|
#
|
@@ -98,7 +98,7 @@ module Beaker
|
|
98
98
|
def rmerge base, hash
|
99
99
|
return base unless hash.is_a?(Hash) || hash.is_a?(OptionsHash)
|
100
100
|
hash.each do |key, v|
|
101
|
-
if (base[key].is_a?(Hash) || base[key].is_a?(OptionsHash)) && (hash[key].is_a?(Hash) ||
|
101
|
+
if (base[key].is_a?(Hash) || base[key].is_a?(OptionsHash)) && (hash[key].is_a?(Hash) || hash[key].is_a?(OptionsHash))
|
102
102
|
rmerge(base[key], hash[key])
|
103
103
|
elsif hash[key].is_a?(Hash)
|
104
104
|
base[key] = OptionsHash.new.merge(hash[key])
|
@@ -149,7 +149,7 @@ module Beaker
|
|
149
149
|
if not master.empty? and master.length == 1
|
150
150
|
default_host_name = master[0]
|
151
151
|
elsif hosts.length == 1
|
152
|
-
default_host_name = hosts
|
152
|
+
default_host_name = hosts.keys[0]
|
153
153
|
end
|
154
154
|
if default_host_name
|
155
155
|
hosts[default_host_name][:roles] << 'default'
|