beaker 2.18.3 → 2.19.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/HISTORY.md +439 -2
- data/acceptance/lib/beaker/acceptance/install_utils.rb +58 -0
- data/acceptance/pre_suite/puppet_git/install.rb +6 -65
- data/acceptance/tests/foss_utils/clone_git_repo_on.rb +49 -0
- data/beaker.gemspec +2 -0
- data/lib/beaker/dsl/helpers/web_helpers.rb +2 -1
- data/lib/beaker/dsl/install_utils/aio_defaults.rb +0 -2
- data/lib/beaker/dsl/install_utils/foss_utils.rb +97 -60
- data/lib/beaker/dsl/install_utils/pe_utils.rb +30 -53
- data/lib/beaker/dsl/install_utils/puppet_utils.rb +43 -0
- data/lib/beaker/dsl/install_utils/windows_utils.rb +144 -0
- data/lib/beaker/dsl/roles.rb +20 -3
- data/lib/beaker/dsl/structure.rb +14 -3
- data/lib/beaker/host.rb +24 -3
- data/lib/beaker/host/unix/pkg.rb +9 -0
- data/lib/beaker/host/windows/exec.rb +3 -0
- data/lib/beaker/host_prebuilt_steps.rb +5 -9
- data/lib/beaker/hypervisor/aws_sdk.rb +22 -18
- data/lib/beaker/hypervisor/docker.rb +7 -0
- data/lib/beaker/hypervisor/vmpooler.rb +4 -0
- data/lib/beaker/logger.rb +12 -1
- data/lib/beaker/options/command_line_parser.rb +9 -0
- data/lib/beaker/options/options_hash.rb +3 -296
- data/lib/beaker/options/parser.rb +12 -0
- data/lib/beaker/options/presets.rb +0 -1
- data/lib/beaker/ssh_connection.rb +48 -23
- data/lib/beaker/test_case.rb +1 -1
- data/lib/beaker/version.rb +1 -1
- data/spec/beaker/dsl/helpers/web_helpers_spec.rb +10 -1
- data/spec/beaker/dsl/install_utils/foss_utils_spec.rb +194 -49
- data/spec/beaker/dsl/install_utils/pe_utils_spec.rb +112 -22
- data/spec/beaker/dsl/install_utils/puppet_utils_spec.rb +57 -0
- data/spec/beaker/dsl/install_utils/windows_utils_spec.rb +132 -0
- data/spec/beaker/dsl/roles_spec.rb +36 -5
- data/spec/beaker/dsl/structure_spec.rb +9 -2
- data/spec/beaker/host/unix/pkg_spec.rb +26 -6
- data/spec/beaker/host_prebuilt_steps_spec.rb +3 -2
- data/spec/beaker/host_spec.rb +18 -0
- data/spec/beaker/hypervisor/aixer_spec.rb +1 -1
- data/spec/beaker/hypervisor/aws_sdk_spec.rb +595 -58
- data/spec/beaker/hypervisor/docker_spec.rb +2 -1
- data/spec/beaker/hypervisor/solaris_spec.rb +1 -0
- data/spec/beaker/hypervisor/vagrant_spec.rb +2 -1
- data/spec/beaker/logger_spec.rb +39 -0
- data/spec/beaker/options/command_line_parser_spec.rb +2 -2
- data/spec/beaker/options/options_hash_spec.rb +1 -102
- data/spec/beaker/options/parser_spec.rb +19 -0
- data/spec/beaker/options/pe_version_scaper_spec.rb +11 -1
- data/spec/beaker/options/presets_spec.rb +8 -0
- data/spec/beaker/ssh_connection_spec.rb +39 -21
- data/spec/helpers.rb +9 -3
- data/spec/mocks.rb +2 -0
- metadata +34 -11
- data/lib/beaker/answers.rb +0 -143
- data/lib/beaker/answers/version20.rb +0 -120
- data/lib/beaker/answers/version28.rb +0 -121
- data/lib/beaker/answers/version30.rb +0 -227
- data/lib/beaker/answers/version32.rb +0 -44
- data/lib/beaker/answers/version34.rb +0 -51
- data/lib/beaker/answers/version38.rb +0 -29
- data/lib/beaker/answers/version40.rb +0 -44
- data/spec/beaker/answers_spec.rb +0 -547
@@ -1,6 +1,7 @@
|
|
1
|
-
[ 'aio_defaults', 'pe_defaults', 'puppet_utils' ].each do |lib|
|
1
|
+
[ 'aio_defaults', 'pe_defaults', 'puppet_utils', 'windows_utils' ].each do |lib|
|
2
2
|
require "beaker/dsl/install_utils/#{lib}"
|
3
3
|
end
|
4
|
+
require "beaker-answers"
|
4
5
|
module Beaker
|
5
6
|
module DSL
|
6
7
|
module InstallUtils
|
@@ -18,26 +19,7 @@ module Beaker
|
|
18
19
|
include AIODefaults
|
19
20
|
include PEDefaults
|
20
21
|
include PuppetUtils
|
21
|
-
|
22
|
-
# Set defaults and PATH for these hosts to be either pe or aio, have host['type'] == aio for aio settings, defaults
|
23
|
-
# to pe.
|
24
|
-
#
|
25
|
-
# @param [Host, Array<Host>, String, Symbol] hosts One or more hosts to act upon,
|
26
|
-
# or a role (String or Symbol) that identifies one or more hosts.
|
27
|
-
def configure_pe_defaults_on( hosts )
|
28
|
-
block_on hosts do |host|
|
29
|
-
if host[:pe_ver] && aio_version?(host) or (host['type'] && host['type'] =~ /aio/)
|
30
|
-
add_aio_defaults_on(host)
|
31
|
-
# provide a sane default here for puppetservice
|
32
|
-
host['puppetservice'] ||= 'pe-puppetserver'
|
33
|
-
else
|
34
|
-
add_pe_defaults_on(host)
|
35
|
-
end
|
36
|
-
# add pathing env
|
37
|
-
add_puppet_paths_on(host)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
22
|
+
include WindowsUtils
|
41
23
|
|
42
24
|
# @!macro [new] common_opts
|
43
25
|
# @param [Hash{Symbol=>String}] opts Options to alter execution.
|
@@ -60,6 +42,7 @@ module Beaker
|
|
60
42
|
# running the command.
|
61
43
|
|
62
44
|
#Sort array of hosts so that it has the correct order for PE installation based upon each host's role
|
45
|
+
#@param subset [Array<Host>] An array of hosts to sort, defaults to global 'hosts' object
|
63
46
|
# @example
|
64
47
|
# h = sorted_hosts
|
65
48
|
#
|
@@ -70,12 +53,13 @@ module Beaker
|
|
70
53
|
# Fourth: everything else
|
71
54
|
#
|
72
55
|
# @!visibility private
|
73
|
-
def sorted_hosts
|
56
|
+
def sorted_hosts subset = hosts
|
74
57
|
special_nodes = []
|
75
58
|
[master, database, dashboard].uniq.each do |host|
|
76
|
-
special_nodes << host if host != nil
|
59
|
+
special_nodes << host if host != nil && subset.include?(host)
|
77
60
|
end
|
78
61
|
real_agents = agents - special_nodes
|
62
|
+
real_agents = real_agents.delete_if{ |host| !subset.include?(host) }
|
79
63
|
special_nodes + real_agents
|
80
64
|
end
|
81
65
|
|
@@ -83,8 +67,6 @@ module Beaker
|
|
83
67
|
# @param [Host] host The host that PE is to be installed on
|
84
68
|
# For UNIX machines using the full PE installer, the host object must have the 'pe_installer' field set correctly.
|
85
69
|
# @param [Hash{Symbol=>String}] opts The options
|
86
|
-
# @option opts [String] :pe_ver_win Default PE version to install or upgrade to on Windows hosts
|
87
|
-
# (Othersie uses individual Windows hosts pe_ver)
|
88
70
|
# @option opts [String] :pe_ver Default PE version to install or upgrade to
|
89
71
|
# (Otherwise uses individual hosts pe_ver)
|
90
72
|
# @option opts [Boolean] :pe_debug (false) Should we run the installer in debug mode?
|
@@ -93,16 +75,9 @@ module Beaker
|
|
93
75
|
# @api private
|
94
76
|
def installer_cmd(host, opts)
|
95
77
|
version = host['pe_ver'] || opts[:pe_ver]
|
96
|
-
if host['platform'] =~ /windows/
|
97
|
-
log_file = "#{File.basename(host['working_dir'])}.log"
|
98
|
-
# cat may not be available with strictly Windows environments
|
99
|
-
# Prefer `type` as an alternative to `cat` if non-cygwin
|
100
|
-
win_cat = host.is_cygwin? ? "cat" : "type"
|
101
|
-
pe_debug = host[:pe_debug] || opts[:pe_debug] ? " && #{win_cat} #{log_file}" : ''
|
102
|
-
"cd #{host['working_dir']} && cmd /C 'start /w msiexec.exe /qn /L*V #{log_file} /i #{host['dist']}.msi PUPPET_MASTER_SERVER=#{master} PUPPET_AGENT_CERTNAME=#{host}'#{pe_debug}"
|
103
78
|
# Frictionless install didn't exist pre-3.2.0, so in that case we fall
|
104
79
|
# through and do a regular install.
|
105
|
-
|
80
|
+
if host['roles'].include? 'frictionless' and ! version_is_less(version, '3.2.0')
|
106
81
|
# PE 3.4 introduced the ability to pass in config options to the bash script in the form
|
107
82
|
# of <section>:<key>=<value>
|
108
83
|
frictionless_install_opts = []
|
@@ -419,14 +394,18 @@ module Beaker
|
|
419
394
|
:puppet_agent_sha => host[:puppet_agent_sha] || opts[:puppet_agent_sha],
|
420
395
|
:pe_ver => host[:pe_ver] || opts[:pe_ver],
|
421
396
|
:puppet_collection => host[:puppet_collection] || opts[:puppet_collection] })
|
422
|
-
|
397
|
+
# 1 since no certificate found and waitforcert disabled
|
398
|
+
acceptable_exit_codes = [0, 1]
|
399
|
+
acceptable_exit_codes << 2 if opts[:type] == :upgrade
|
400
|
+
setup_defaults_and_config_helper_on(host, master, acceptable_exit_codes)
|
423
401
|
elsif host['platform'] =~ /windows/
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
402
|
+
opts = { :debug => host[:pe_debug] || opts[:pe_debug] }
|
403
|
+
msi_path = "#{host['working_dir']}\\#{host['dist']}.msi"
|
404
|
+
install_msi_on(host, msi_path, {}, opts)
|
405
|
+
|
406
|
+
# 1 since no certificate found and waitforcert disabled
|
407
|
+
acceptable_exit_codes = 1
|
408
|
+
setup_defaults_and_config_helper_on(host, master, acceptable_exit_codes)
|
430
409
|
else
|
431
410
|
# We only need answers if we're using the classic installer
|
432
411
|
version = host['pe_ver'] || opts[:pe_ver]
|
@@ -437,17 +416,17 @@ module Beaker
|
|
437
416
|
deploy_frictionless_to_master(host)
|
438
417
|
end
|
439
418
|
on host, installer_cmd(host, opts)
|
440
|
-
|
419
|
+
configure_type_defaults_on(host)
|
441
420
|
elsif host['platform'] =~ /osx|eos/
|
442
421
|
# If we're not frictionless, we need to run the OSX special-case
|
443
422
|
on host, installer_cmd(host, opts)
|
444
423
|
acceptable_codes = host['platform'] =~ /osx/ ? [1] : [0, 1]
|
445
424
|
setup_defaults_and_config_helper_on(host, master, acceptable_codes)
|
446
425
|
else
|
447
|
-
answers =
|
426
|
+
answers = BeakerAnswers::Answers.create(opts[:pe_ver] || host['pe_ver'], hosts, opts)
|
448
427
|
create_remote_file host, "#{host['working_dir']}/answers", answers.answer_string(host)
|
449
428
|
on host, installer_cmd(host, opts)
|
450
|
-
|
429
|
+
configure_type_defaults_on(host)
|
451
430
|
end
|
452
431
|
end
|
453
432
|
|
@@ -535,7 +514,7 @@ module Beaker
|
|
535
514
|
# @return nil
|
536
515
|
# @api private
|
537
516
|
def setup_defaults_and_config_helper_on(host, master, acceptable_exit_codes=nil)
|
538
|
-
|
517
|
+
configure_type_defaults_on(host)
|
539
518
|
#set the certname and master
|
540
519
|
on host, puppet("config set server #{master}")
|
541
520
|
on host, puppet("config set certname #{host}")
|
@@ -551,8 +530,7 @@ module Beaker
|
|
551
530
|
|
552
531
|
#Install PE based upon host configuration and options
|
553
532
|
#
|
554
|
-
# @param [Host, Array<Host
|
555
|
-
# or a role (String or Symbol) that identifies one or more hosts.
|
533
|
+
# @param [Host, Array<Host>] install_hosts One or more hosts to act upon
|
556
534
|
# @!macro common_opts
|
557
535
|
# @option opts [Boolean] :masterless Are we performing a masterless installation?
|
558
536
|
# @option opts [String] :puppet_agent_version Version of puppet-agent to install. Required for PE agent
|
@@ -569,10 +547,10 @@ module Beaker
|
|
569
547
|
# Install file names are assumed to be of the format puppet-enterprise-VERSION-PLATFORM.(tar)|(tar.gz)
|
570
548
|
# for Unix like systems and puppet-enterprise-VERSION.msi for Windows systems.
|
571
549
|
#
|
572
|
-
def install_pe_on(
|
573
|
-
|
574
|
-
confine_block(:to, {}, hosts) do
|
550
|
+
def install_pe_on(install_hosts, opts)
|
551
|
+
confine_block(:to, {}, install_hosts) do
|
575
552
|
sorted_hosts.each do |host|
|
553
|
+
#process the version files if necessary
|
576
554
|
host['pe_dir'] ||= opts[:pe_dir]
|
577
555
|
if host['platform'] =~ /windows/
|
578
556
|
# we don't need the pe_version if:
|
@@ -598,8 +576,7 @@ module Beaker
|
|
598
576
|
end
|
599
577
|
|
600
578
|
#Upgrade PE based upon host configuration and options
|
601
|
-
# @param [Host, Array<Host
|
602
|
-
# or a role (String or Symbol) that identifies one or more hosts.
|
579
|
+
# @param [Host, Array<Host>] upgrade_hosts One or more hosts to act upon
|
603
580
|
# @!macro common_opts
|
604
581
|
# @param [String] path A path (either local directory or a URL to a listing of PE builds).
|
605
582
|
# Will contain a LATEST file indicating the latest build to install.
|
@@ -610,8 +587,8 @@ module Beaker
|
|
610
587
|
#
|
611
588
|
# @note Install file names are assumed to be of the format puppet-enterprise-VERSION-PLATFORM.(tar)|(tar.gz)
|
612
589
|
# for Unix like systems and puppet-enterprise-VERSION.msi for Windows systems.
|
613
|
-
def upgrade_pe_on
|
614
|
-
confine_block(:to, {},
|
590
|
+
def upgrade_pe_on upgrade_hosts, opts, path=nil
|
591
|
+
confine_block(:to, {}, upgrade_hosts) do
|
615
592
|
set_console_password = false
|
616
593
|
# if we are upgrading from something lower than 3.4 then we need to set the pe console password
|
617
594
|
if (dashboard[:pe_ver] ? version_is_less(dashboard[:pe_ver], "3.4.0") : true)
|
@@ -65,6 +65,46 @@ module Beaker
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
+
# Configure the provided hosts to be of their host[:type], it host[type] == nil do nothing
|
69
|
+
def configure_type_defaults_on( hosts )
|
70
|
+
block_on hosts do |host|
|
71
|
+
has_defaults = false
|
72
|
+
if host[:type]
|
73
|
+
host_type = host[:type]
|
74
|
+
# clean up the naming conventions here (some teams use foss-package, git-whatever, we need
|
75
|
+
# to correctly handle that
|
76
|
+
# don't worry about aio, that happens in the aio_version? check
|
77
|
+
host_type = case host_type
|
78
|
+
when /(\A|-)(git)|(foss)(\Z|-)/
|
79
|
+
'foss'
|
80
|
+
when /(\A|-)pe(\Z|-)/
|
81
|
+
'pe'
|
82
|
+
else
|
83
|
+
nil
|
84
|
+
end
|
85
|
+
if host_type
|
86
|
+
add_method = "add_#{host_type}_defaults_on"
|
87
|
+
if self.respond_to?(add_method, host)
|
88
|
+
self.send(add_method, host)
|
89
|
+
else
|
90
|
+
raise "cannot add defaults of type #{host_type} for host #{host.name} (#{add_method} not present)"
|
91
|
+
end
|
92
|
+
has_defaults = true
|
93
|
+
end
|
94
|
+
end
|
95
|
+
if aio_version?(host)
|
96
|
+
add_aio_defaults_on(host)
|
97
|
+
has_defaults = true
|
98
|
+
end
|
99
|
+
# add pathing env
|
100
|
+
if has_defaults
|
101
|
+
add_puppet_paths_on(host)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
alias_method :configure_foss_defaults_on, :configure_type_defaults_on
|
106
|
+
alias_method :configure_pe_defaults_on, :configure_type_defaults_on
|
107
|
+
|
68
108
|
#If the host is associated with a type remove all defaults and environment associated with that type.
|
69
109
|
# @param [Host, Array<Host>, String, Symbol] hosts One or more hosts to act upon,
|
70
110
|
# or a role (String or Symbol) that identifies one or more hosts.
|
@@ -78,6 +118,9 @@ module Beaker
|
|
78
118
|
else
|
79
119
|
raise "cannot remove defaults of type #{host['type']} associated with host #{host.name} (#{remove_method} not present)"
|
80
120
|
end
|
121
|
+
if aio_version?(host)
|
122
|
+
remove_aio_defaults_on(host)
|
123
|
+
end
|
81
124
|
end
|
82
125
|
end
|
83
126
|
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
module Beaker
|
2
|
+
module DSL
|
3
|
+
module InstallUtils
|
4
|
+
#
|
5
|
+
# This module contains methods useful for Windows installs
|
6
|
+
#
|
7
|
+
module WindowsUtils
|
8
|
+
|
9
|
+
# Given a host, returns it's system TEMP path
|
10
|
+
# @param [Host] host An object implementing {Beaker::Hosts}'s interface.
|
11
|
+
def get_temp_path(host)
|
12
|
+
# under CYGWIN %TEMP% may not be set
|
13
|
+
tmp_path = on(host, Command.new('ECHO %SYSTEMROOT%', [], { :cmdexe => true }))
|
14
|
+
tmp_path.output.gsub(/\n/, '') + '\\TEMP'
|
15
|
+
end
|
16
|
+
|
17
|
+
# Generates commands to be inserted into a Windows batch file to launch an MSI install
|
18
|
+
# @param [String] msi_path The path of the MSI - can be a local Windows style file path like
|
19
|
+
# c:\temp\puppet.msi OR a url like https://download.com/puppet.msi or file://c:\temp\puppet.msi
|
20
|
+
# @param [Hash{String=>String}] msi_opts MSI installer options
|
21
|
+
# See https://docs.puppetlabs.com/guides/install_puppet/install_windows.html#msi-properties
|
22
|
+
# @param [String] log_path The path to write the MSI log - must be a local Windows style file path
|
23
|
+
#
|
24
|
+
# @api private
|
25
|
+
def msi_install_script(msi_path, msi_opts, log_path)
|
26
|
+
# msiexec requires backslashes in file paths launched under cmd.exe start /w
|
27
|
+
url_pattern = /^(https?|file):\/\//
|
28
|
+
msi_path = msi_path.gsub(/\//, "\\") if msi_path !~ url_pattern
|
29
|
+
|
30
|
+
msi_params = msi_opts.map{|k, v| "#{k}=#{v}"}.join(' ')
|
31
|
+
|
32
|
+
# msiexec requires quotes around paths with backslashes - c:\ or file://c:\
|
33
|
+
# not strictly needed for http:// but it simplifies this code
|
34
|
+
batch_contents = <<-BATCH
|
35
|
+
start /w msiexec.exe /i \"#{msi_path}\" /qn /L*V #{log_path} #{msi_params}
|
36
|
+
exit /B %errorlevel%
|
37
|
+
BATCH
|
38
|
+
end
|
39
|
+
|
40
|
+
# Given a host, path to MSI and MSI options, will create a batch file
|
41
|
+
# on the host, returning the path to the randomized batch file and
|
42
|
+
# the randomized log file
|
43
|
+
# @param [Host] host An object implementing {Beaker::Hosts}'s interface.
|
44
|
+
# @param [String] msi_path The path of the MSI - can be a local Windows style file path like
|
45
|
+
# c:\temp\puppet.msi OR a url like https://download.com/puppet.msi or file://c:\temp\puppet.msi
|
46
|
+
# @param [Hash{String=>String}] msi_opts MSI installer options
|
47
|
+
# See https://docs.puppetlabs.com/guides/install_puppet/install_windows.html#msi-properties
|
48
|
+
# @api private
|
49
|
+
def create_install_msi_batch_on(host, msi_path, msi_opts)
|
50
|
+
timestamp = Time.new.strftime('%Y-%m-%d_%H.%M.%S')
|
51
|
+
tmp_path = get_temp_path(host)
|
52
|
+
|
53
|
+
batch_name = "install-puppet-msi-#{timestamp}.bat"
|
54
|
+
batch_path = "#{tmp_path}\\#{batch_name}"
|
55
|
+
|
56
|
+
log_path = "#{tmp_path}\\install-puppet-#{timestamp}.log"
|
57
|
+
|
58
|
+
Tempfile.open(batch_name) do |tmp_file|
|
59
|
+
batch_contents = msi_install_script(msi_path, msi_opts, log_path)
|
60
|
+
|
61
|
+
File.open(tmp_file.path, 'w') { |file| file.puts(batch_contents) }
|
62
|
+
host.do_scp_to(tmp_file.path, batch_path, {})
|
63
|
+
end
|
64
|
+
|
65
|
+
return batch_path, log_path
|
66
|
+
end
|
67
|
+
|
68
|
+
# Given hosts construct a PATH that includes puppetbindir, facterbindir and hierabindir
|
69
|
+
# @param [Host, Array<Host>, String, Symbol] hosts One or more hosts to act upon,
|
70
|
+
# or a role (String or Symbol) that identifies one or more hosts.
|
71
|
+
# @param [String] msi_path The path of the MSI - can be a local Windows style file path like
|
72
|
+
# c:\temp\puppet.msi OR a url like https://download.com/puppet.msi or file://c:\temp\puppet.msi
|
73
|
+
# @param [Hash{String=>String}] msi_opts MSI installer options
|
74
|
+
# See https://docs.puppetlabs.com/guides/install_puppet/install_windows.html#msi-properties
|
75
|
+
# @option msi_opts [String] INSTALLIDIR Where Puppet and its dependencies should be installed.
|
76
|
+
# (Defaults vary based on operating system and intaller architecture)
|
77
|
+
# Requires Puppet 2.7.12 / PE 2.5.0
|
78
|
+
# @option msi_opts [String] PUPPET_MASTER_SERVER The hostname where the puppet master server can be reached.
|
79
|
+
# (Defaults to puppet)
|
80
|
+
# Requires Puppet 2.7.12 / PE 2.5.0
|
81
|
+
# @option msi_opts [String] PUPPET_CA_SERVER The hostname where the CA puppet master server can be reached, if you are using multiple masters and only one of them is acting as the CA.
|
82
|
+
# (Defaults the value of PUPPET_MASTER_SERVER)
|
83
|
+
# Requires Puppet 2.7.12 / PE 2.5.0
|
84
|
+
# @option msi_opts [String] PUPPET_AGENT_CERTNAME The node’s certificate name, and the name it uses when requesting catalogs. This will set a value for
|
85
|
+
# (Defaults to the node's fqdn as discovered by facter fqdn)
|
86
|
+
# Requires Puppet 2.7.12 / PE 2.5.0
|
87
|
+
# @option msi_opts [String] PUPPET_AGENT_ENVIRONMENT The node’s environment.
|
88
|
+
# (Defaults to production)
|
89
|
+
# Requires Puppet 3.3.1 / PE 3.1.0
|
90
|
+
# @option msi_opts [String] PUPPET_AGENT_STARTUP_MODE Whether the puppet agent service should run (or be allowed to run)
|
91
|
+
# (Defaults to Manual - valid values are Automatic, Manual or Disabled)
|
92
|
+
# Requires Puppet 3.4.0 / PE 3.2.0
|
93
|
+
# @option msi_opts [String] PUPPET_AGENT_ACCOUNT_USER Whether the puppet agent service should run (or be allowed to run)
|
94
|
+
# (Defaults to LocalSystem)
|
95
|
+
# Requires Puppet 3.4.0 / PE 3.2.0
|
96
|
+
# @option msi_opts [String] PUPPET_AGENT_ACCOUNT_PASSWORD The password to use for puppet agent’s user account
|
97
|
+
# (No default)
|
98
|
+
# Requires Puppet 3.4.0 / PE 3.2.0
|
99
|
+
# @option msi_opts [String] PUPPET_AGENT_ACCOUNT_DOMAIN The domain of puppet agent’s user account.
|
100
|
+
# (Defaults to .)
|
101
|
+
# Requires Puppet 3.4.0 / PE 3.2.0
|
102
|
+
# @option opts [Boolean] :debug output the MSI installation log when set to true
|
103
|
+
# otherwise do not output log (false; default behavior)
|
104
|
+
#
|
105
|
+
# @example
|
106
|
+
# install_msi_on(hosts, 'c:\puppet.msi', {:debug => true})
|
107
|
+
#
|
108
|
+
# @api private
|
109
|
+
def install_msi_on(hosts, msi_path, msi_opts = {}, opts = {})
|
110
|
+
block_on hosts do | host |
|
111
|
+
msi_opts['PUPPET_AGENT_STARTUP_MODE'] ||= 'Manual'
|
112
|
+
batch_path, log_file = create_install_msi_batch_on(host, msi_path, msi_opts)
|
113
|
+
|
114
|
+
# begin / rescue here so that we can reuse existing error msg propagation
|
115
|
+
begin
|
116
|
+
# 1641 = ERROR_SUCCESS_REBOOT_INITIATED
|
117
|
+
# 3010 = ERROR_SUCCESS_REBOOT_REQUIRED
|
118
|
+
on host, Command.new("\"#{batch_path}\"", [], { :cmdexe => true }), :acceptable_exit_codes => [0, 1641, 3010]
|
119
|
+
rescue
|
120
|
+
on host, Command.new("type \"#{log_file}\"", [], { :cmdexe => true })
|
121
|
+
raise
|
122
|
+
end
|
123
|
+
|
124
|
+
if opts[:debug]
|
125
|
+
on host, Command.new("type \"#{log_file}\"", [], { :cmdexe => true })
|
126
|
+
end
|
127
|
+
|
128
|
+
if !host.is_cygwin?
|
129
|
+
# HACK: for some reason, post install we need to refresh the connection to make puppet available for execution
|
130
|
+
host.close
|
131
|
+
end
|
132
|
+
|
133
|
+
# verify service status post install
|
134
|
+
# if puppet service exists, then pe-puppet is not queried
|
135
|
+
# if puppet service does not exist, pe-puppet is queried and that exit code is used
|
136
|
+
# therefore, this command will always exit 0 if either service is installed
|
137
|
+
on host, Command.new("sc query puppet || sc query pe-puppet", [], { :cmdexe => true })
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
data/lib/beaker/dsl/roles.rb
CHANGED
@@ -119,16 +119,25 @@ module Beaker
|
|
119
119
|
host['roles'].length == 1 && host['roles'].include?('agent')
|
120
120
|
end
|
121
121
|
|
122
|
-
# Determine whether a host has an AIO version or not. If a host :pe_ver
|
122
|
+
# Determine whether a host has an AIO version or not. If a host :pe_ver or :version
|
123
123
|
# is not specified, then it is open-ended, and as such, can be an AIO
|
124
124
|
# version depending on the context.
|
125
125
|
#
|
126
|
+
# True when any of the following cases are true
|
127
|
+
# * has PE version (:pe_ver) >= 4.0
|
128
|
+
# * has FOSS version (:version) >= 4.0
|
129
|
+
# * host has role 'aio'
|
130
|
+
# * host as the type 'aio'
|
131
|
+
#
|
126
132
|
# @note aio version is just a base-line condition. If you want to check
|
127
133
|
# that a host is an aio agent, refer to {#aio_agent?}.
|
128
134
|
#
|
129
135
|
# @return [Boolean] whether or not a host is AIO-capable
|
130
136
|
def aio_version?(host)
|
131
|
-
return
|
137
|
+
return (( host[:pe_ver] && !version_is_less(host[:pe_ver], '4.0') ) ||
|
138
|
+
( host[:version] && !version_is_less(host[:version], '4.0') ) ||
|
139
|
+
( host[:roles] && host[:roles].include?('aio')) ||
|
140
|
+
( host[:type] && !!(host[:type] =~ /(\A|-)aio(\Z|-)/ ))) == true
|
132
141
|
end
|
133
142
|
|
134
143
|
# Determine if the host is an AIO agent
|
@@ -140,6 +149,14 @@ module Beaker
|
|
140
149
|
aio_version?(host) && agent_only(host)
|
141
150
|
end
|
142
151
|
|
152
|
+
# Add the provided role to the host
|
153
|
+
#
|
154
|
+
# @param [Host] host Host to add role to
|
155
|
+
# @param [String] role The role to add to host
|
156
|
+
def add_role(host, role)
|
157
|
+
host[:roles] = host[:roles] | [role]
|
158
|
+
end
|
159
|
+
|
143
160
|
#Create a new role method for a given arbitrary role name. Makes it possible to be able to run
|
144
161
|
#commands without having to refer to role by String or Symbol. Will not add a new method
|
145
162
|
#definition if the name is already in use.
|
@@ -156,7 +173,7 @@ module Beaker
|
|
156
173
|
else
|
157
174
|
if not respond_to? role
|
158
175
|
if role !~ /\A[[:alpha:]]+[a-zA-Z0-9_]*[!?=]?\Z/
|
159
|
-
raise "Role name format error for '#{role}'. Allowed characters are: \na-Z\n0-9 (as long as not at the beginning of name)\n'_'\n'?', '!' and '=' (only as individual last character at end of name)"
|
176
|
+
raise ArgumentError, "Role name format error for '#{role}'. Allowed characters are: \na-Z\n0-9 (as long as not at the beginning of name)\n'_'\n'?', '!' and '=' (only as individual last character at end of name)"
|
160
177
|
end
|
161
178
|
self.class.send :define_method, role.to_s do
|
162
179
|
hosts_with_role = hosts_as role.to_sym
|
data/lib/beaker/dsl/structure.rb
CHANGED
@@ -167,18 +167,29 @@ module Beaker
|
|
167
167
|
# @example Confining to an already defined subset of hosts
|
168
168
|
# confine :to, {}, agents
|
169
169
|
#
|
170
|
+
# @example Confining from an already defined subset of hosts
|
171
|
+
# confine :except, {}, agents
|
172
|
+
#
|
173
|
+
#
|
170
174
|
# @return [Array<Host>] Returns an array of hosts that are still valid
|
171
175
|
# targets for this tests case.
|
172
176
|
# @raise [SkipTest] Raises skip test if there are no valid hosts for
|
173
177
|
# this test case after confinement.
|
174
178
|
def confine(type, criteria, host_array = nil, &block)
|
175
|
-
hosts_to_modify = host_array || hosts
|
179
|
+
hosts_to_modify = Array( host_array || hosts )
|
176
180
|
case type
|
177
181
|
when :except
|
178
|
-
|
182
|
+
if criteria and ( not criteria.empty? )
|
183
|
+
hosts_to_modify = hosts_to_modify - select_hosts(criteria, hosts_to_modify, &block)
|
184
|
+
else
|
185
|
+
# confining to all hosts *except* provided array of hosts
|
186
|
+
hosts_to_modify = hosts - host_array
|
187
|
+
end
|
179
188
|
when :to
|
180
189
|
if criteria and ( not criteria.empty? )
|
181
190
|
hosts_to_modify = select_hosts(criteria, hosts_to_modify, &block)
|
191
|
+
else
|
192
|
+
# confining to only hosts in provided array of hosts
|
182
193
|
end
|
183
194
|
else
|
184
195
|
raise "Unknown option #{type}"
|
@@ -198,7 +209,7 @@ module Beaker
|
|
198
209
|
# @see #confine
|
199
210
|
def confine_block(type, criteria, host_array = nil, &block)
|
200
211
|
begin
|
201
|
-
host_array
|
212
|
+
host_array = Array( host_array || hosts )
|
202
213
|
original_hosts = self.hosts.dup
|
203
214
|
confine(type, criteria, host_array)
|
204
215
|
|