beaker 1.16.0 → 1.17.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.
- 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'
|