beaker 2.18.3 → 2.19.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|