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.
Files changed (51) hide show
  1. checksums.yaml +8 -8
  2. data/CONTRIBUTING.md +90 -0
  3. data/HISTORY.md +654 -2
  4. data/beaker.gemspec +1 -0
  5. data/lib/beaker/answers/version34.rb +4 -0
  6. data/lib/beaker/cli.rb +49 -2
  7. data/lib/beaker/dsl/helpers.rb +356 -196
  8. data/lib/beaker/dsl/install_utils.rb +135 -16
  9. data/lib/beaker/dsl/patterns.rb +37 -0
  10. data/lib/beaker/dsl/roles.rb +29 -0
  11. data/lib/beaker/dsl.rb +2 -1
  12. data/lib/beaker/host/unix.rb +14 -10
  13. data/lib/beaker/host/windows.rb +2 -0
  14. data/lib/beaker/host.rb +96 -1
  15. data/lib/beaker/host_prebuilt_steps.rb +41 -51
  16. data/lib/beaker/hypervisor/aws_sdk.rb +80 -16
  17. data/lib/beaker/hypervisor/ec2_helper.rb +1 -1
  18. data/lib/beaker/logger.rb +17 -0
  19. data/lib/beaker/options/command_line_parser.rb +3 -0
  20. data/lib/beaker/options/hosts_file_parser.rb +7 -4
  21. data/lib/beaker/options/options_hash.rb +2 -2
  22. data/lib/beaker/options/parser.rb +1 -1
  23. data/lib/beaker/options/presets.rb +128 -83
  24. data/lib/beaker/perf.rb +58 -0
  25. data/lib/beaker/shared/host_manager.rb +81 -0
  26. data/lib/beaker/shared.rb +2 -2
  27. data/lib/beaker/ssh_connection.rb +14 -7
  28. data/lib/beaker/test_case.rb +13 -0
  29. data/lib/beaker/test_suite.rb +23 -5
  30. data/lib/beaker/version.rb +1 -1
  31. data/lib/beaker.rb +1 -1
  32. data/spec/beaker/answers_spec.rb +13 -8
  33. data/spec/beaker/dsl/ezbake_utils_spec.rb +8 -9
  34. data/spec/beaker/dsl/helpers_spec.rb +299 -51
  35. data/spec/beaker/dsl/install_utils_spec.rb +75 -10
  36. data/spec/beaker/dsl/roles_spec.rb +36 -1
  37. data/spec/beaker/host_prebuilt_steps_spec.rb +21 -5
  38. data/spec/beaker/host_spec.rb +187 -23
  39. data/spec/beaker/hypervisor/ec2_helper_spec.rb +4 -4
  40. data/spec/beaker/hypervisor/vagrant_spec.rb +1 -1
  41. data/spec/beaker/options/hosts_file_parser_spec.rb +5 -0
  42. data/spec/beaker/options/options_hash_spec.rb +2 -2
  43. data/spec/beaker/options/parser_spec.rb +6 -0
  44. data/spec/beaker/options/presets_spec.rb +18 -2
  45. data/spec/beaker/perf_spec.rb +87 -0
  46. data/spec/beaker/shared/{host_role_parser_spec.rb → host_manager_spec.rb} +36 -5
  47. data/spec/beaker/test_suite_spec.rb +4 -3
  48. data/spec/matchers.rb +31 -3
  49. data/spec/mocks.rb +31 -25
  50. metadata +24 -5
  51. 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>, String, Symbol] host One or more hosts to act upon
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
- if host.is_a? Array
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 and {HostPrebuiltSteps::WINDOWS_PACKAGES} on windows
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 host.is_a? Array
79
- host.map { |h| validate_host(h, opts) }
80
- else
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>, String, Symbol] host One or more hosts to act upon
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
- if host.is_a? Array
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>, String, Symbol] host One or more hosts to act upon
158
- def apt_get_update host
159
- if host.is_a? Array
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>, String, Symbol] host One or more hosts to act upon
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
- if host.is_a? Array
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>, String, Symbol] host One or more hosts to act upon
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
- if host.is_a? Array
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>, String, Symbol] host One or more hosts to act upon
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
- if host.is_a? Array
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>, String, Symbol] host One or more hosts to act upon
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
- if host.is_a? Array
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>, String, Symbol] hosts An array of hosts to act upon
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>, String, Symbol] host One or more hosts to act upon
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
- if host.is_a? Array
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>, String, Symbol] host One or more hosts to act upon
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
- if host.is_a? Array
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>, String, Symbol] host One or more hosts to act upon
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
- if host.is_a? Array
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
- if host.is_a? Array
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
- # Populate the hosts IP address and vmhostname entry from the EC2 dns_name
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
- @logger.notify("aws-sdk: name: #{host.name} vmhostname: #{host['vmhostname']} ip: #{host['ip']} private_ip: #{host['private_ip']}")
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
- hn = host.hostname
231
- etc_hosts = base + "#{host['private_ip']}\t#{hn} #{hn.split(".")[0]}\n"
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['vmhostname']}"))
307
+ host.exec(Command.new("hostname #{host.name}"))
244
308
  end
245
309
  end
246
310
 
@@ -7,7 +7,7 @@ module Beaker
7
7
  # @return [Array<Number>] array of port numbers
8
8
  # @api private
9
9
  def self.amiports(roles)
10
- ports = [22]
10
+ ports = [22, 61613, 8139]
11
11
 
12
12
  if roles.include? 'database'
13
13
  ports << 8080
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
@@ -201,6 +201,9 @@ module Beaker
201
201
  #noop
202
202
  end
203
203
 
204
+ opts.on '--collect-perf-data', 'Use sysstat on linux hosts to collect performance and load data' do
205
+ @cmd_options[:collect_perf_data] = true
206
+ end
204
207
  end
205
208
 
206
209
  end
@@ -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, "Required host file '#{hosts_file_path}' does not exist!"
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 return the value for a given key
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) || has[key].is_a?(OptionsHash))
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[0].keys[0]
152
+ default_host_name = hosts.keys[0]
153
153
  end
154
154
  if default_host_name
155
155
  hosts[default_host_name][:roles] << 'default'