beaker 2.46.0 → 2.47.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 +15 -10
- data/HISTORY.md +145 -2
- data/acceptance/tests/base/dsl/helpers/host_helpers/on_test.rb +32 -0
- data/acceptance/tests/base/packages.rb +2 -2
- data/acceptance/tests/base/packages_unix.rb +1 -0
- data/beaker.gemspec +5 -1
- data/docs/Argument-Processing-and-Precedence.md +30 -38
- data/docs/Shared-Options-for-Executing-Beaker-Commands.md +6 -0
- data/docs/runner/run_in_parallel.md +62 -0
- data/lib/beaker.rb +4 -1
- data/lib/beaker/cli.rb +1 -0
- data/lib/beaker/dsl.rb +2 -2
- data/lib/beaker/dsl/helpers/host_helpers.rb +5 -3
- data/lib/beaker/dsl/helpers/puppet_helpers.rb +50 -30
- data/lib/beaker/dsl/install_utils/foss_utils.rb +14 -4
- data/lib/beaker/dsl/install_utils/module_utils.rb +1 -1
- data/lib/beaker/dsl/patterns.rb +4 -2
- data/lib/beaker/host_prebuilt_steps.rb +2 -1
- data/lib/beaker/hypervisor.rb +3 -2
- data/lib/beaker/options/presets.rb +5 -0
- data/lib/beaker/shared/host_manager.rb +15 -3
- data/lib/beaker/tasks/quick_start.rb +49 -0
- data/lib/beaker/tasks/rake_task.rb +1 -1
- data/lib/beaker/version.rb +1 -1
- data/spec/beaker/dsl/helpers/host_helpers_spec.rb +16 -0
- data/spec/beaker/dsl/helpers/puppet_helpers_spec.rb +78 -0
- data/spec/beaker/dsl/install_utils/foss_utils_spec.rb +12 -0
- data/spec/beaker/host_prebuilt_steps_spec.rb +4 -4
- data/spec/beaker/hypervisor/hypervisor_spec.rb +18 -2
- data/spec/beaker/options/presets_spec.rb +6 -0
- data/spec/beaker/shared/host_manager_spec.rb +37 -0
- metadata +54 -10
@@ -41,3 +41,9 @@ Do not output any logging for this command. Defaults to `false`.
|
|
41
41
|
Specifies standard input to be provided to the command post execution. Defaults to `nil`.
|
42
42
|
|
43
43
|
on host, "this command takes input", {:stdin => "hiya"}
|
44
|
+
|
45
|
+
## [:run_in_parallel](runner/run_in_parallel.md)
|
46
|
+
|
47
|
+
Execute the command against all hosts in parallel
|
48
|
+
|
49
|
+
on hosts, puppet( 'agent -t' ), :run_in_parallel => true
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# run_in_parallel global and command options
|
2
|
+
|
3
|
+
## run_in_parallel global option
|
4
|
+
The run_in_parallel global option is an array with the following possible values: ['configure', 'install']
|
5
|
+
It defaults to an empty array []
|
6
|
+
It can be set in an options file, or overriden by the BEAKER_RUN_IN_PARALLEL environment variable
|
7
|
+
example:
|
8
|
+
|
9
|
+
export BEAKER_RUN_IN_PARALLEL=configure,install
|
10
|
+
|
11
|
+
Including 'configure' causes timesync to execute in parallel (if timesync=true for any host)
|
12
|
+
|
13
|
+
Including 'install' causes as much of the puppet install to happen in parallel as possible.
|
14
|
+
|
15
|
+
## run_in_parallel command option
|
16
|
+
The run_in_parallel command option is a boolean value, specifying whether to execute each iteration (usually of hosts)
|
17
|
+
in parallel, or not. The block_on method is the primary method accepting the run_in_parallel command option,
|
18
|
+
however many methods that call into block_on respect it as well:
|
19
|
+
- on
|
20
|
+
- run_block_on
|
21
|
+
- block_on
|
22
|
+
- install_puppet_agent_on
|
23
|
+
- apply_manifest_on
|
24
|
+
- stop_agent_on
|
25
|
+
- execute_powershell_script_on
|
26
|
+
|
27
|
+
## Using InParallel in your test scripts
|
28
|
+
In addition to the options, you can use InParallel within your test scripts as well.
|
29
|
+
|
30
|
+
Examples:
|
31
|
+
```ruby
|
32
|
+
include InParallel
|
33
|
+
|
34
|
+
test_name('test_test')
|
35
|
+
|
36
|
+
# Example 1
|
37
|
+
hosts.each_in_parallel{ |host|
|
38
|
+
# Do something on each host
|
39
|
+
}
|
40
|
+
|
41
|
+
def some_method_call
|
42
|
+
return "some_method_call"
|
43
|
+
end
|
44
|
+
|
45
|
+
def some_method_call
|
46
|
+
return "some_other_method_call"
|
47
|
+
end
|
48
|
+
|
49
|
+
# Example 2
|
50
|
+
# Runs each method within the block in parallel in a forked process
|
51
|
+
run_in_parallel{
|
52
|
+
@result = some_method_call
|
53
|
+
@result_2 = some_other_method_call
|
54
|
+
}
|
55
|
+
|
56
|
+
# results in 'some_method_callsome_other_method_call'
|
57
|
+
puts @result + @result_2
|
58
|
+
```
|
59
|
+
|
60
|
+
**_Note:_** While you can return a result from a forked process to an instance variable, any values assigned to local variables, or other changes to global state will not persist from the child process to the parent process.
|
61
|
+
|
62
|
+
Further documentation on the usage of [InParallel](http://github/puppetlabs/in-parallel/readme.md)
|
data/lib/beaker.rb
CHANGED
data/lib/beaker/cli.rb
CHANGED
@@ -14,6 +14,7 @@ module Beaker
|
|
14
14
|
@options_parser = Beaker::Options::Parser.new
|
15
15
|
@options = @options_parser.parse_args
|
16
16
|
@logger = Beaker::Logger.new(@options)
|
17
|
+
InParallel::InParallelExecutor.logger = @logger
|
17
18
|
@options[:logger] = @logger
|
18
19
|
@options[:timestamp] = @timestamp
|
19
20
|
@options[:beaker_version] = Beaker::Version::STRING
|
data/lib/beaker/dsl.rb
CHANGED
@@ -56,8 +56,8 @@ module Beaker
|
|
56
56
|
# require 'spec_helper'
|
57
57
|
#
|
58
58
|
# describe 'A Test With RSpec' do
|
59
|
-
# let(:hosts) { Host.new('blah', 'blah', 'not helpful' }
|
60
|
-
# let(:logger) { Where.is('the', 'rspec', 'logger')
|
59
|
+
# let(:hosts) { Host.new('blah', 'blah', 'not helpful') }
|
60
|
+
# let(:logger) { Where.is('the', 'rspec', 'logger') }
|
61
61
|
#
|
62
62
|
# after do
|
63
63
|
# on master, puppet('resource mything ensure=absent')
|
@@ -24,7 +24,7 @@ module Beaker
|
|
24
24
|
# @option opts [Hash{String=>String}] :environment ({}) These will be
|
25
25
|
# treated as extra environment variables that should be set before
|
26
26
|
# running the command.
|
27
|
-
#
|
27
|
+
# @option opts [Boolean] :run_in_parallel Whether to run on each host in parallel.
|
28
28
|
|
29
29
|
# The primary method for executing commands *on* some set of hosts.
|
30
30
|
#
|
@@ -60,7 +60,7 @@ module Beaker
|
|
60
60
|
# @return [Result] An object representing the outcome of *command*.
|
61
61
|
# @raise [FailTest] Raises an exception if *command* obviously fails.
|
62
62
|
def on(host, command, opts = {}, &block)
|
63
|
-
block_on host do | host |
|
63
|
+
block_on host, opts do | host |
|
64
64
|
if command.is_a? String
|
65
65
|
cmd_opts = {}
|
66
66
|
#add any additional environment variables to the command
|
@@ -280,10 +280,12 @@ module Beaker
|
|
280
280
|
# that responds like
|
281
281
|
# {Beaker::Host#do_scp_from}.
|
282
282
|
# @param [String] powershell_script A string describing a set of powershell actions
|
283
|
+
# @param [Hash{Symbol=>String}] opts Options to alter execution.
|
284
|
+
# @option opts [Boolean] :run_in_parallel Whether to run on each host in parallel.
|
283
285
|
#
|
284
286
|
# @return [Result] Returns the result of the powershell command execution
|
285
287
|
def execute_powershell_script_on(hosts, powershell_script, opts = {})
|
286
|
-
block_on hosts do |host|
|
288
|
+
block_on hosts, opts do |host|
|
287
289
|
script_path = "beaker_powershell_script_#{Time.now.to_i}.ps1"
|
288
290
|
create_remote_file(host, script_path, powershell_script, opts)
|
289
291
|
native_path = script_path.gsub(/\//, "\\")
|
@@ -397,6 +397,7 @@ module Beaker
|
|
397
397
|
# @option opts [String] :debug (false) If this option exists,
|
398
398
|
# the "--debug" command line parameter
|
399
399
|
# will be passed to the 'puppet apply' command.
|
400
|
+
# @option opts [Boolean] :run_in_parallel Whether to run on each host in parallel.
|
400
401
|
#
|
401
402
|
# @param [Block] block This method will yield to a block of code passed
|
402
403
|
# by the caller; this can be used for additional
|
@@ -405,7 +406,7 @@ module Beaker
|
|
405
406
|
# @return [Array<Result>, Result, nil] An array of results, a result object,
|
406
407
|
# or nil. Check {#run_block_on} for more details on this.
|
407
408
|
def apply_manifest_on(host, manifest, opts = {}, &block)
|
408
|
-
block_on host do | host |
|
409
|
+
block_on host, opts do | host |
|
409
410
|
on_options = {}
|
410
411
|
on_options[:acceptable_exit_codes] = Array(opts[:acceptable_exit_codes])
|
411
412
|
|
@@ -658,12 +659,14 @@ module Beaker
|
|
658
659
|
#stops the puppet agent running on the host
|
659
660
|
# @param [Host, Array<Host>, String, Symbol] agent One or more hosts to act upon,
|
660
661
|
# or a role (String or Symbol) that identifies one or more hosts.
|
661
|
-
|
662
|
-
|
663
|
-
|
662
|
+
# @param [Hash{Symbol=>String}] opts Options to alter execution.
|
663
|
+
# @option opts [Boolean] :run_in_parallel Whether to run on each host in parallel.
|
664
|
+
def stop_agent_on(agent, opts = {})
|
665
|
+
block_on agent, opts do | host |
|
666
|
+
vardir = host.puppet_configprint['vardir']
|
664
667
|
agent_running = true
|
665
668
|
while agent_running
|
666
|
-
agent_running =
|
669
|
+
agent_running = host.file_exist?("#{vardir}/state/agent_catalog_run.lock")
|
667
670
|
if agent_running
|
668
671
|
sleep 2
|
669
672
|
end
|
@@ -671,26 +674,26 @@ module Beaker
|
|
671
674
|
|
672
675
|
# In 4.0 this was changed to just be `puppet`
|
673
676
|
agent_service = 'puppet'
|
674
|
-
if !aio_version?(
|
677
|
+
if !aio_version?(host)
|
675
678
|
# The agent service is `pe-puppet` everywhere EXCEPT certain linux distros on PE 2.8
|
676
679
|
# In all the case that it is different, this init script will exist. So we can assume
|
677
680
|
# that if the script doesn't exist, we should just use `pe-puppet`
|
678
681
|
agent_service = 'pe-puppet-agent'
|
679
|
-
agent_service = 'pe-puppet' unless
|
682
|
+
agent_service = 'pe-puppet' unless host.file_exist?('/etc/init.d/pe-puppet-agent')
|
680
683
|
end
|
681
684
|
|
682
685
|
# Under a number of stupid circumstances, we can't stop the
|
683
686
|
# agent using puppet. This is usually because of issues with
|
684
687
|
# the init script or system on that particular configuration.
|
685
688
|
avoid_puppet_at_all_costs = false
|
686
|
-
avoid_puppet_at_all_costs ||=
|
687
|
-
avoid_puppet_at_all_costs ||=
|
689
|
+
avoid_puppet_at_all_costs ||= host['platform'] =~ /el-4/
|
690
|
+
avoid_puppet_at_all_costs ||= host['pe_ver'] && version_is_less(host['pe_ver'], '3.2') && host['platform'] =~ /sles/
|
688
691
|
|
689
692
|
if avoid_puppet_at_all_costs
|
690
693
|
# When upgrading, puppet is already stopped. On EL4, this causes an exit code of '1'
|
691
|
-
on
|
694
|
+
on host, "/etc/init.d/#{agent_service} stop", :acceptable_exit_codes => [0, 1]
|
692
695
|
else
|
693
|
-
on
|
696
|
+
on host, puppet_resource('service', agent_service, 'ensure=stopped')
|
694
697
|
end
|
695
698
|
end
|
696
699
|
end
|
@@ -714,35 +717,52 @@ module Beaker
|
|
714
717
|
|
715
718
|
# Ensure the host has requested a cert, then sign it
|
716
719
|
#
|
717
|
-
# @param [Host, Array<Host>, String, Symbol] host
|
718
|
-
#
|
720
|
+
# @param [Host, Array<Host>, String, Symbol] host One or more hosts, or a role (String or Symbol)
|
721
|
+
# that identifies one or more hosts to validate certificate signing.
|
722
|
+
# No argument, or an empty array means no validation of success
|
723
|
+
# for specific hosts will be performed. This will always execute
|
724
|
+
# 'cert --sign --all --allow-dns-alt-names' even for a single host.
|
719
725
|
#
|
720
726
|
# @return nil
|
721
727
|
# @raise [FailTest] if process times out
|
722
|
-
def sign_certificate_for(host)
|
723
|
-
|
724
|
-
|
728
|
+
def sign_certificate_for(host = [])
|
729
|
+
hostnames = []
|
730
|
+
hosts = host.is_a?(Array) ? host : [host]
|
731
|
+
hosts.each{ |current_host|
|
732
|
+
if [master, dashboard, database].include? current_host
|
725
733
|
|
726
|
-
on
|
727
|
-
on master, puppet( "cert --allow-dns-alt-names sign #{
|
734
|
+
on current_host, puppet( 'agent -t' ), :acceptable_exit_codes => [0,1,2]
|
735
|
+
on master, puppet( "cert --allow-dns-alt-names sign #{current_host}" ), :acceptable_exit_codes => [0,24]
|
728
736
|
|
729
737
|
else
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
738
|
+
hostnames << Regexp.escape( current_host.node_name )
|
739
|
+
end
|
740
|
+
}
|
741
|
+
if hostnames.size < 1
|
742
|
+
on master, puppet("cert --sign --all --allow-dns-alt-names"),
|
743
|
+
:acceptable_exit_codes => [0,24]
|
744
|
+
return
|
745
|
+
end
|
746
|
+
while hostnames.size > 0
|
747
|
+
last_sleep = 0
|
748
|
+
next_sleep = 1
|
749
|
+
(0..10).each do |i|
|
750
|
+
if i == 10
|
751
|
+
fail_test("Failed to sign cert for #{hostnames}")
|
752
|
+
hostnames.clear
|
753
|
+
end
|
754
|
+
on master, puppet("cert --sign --all --allow-dns-alt-names"), :acceptable_exit_codes => [0,24]
|
755
|
+
out = on(master, puppet("cert --list --all")).stdout
|
756
|
+
if hostnames.all? { |hostname| out =~ /\+ "?#{hostname}"?/ }
|
757
|
+
hostnames.clear
|
758
|
+
break
|
742
759
|
end
|
743
760
|
|
761
|
+
sleep next_sleep
|
762
|
+
(last_sleep, next_sleep) = next_sleep, last_sleep+next_sleep
|
744
763
|
end
|
745
764
|
end
|
765
|
+
host
|
746
766
|
end
|
747
767
|
|
748
768
|
#prompt the master to sign certs then check to confirm the cert for the default host is signed
|
@@ -245,6 +245,7 @@ module Beaker
|
|
245
245
|
# @option opts [String] :puppet_agent_version Version of puppet agent to download
|
246
246
|
# @option opts [String] :mac_download_url Url to download msi pattern of %url%/puppet-%version%.msi
|
247
247
|
# @option opts [String] :win_download_url Url to download dmg pattern of %url%/(puppet|hiera|facter)-%version%.msi
|
248
|
+
# @option opts [Boolean] :run_in_parallel Whether to install on all hosts in parallel. Defaults to false.
|
248
249
|
#
|
249
250
|
# @return nil
|
250
251
|
# @raise [StandardError] When encountering an unsupported platform by default, or if gem cannot be found when default_action => 'gem_install'
|
@@ -257,9 +258,13 @@ module Beaker
|
|
257
258
|
# backwards compatability
|
258
259
|
opts[:puppet_agent_version] ||= opts[:version]
|
259
260
|
install_puppet_agent_on(hosts, opts)
|
260
|
-
|
261
261
|
else
|
262
|
-
|
262
|
+
# Use option specified in the method call, otherwise check whether the global
|
263
|
+
# run_in_parallel option includes install
|
264
|
+
run_in_parallel = opts[:run_in_parallel]
|
265
|
+
run_in_parallel = ((@options && @options[:run_in_parallel].is_a?(Array)) ?
|
266
|
+
@options[:run_in_parallel].include?('install') : false) if run_in_parallel.nil?
|
267
|
+
block_on hosts, { :run_in_parallel => run_in_parallel} do |host|
|
263
268
|
if host['platform'] =~ /el-(5|6|7)/
|
264
269
|
relver = $1
|
265
270
|
install_puppet_from_rpm_on(host, opts.merge(:release => relver, :family => 'el'))
|
@@ -325,6 +330,7 @@ module Beaker
|
|
325
330
|
# @option opts [String] :mac_download_url Url to download msi pattern of %url%/puppet-agent-%version%.msi
|
326
331
|
# @option opts [String] :win_download_url Url to download dmg pattern of %url%/puppet-agent-%version%.msi
|
327
332
|
# @option opts [String] :puppet_collection Defaults to 'pc1'
|
333
|
+
# @option opts [Boolean] :run_in_parallel Whether to run on each host in parallel.
|
328
334
|
#
|
329
335
|
# @return nil
|
330
336
|
# @raise [StandardError] When encountering an unsupported platform by default, or if gem cannot be found when default_action => 'gem_install'
|
@@ -334,7 +340,10 @@ module Beaker
|
|
334
340
|
opts[:puppet_collection] ||= 'pc1' #hi! i'm case sensitive! be careful!
|
335
341
|
opts[:puppet_agent_version] ||= opts[:version] #backwards compatability with old parameter name
|
336
342
|
|
337
|
-
|
343
|
+
run_in_parallel = opts[:run_in_parallel]
|
344
|
+
run_in_parallel = ((@options && @options[:run_in_parallel].is_a?(Array)) ?
|
345
|
+
@options[:run_in_parallel].include?('install') : false) if run_in_parallel.nil?
|
346
|
+
block_on hosts, { :run_in_parallel => run_in_parallel } do |host|
|
338
347
|
add_role(host, 'aio') #we are installing agent, so we want aio role
|
339
348
|
package_name = nil
|
340
349
|
case host['platform']
|
@@ -379,6 +388,7 @@ module Beaker
|
|
379
388
|
# @param [Hash{Symbol=>String}] opts
|
380
389
|
# @option opts [Hash{String=>String}] :main configure the main section of puppet.conf
|
381
390
|
# @option opts [Hash{String=>String}] :agent configure the agent section of puppet.conf
|
391
|
+
# @option opts [Boolean] :run_in_parallel Whether to run on each host in parallel.
|
382
392
|
#
|
383
393
|
# @example will configure /etc/puppet.conf on the puppet master.
|
384
394
|
# config = {
|
@@ -407,7 +417,7 @@ module Beaker
|
|
407
417
|
puppet_conf_text << "\n"
|
408
418
|
end
|
409
419
|
logger.debug( "setting config '#{puppet_conf_text}' on hosts #{hosts}" )
|
410
|
-
block_on hosts do |host|
|
420
|
+
block_on hosts, opts do |host|
|
411
421
|
puppet_conf_path = host.puppet['config']
|
412
422
|
create_remote_file(host, puppet_conf_path, puppet_conf_text)
|
413
423
|
end
|
@@ -16,7 +16,7 @@ module Beaker
|
|
16
16
|
# The directories in the module directory that will not be scp-ed to the test system when using
|
17
17
|
# `copy_module_to`
|
18
18
|
PUPPET_MODULE_INSTALL_IGNORE = ['.bundle', '.git', '.idea', '.vagrant', '.vendor', 'vendor', 'acceptance',
|
19
|
-
'bundle', 'spec', 'tests', 'log']
|
19
|
+
'bundle', 'spec', 'tests', 'log', '.svn', 'junit', 'pkg', 'example']
|
20
20
|
|
21
21
|
# Install the desired module on all hosts using either the PMT or a
|
22
22
|
# staging forge
|
data/lib/beaker/dsl/patterns.rb
CHANGED
@@ -17,11 +17,13 @@ module Beaker
|
|
17
17
|
# as a String that can be used to search for
|
18
18
|
# a set of Hosts, or a {Host}
|
19
19
|
# or Array<{Host}> to run the block against
|
20
|
+
# @param [Hash{Symbol=>String}] opts Options to alter execution.
|
21
|
+
# @option opts [Boolean] :run_in_parallel Whether to run on each host in parallel.
|
20
22
|
# @param [Block] block This method will yield to a block of code passed by the caller
|
21
23
|
#
|
22
24
|
# @return [Array<Result>, Result, nil] An array of results, a result object, or nil.
|
23
25
|
# Check {#run_block_on} for more details on this.
|
24
|
-
def block_on hosts_or_filter, &block
|
26
|
+
def block_on hosts_or_filter, opts={}, &block
|
25
27
|
block_hosts = nil
|
26
28
|
if defined? hosts
|
27
29
|
block_hosts = hosts
|
@@ -32,7 +34,7 @@ module Beaker
|
|
32
34
|
else
|
33
35
|
block_hosts = hosts_or_filter
|
34
36
|
end
|
35
|
-
run_block_on block_hosts, filter, &block
|
37
|
+
run_block_on block_hosts, filter, opts, &block
|
36
38
|
end
|
37
39
|
|
38
40
|
end
|
@@ -52,7 +52,7 @@ module Beaker
|
|
52
52
|
when host['platform'] =~ /sles-/
|
53
53
|
ntp_command = "sntp #{ntp_server}"
|
54
54
|
else
|
55
|
-
ntp_command = "ntpdate -t 20 #{ntp_server}"
|
55
|
+
ntp_command = "ntpdate -u -t 20 #{ntp_server}"
|
56
56
|
end
|
57
57
|
success=false
|
58
58
|
try = 0
|
@@ -71,6 +71,7 @@ module Beaker
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
end
|
74
|
+
nil
|
74
75
|
rescue => e
|
75
76
|
report_and_raise(logger, e, "timesync (--ntp)")
|
76
77
|
end
|
data/lib/beaker/hypervisor.rb
CHANGED
@@ -101,9 +101,10 @@ module Beaker
|
|
101
101
|
|
102
102
|
#Default configuration steps to be run for a given hypervisor. Any additional configuration to be done
|
103
103
|
#to the provided SUT for test execution to be successful.
|
104
|
-
def configure
|
104
|
+
def configure(opts = {})
|
105
105
|
return unless @options[:configure]
|
106
|
-
block_on @hosts
|
106
|
+
block_on @hosts, { :run_in_parallel => (@options && @options[:run_in_parallel].is_a?(Array)) ?
|
107
|
+
@options[:run_in_parallel].include?('configure') : false} do |host|
|
107
108
|
if host[:timesync]
|
108
109
|
timesync(host, @options)
|
109
110
|
end
|
@@ -36,6 +36,7 @@ module Beaker
|
|
36
36
|
:vbguest_plugin => ['BEAKER_VB_GUEST_PLUGIN', 'BEAKER_vb_guest_plugin'],
|
37
37
|
:tag_includes => ['BEAKER_TAG'],
|
38
38
|
:tag_excludes => ['BEAKER_EXCLUDE_TAG'],
|
39
|
+
:run_in_parallel => ['BEAKER_RUN_IN_PARALLEL'],
|
39
40
|
}
|
40
41
|
|
41
42
|
# Select all environment variables whose name matches provided regex
|
@@ -86,6 +87,9 @@ module Beaker
|
|
86
87
|
|
87
88
|
found_env_vars[:type] = type
|
88
89
|
end
|
90
|
+
if found_env_vars[:run_in_parallel]
|
91
|
+
found_env_vars[:run_in_parallel] = found_env_vars[:run_in_parallel].split(',')
|
92
|
+
end
|
89
93
|
|
90
94
|
found_env_vars[:pe_version_file_win] = found_env_vars[:pe_version_file]
|
91
95
|
found_env_vars
|
@@ -188,6 +192,7 @@ module Beaker
|
|
188
192
|
:nodeclassifier_port => 4433,
|
189
193
|
:cache_files_locally => true, # TODO change to false in next major version
|
190
194
|
:aws_keyname_modifier => rand(10 ** 10).to_s.rjust(10,'0'), # 10 digit random number string
|
195
|
+
:run_in_parallel => [],
|
191
196
|
:ssh => {
|
192
197
|
:config => false,
|
193
198
|
:paranoid => false,
|
@@ -72,6 +72,8 @@ module Beaker
|
|
72
72
|
#
|
73
73
|
# @param [Array<Host>, Host] hosts The host or hosts to run the provided block against
|
74
74
|
# @param [String, Symbol] filter Optional filter to apply to provided hosts - limits by name or role
|
75
|
+
# @param [Hash{Symbol=>String}] opts
|
76
|
+
# @option opts [Boolean] :run_in_parallel Whether to run on each host in parallel.
|
75
77
|
# @param [Block] block This method will yield to a block of code passed by the caller
|
76
78
|
#
|
77
79
|
# @todo (beaker3.0:BKR-571): simplify return types to Array<Result> only
|
@@ -82,7 +84,7 @@ module Beaker
|
|
82
84
|
# Else, a result object is returned. If filtering makes it such that only
|
83
85
|
# one host is left, then it's passed as a host object (not in an array),
|
84
86
|
# and thus a result object is returned.
|
85
|
-
def run_block_on hosts = [], filter = nil, &block
|
87
|
+
def run_block_on hosts = [], filter = nil, opts = {}, &block
|
86
88
|
result = nil
|
87
89
|
block_hosts = hosts #the hosts to apply the block to after any filtering
|
88
90
|
if filter
|
@@ -100,8 +102,18 @@ module Beaker
|
|
100
102
|
end
|
101
103
|
if block_hosts.is_a? Array
|
102
104
|
if block_hosts.length > 0
|
103
|
-
|
104
|
-
|
105
|
+
if opts[:run_in_parallel]
|
106
|
+
# Pass caller[1] - the line that called block_on - for logging purposes.
|
107
|
+
result = block_hosts.map.each_in_parallel(caller[1]) do |h|
|
108
|
+
run_block_on h, &block
|
109
|
+
end
|
110
|
+
hosts.each{|host| host.close}# For some reason, I have to close the SSH connection
|
111
|
+
# after spawning a process and running commands on a host,
|
112
|
+
# or else it gets into a broken state for the next call.
|
113
|
+
else
|
114
|
+
result = block_hosts.map do |h|
|
115
|
+
run_block_on h, &block
|
116
|
+
end
|
105
117
|
end
|
106
118
|
else
|
107
119
|
# there are no matching hosts to execute against
|