beaker 2.7.1 → 2.8.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 +121 -2
- data/lib/beaker/dsl.rb +2 -2
- data/lib/beaker/dsl/helpers.rb +13 -1429
- data/lib/beaker/dsl/helpers/facter_helpers.rb +48 -0
- data/lib/beaker/dsl/helpers/hiera_helpers.rb +71 -0
- data/lib/beaker/dsl/helpers/host_helpers.rb +506 -0
- data/lib/beaker/dsl/helpers/puppet_helpers.rb +698 -0
- data/lib/beaker/dsl/helpers/tk_helpers.rb +101 -0
- data/lib/beaker/dsl/helpers/web_helpers.rb +115 -0
- data/lib/beaker/dsl/install_utils.rb +8 -1570
- data/lib/beaker/dsl/install_utils/ezbake_utils.rb +256 -0
- data/lib/beaker/dsl/install_utils/module_utils.rb +237 -0
- data/lib/beaker/dsl/install_utils/pe_utils.rb +518 -0
- data/lib/beaker/dsl/install_utils/puppet_utils.rb +722 -0
- data/lib/beaker/dsl/outcomes.rb +0 -4
- data/lib/beaker/dsl/roles.rb +0 -3
- data/lib/beaker/dsl/structure.rb +127 -4
- data/lib/beaker/dsl/wrappers.rb +0 -4
- data/lib/beaker/host.rb +23 -0
- data/lib/beaker/host/unix/pkg.rb +4 -4
- data/lib/beaker/host_prebuilt_steps.rb +11 -5
- data/lib/beaker/hypervisor/vagrant.rb +1 -0
- data/lib/beaker/hypervisor/vmpooler.rb +38 -0
- data/lib/beaker/logger.rb +10 -4
- data/lib/beaker/network_manager.rb +5 -4
- data/lib/beaker/options/command_line_parser.rb +7 -0
- data/lib/beaker/shared.rb +2 -1
- data/lib/beaker/shared/semvar.rb +41 -0
- data/lib/beaker/test_suite.rb +20 -6
- data/lib/beaker/version.rb +1 -1
- data/spec/beaker/dsl/helpers/facter_helpers_spec.rb +59 -0
- data/spec/beaker/dsl/helpers/hiera_helpers_spec.rb +96 -0
- data/spec/beaker/dsl/helpers/host_helpers_spec.rb +413 -0
- data/spec/beaker/dsl/{helpers_spec.rb → helpers/puppet_helpers_spec.rb} +2 -611
- data/spec/beaker/dsl/helpers/tk_helpers_spec.rb +83 -0
- data/spec/beaker/dsl/helpers/web_helpers_spec.rb +60 -0
- data/spec/beaker/dsl/install_utils/module_utils_spec.rb +241 -0
- data/spec/beaker/dsl/install_utils/pe_utils_spec.rb +475 -0
- data/spec/beaker/dsl/install_utils/puppet_utils_spec.rb +523 -0
- data/spec/beaker/dsl/structure_spec.rb +108 -0
- data/spec/beaker/host_prebuilt_steps_spec.rb +44 -0
- data/spec/beaker/host_spec.rb +41 -0
- data/spec/beaker/hypervisor/vagrant_spec.rb +2 -1
- data/spec/beaker/logger_spec.rb +9 -2
- data/spec/beaker/network_manager_spec.rb +7 -1
- data/spec/beaker/options/command_line_parser_spec.rb +3 -2
- data/spec/beaker/shared/semvar_spec.rb +36 -0
- data/spec/beaker/test_suite_spec.rb +48 -0
- data/spec/mocks.rb +10 -0
- metadata +23 -5
- data/lib/beaker/dsl/ezbake_utils.rb +0 -259
- data/spec/beaker/dsl/install_utils_spec.rb +0 -1242
@@ -0,0 +1,518 @@
|
|
1
|
+
module Beaker
|
2
|
+
module DSL
|
3
|
+
module InstallUtils
|
4
|
+
#
|
5
|
+
# This module contains methods to help installing/upgrading PE builds - including Higgs installs
|
6
|
+
#
|
7
|
+
# To mix this is into a class you need the following:
|
8
|
+
# * a method *hosts* that yields any hosts implementing
|
9
|
+
# {Beaker::Host}'s interface to act upon.
|
10
|
+
# * a method *options* that provides an options hash, see {Beaker::Options::OptionsHash}
|
11
|
+
# * the module {Beaker::DSL::Roles} that provides access to the various hosts implementing
|
12
|
+
# {Beaker::Host}'s interface to act upon
|
13
|
+
# * the module {Beaker::DSL::Wrappers} the provides convenience methods for {Beaker::DSL::Command} creation
|
14
|
+
module PEUtils
|
15
|
+
|
16
|
+
#Sort array of hosts so that it has the correct order for PE installation based upon each host's role
|
17
|
+
# @example
|
18
|
+
# h = sorted_hosts
|
19
|
+
#
|
20
|
+
# @note Order for installation should be
|
21
|
+
# First : master
|
22
|
+
# Second: database host (if not same as master)
|
23
|
+
# Third: dashboard (if not same as master or database)
|
24
|
+
# Fourth: everything else
|
25
|
+
#
|
26
|
+
# @!visibility private
|
27
|
+
def sorted_hosts
|
28
|
+
special_nodes = []
|
29
|
+
[master, database, dashboard].uniq.each do |host|
|
30
|
+
special_nodes << host if host != nil
|
31
|
+
end
|
32
|
+
real_agents = agents - special_nodes
|
33
|
+
special_nodes + real_agents
|
34
|
+
end
|
35
|
+
|
36
|
+
#Create the PE install command string based upon the host and options settings
|
37
|
+
# @param [Host] host The host that PE is to be installed on
|
38
|
+
# For UNIX machines using the full PE installer, the host object must have the 'pe_installer' field set correctly.
|
39
|
+
# @param [Hash{Symbol=>String}] opts The options
|
40
|
+
# @option opts [String] :pe_ver_win Default PE version to install or upgrade to on Windows hosts
|
41
|
+
# (Othersie uses individual Windows hosts pe_ver)
|
42
|
+
# @option opts [String] :pe_ver Default PE version to install or upgrade to
|
43
|
+
# (Otherwise uses individual hosts pe_ver)
|
44
|
+
# @option opts [Boolean] :pe_debug (false) Should we run the installer in debug mode?
|
45
|
+
# @example
|
46
|
+
# on host, "#{installer_cmd(host, opts)} -a #{host['working_dir']}/answers"
|
47
|
+
# @api private
|
48
|
+
def installer_cmd(host, opts)
|
49
|
+
version = host['pe_ver'] || opts[:pe_ver]
|
50
|
+
if host['platform'] =~ /windows/
|
51
|
+
log_file = "#{File.basename(host['working_dir'])}.log"
|
52
|
+
pe_debug = host[:pe_debug] || opts[:pe_debug] ? " && cat #{log_file}" : ''
|
53
|
+
if host.is_cygwin?
|
54
|
+
"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}"
|
55
|
+
else
|
56
|
+
"cd #{host['working_dir']} && msiexec.exe /qn /L*V #{log_file} /i #{host['dist']}.msi PUPPET_MASTER_SERVER=#{master} PUPPET_AGENT_CERTNAME=#{host}#{pe_debug}"
|
57
|
+
end
|
58
|
+
# Frictionless install didn't exist pre-3.2.0, so in that case we fall
|
59
|
+
# through and do a regular install.
|
60
|
+
elsif host['roles'].include? 'frictionless' and ! version_is_less(version, '3.2.0')
|
61
|
+
# PE 3.4 introduced the ability to pass in config options to the bash script in the form
|
62
|
+
# of <section>:<key>=<value>
|
63
|
+
frictionless_install_opts = []
|
64
|
+
if host.has_key?('frictionless_options') and ! version_is_less(version, '3.4.0')
|
65
|
+
# since we have options to pass in, we need to tell the bash script
|
66
|
+
host['frictionless_options'].each do |section, settings|
|
67
|
+
settings.each do |key, value|
|
68
|
+
frictionless_install_opts << "#{section}:#{key}=#{value}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
pe_debug = host[:pe_debug] || opts[:pe_debug] ? ' -x' : ''
|
74
|
+
"cd #{host['working_dir']} && curl --tlsv1 -kO https://#{master}:8140/packages/#{version}/install.bash && bash#{pe_debug} install.bash #{frictionless_install_opts.join(' ')}".strip
|
75
|
+
elsif host['platform'] =~ /osx/
|
76
|
+
version = host['pe_ver'] || opts[:pe_ver]
|
77
|
+
pe_debug = host[:pe_debug] || opts[:pe_debug] ? ' -verboseR' : ''
|
78
|
+
"cd #{host['working_dir']} && hdiutil attach #{host['dist']}.dmg && installer#{pe_debug} -pkg /Volumes/puppet-enterprise-#{version}/puppet-enterprise-installer-#{version}.pkg -target /"
|
79
|
+
elsif host['platform'] =~ /eos/
|
80
|
+
commands = ['enable', "extension puppet-enterprise-#{version}-#{host['platform']}.swix"]
|
81
|
+
command = commands.join("\n")
|
82
|
+
"Cli -c '#{command}'"
|
83
|
+
else
|
84
|
+
pe_debug = host[:pe_debug] || opts[:pe_debug] ? ' -D' : ''
|
85
|
+
"cd #{host['working_dir']}/#{host['dist']} && ./#{host['pe_installer']}#{pe_debug} -a #{host['working_dir']}/answers"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
#Determine the PE package to download/upload on a mac host, download/upload that package onto the host.
|
90
|
+
# Assumed file name format: puppet-enterprise-3.3.0-rc1-559-g97f0833-osx-10.9-x86_64.dmg.
|
91
|
+
# @param [Host] host The mac host to download/upload and unpack PE onto
|
92
|
+
# @param [Hash{Symbol=>Symbol, String}] opts The options
|
93
|
+
# @option opts [String] :pe_dir Default directory or URL to pull PE package from
|
94
|
+
# (Otherwise uses individual hosts pe_dir)
|
95
|
+
# @api private
|
96
|
+
def fetch_pe_on_mac(host, opts)
|
97
|
+
path = host['pe_dir'] || opts[:pe_dir]
|
98
|
+
local = File.directory?(path)
|
99
|
+
filename = "#{host['dist']}"
|
100
|
+
extension = ".dmg"
|
101
|
+
if local
|
102
|
+
if not File.exists?("#{path}/#{filename}#{extension}")
|
103
|
+
raise "attempting installation on #{host}, #{path}/#{filename}#{extension} does not exist"
|
104
|
+
end
|
105
|
+
scp_to host, "#{path}/#{filename}#{extension}", "#{host['working_dir']}/#{filename}#{extension}"
|
106
|
+
else
|
107
|
+
if not link_exists?("#{path}/#{filename}#{extension}")
|
108
|
+
raise "attempting installation on #{host}, #{path}/#{filename}#{extension} does not exist"
|
109
|
+
end
|
110
|
+
on host, "cd #{host['working_dir']}; curl -O #{path}/#{filename}#{extension}"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
#Determine the PE package to download/upload on a windows host, download/upload that package onto the host.
|
115
|
+
#Assumed file name format: puppet-enterprise-3.3.0-rc1-559-g97f0833.msi
|
116
|
+
# @param [Host] host The windows host to download/upload and unpack PE onto
|
117
|
+
# @param [Hash{Symbol=>Symbol, String}] opts The options
|
118
|
+
# @option opts [String] :pe_dir Default directory or URL to pull PE package from
|
119
|
+
# (Otherwise uses individual hosts pe_dir)
|
120
|
+
# @option opts [String] :pe_ver_win Default PE version to install or upgrade to
|
121
|
+
# (Otherwise uses individual hosts pe_ver)
|
122
|
+
# @api private
|
123
|
+
def fetch_pe_on_windows(host, opts)
|
124
|
+
path = host['pe_dir'] || opts[:pe_dir]
|
125
|
+
local = File.directory?(path)
|
126
|
+
version = host['pe_ver'] || opts[:pe_ver_win]
|
127
|
+
filename = "#{host['dist']}"
|
128
|
+
extension = ".msi"
|
129
|
+
if local
|
130
|
+
if not File.exists?("#{path}/#{filename}#{extension}")
|
131
|
+
raise "attempting installation on #{host}, #{path}/#{filename}#{extension} does not exist"
|
132
|
+
end
|
133
|
+
scp_to host, "#{path}/#{filename}#{extension}", "#{host['working_dir']}/#{filename}#{extension}"
|
134
|
+
else
|
135
|
+
if not link_exists?("#{path}/#{filename}#{extension}")
|
136
|
+
raise "attempting installation on #{host}, #{path}/#{filename}#{extension} does not exist"
|
137
|
+
end
|
138
|
+
if host.is_cygwin?
|
139
|
+
on host, "cd #{host['working_dir']}; curl -O #{path}/#{filename}#{extension}"
|
140
|
+
else
|
141
|
+
on host, powershell("$webclient = New-Object System.Net.WebClient; $webclient.DownloadFile('#{path}/#{filename}#{extension}','#{host['wor
|
142
|
+
king_dir']}\\#{filename}#{extension}')")
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
#Determine the PE package to download/upload on a unix style host, download/upload that package onto the host
|
148
|
+
#and unpack it.
|
149
|
+
# @param [Host] host The unix style host to download/upload and unpack PE onto
|
150
|
+
# @param [Hash{Symbol=>Symbol, String}] opts The options
|
151
|
+
# @option opts [String] :pe_dir Default directory or URL to pull PE package from
|
152
|
+
# (Otherwise uses individual hosts pe_dir)
|
153
|
+
# @api private
|
154
|
+
def fetch_pe_on_unix(host, opts)
|
155
|
+
path = host['pe_dir'] || opts[:pe_dir]
|
156
|
+
local = File.directory?(path)
|
157
|
+
filename = "#{host['dist']}"
|
158
|
+
if local
|
159
|
+
extension = File.exists?("#{path}/#{filename}.tar.gz") ? ".tar.gz" : ".tar"
|
160
|
+
if not File.exists?("#{path}/#{filename}#{extension}")
|
161
|
+
raise "attempting installation on #{host}, #{path}/#{filename}#{extension} does not exist"
|
162
|
+
end
|
163
|
+
scp_to host, "#{path}/#{filename}#{extension}", "#{host['working_dir']}/#{filename}#{extension}"
|
164
|
+
if extension =~ /gz/
|
165
|
+
on host, "cd #{host['working_dir']}; gunzip #{filename}#{extension}"
|
166
|
+
end
|
167
|
+
if extension =~ /tar/
|
168
|
+
on host, "cd #{host['working_dir']}; tar -xvf #{filename}.tar"
|
169
|
+
end
|
170
|
+
else
|
171
|
+
if host['platform'] =~ /eos/
|
172
|
+
extension = '.swix'
|
173
|
+
else
|
174
|
+
extension = link_exists?("#{path}/#{filename}.tar.gz") ? ".tar.gz" : ".tar"
|
175
|
+
end
|
176
|
+
if not link_exists?("#{path}/#{filename}#{extension}")
|
177
|
+
raise "attempting installation on #{host}, #{path}/#{filename}#{extension} does not exist"
|
178
|
+
end
|
179
|
+
|
180
|
+
if host['platform'] =~ /eos/
|
181
|
+
commands = ['enable', "copy #{path}/#{filename}#{extension} extension:"]
|
182
|
+
command = commands.join("\n")
|
183
|
+
on host, "Cli -c '#{command}'"
|
184
|
+
else
|
185
|
+
unpack = 'tar -xvf -'
|
186
|
+
unpack = extension =~ /gz/ ? 'gunzip | ' + unpack : unpack
|
187
|
+
on host, "cd #{host['working_dir']}; curl #{path}/#{filename}#{extension} | #{unpack}"
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
#Determine the PE package to download/upload per-host, download/upload that package onto the host
|
193
|
+
#and unpack it.
|
194
|
+
# @param [Array<Host>] hosts The hosts to download/upload and unpack PE onto
|
195
|
+
# @param [Hash{Symbol=>Symbol, String}] opts The options
|
196
|
+
# @option opts [String] :pe_dir Default directory or URL to pull PE package from
|
197
|
+
# (Otherwise uses individual hosts pe_dir)
|
198
|
+
# @option opts [String] :pe_ver Default PE version to install or upgrade to
|
199
|
+
# (Otherwise uses individual hosts pe_ver)
|
200
|
+
# @option opts [String] :pe_ver_win Default PE version to install or upgrade to on Windows hosts
|
201
|
+
# (Otherwise uses individual Windows hosts pe_ver)
|
202
|
+
# @api private
|
203
|
+
def fetch_pe(hosts, opts)
|
204
|
+
hosts.each do |host|
|
205
|
+
# We install Puppet from the master for frictionless installs, so we don't need to *fetch* anything
|
206
|
+
next if host['roles'].include?('frictionless') && (! version_is_less(opts[:pe_ver] || host['pe_ver'], '3.2.0'))
|
207
|
+
|
208
|
+
if host['platform'] =~ /windows/
|
209
|
+
fetch_pe_on_windows(host, opts)
|
210
|
+
elsif host['platform'] =~ /osx/
|
211
|
+
fetch_pe_on_mac(host, opts)
|
212
|
+
else
|
213
|
+
fetch_pe_on_unix(host, opts)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
#Classify the master so that it can deploy frictionless packages for a given host.
|
219
|
+
# @param [Host] host The host to install pacakges for
|
220
|
+
# @api private
|
221
|
+
def deploy_frictionless_to_master(host)
|
222
|
+
klass = host['platform'].gsub(/-/, '_').gsub(/\./,'')
|
223
|
+
klass = "pe_repo::platform::#{klass}"
|
224
|
+
on dashboard, "cd /opt/puppet/share/puppet-dashboard && /opt/puppet/bin/bundle exec /opt/puppet/bin/rake nodeclass:add[#{klass},skip]"
|
225
|
+
on dashboard, "cd /opt/puppet/share/puppet-dashboard && /opt/puppet/bin/bundle exec /opt/puppet/bin/rake node:add[#{master},,,skip]"
|
226
|
+
on dashboard, "cd /opt/puppet/share/puppet-dashboard && /opt/puppet/bin/bundle exec /opt/puppet/bin/rake node:addclass[#{master},#{klass}]"
|
227
|
+
on master, puppet("agent -t"), :acceptable_exit_codes => [0,2]
|
228
|
+
end
|
229
|
+
|
230
|
+
#Perform a Puppet Enterprise upgrade or install
|
231
|
+
# @param [Array<Host>] hosts The hosts to install or upgrade PE on
|
232
|
+
# @param [Hash{Symbol=>Symbol, String}] opts The options
|
233
|
+
# @option opts [String] :pe_dir Default directory or URL to pull PE package from
|
234
|
+
# (Otherwise uses individual hosts pe_dir)
|
235
|
+
# @option opts [String] :pe_ver Default PE version to install or upgrade to
|
236
|
+
# (Otherwise uses individual hosts pe_ver)
|
237
|
+
# @option opts [String] :pe_ver_win Default PE version to install or upgrade to on Windows hosts
|
238
|
+
# (Otherwise uses individual Windows hosts pe_ver)
|
239
|
+
# @option opts [Symbol] :type (:install) One of :upgrade or :install
|
240
|
+
# @option opts [Boolean] :set_console_password Should we set the PE console password in the answers file? Used during upgrade only.
|
241
|
+
# @option opts [Hash<String>] :answers Pre-set answers based upon ENV vars and defaults
|
242
|
+
# (See {Beaker::Options::Presets.env_vars})
|
243
|
+
#
|
244
|
+
# @example
|
245
|
+
# do_install(hosts, {:type => :upgrade, :pe_dir => path, :pe_ver => version, :pe_ver_win => version_win})
|
246
|
+
#
|
247
|
+
# @api private
|
248
|
+
#
|
249
|
+
def do_install hosts, opts = {}
|
250
|
+
masterless = (defined? options) ? options[:masterless] : false
|
251
|
+
opts[:masterless] = masterless # has to pass masterless down for answer generation awareness
|
252
|
+
opts[:type] = opts[:type] || :install
|
253
|
+
unless masterless
|
254
|
+
pre30database = version_is_less(opts[:pe_ver] || database['pe_ver'], '3.0')
|
255
|
+
pre30master = version_is_less(opts[:pe_ver] || master['pe_ver'], '3.0')
|
256
|
+
|
257
|
+
unless version_is_less(opts[:pe_ver] || master['pe_ver'], '3.4')
|
258
|
+
master['puppetservice'] = 'pe-puppetserver'
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
# Set PE distribution for all the hosts, create working dir
|
263
|
+
use_all_tar = ENV['PE_USE_ALL_TAR'] == 'true'
|
264
|
+
hosts.each do |host|
|
265
|
+
host['pe_installer'] ||= 'puppet-enterprise-installer'
|
266
|
+
if host['platform'] !~ /windows|osx/
|
267
|
+
platform = use_all_tar ? 'all' : host['platform']
|
268
|
+
version = host['pe_ver'] || opts[:pe_ver]
|
269
|
+
host['dist'] = "puppet-enterprise-#{version}-#{platform}"
|
270
|
+
elsif host['platform'] =~ /osx/
|
271
|
+
version = host['pe_ver'] || opts[:pe_ver]
|
272
|
+
host['dist'] = "puppet-enterprise-#{version}-#{host['platform']}"
|
273
|
+
elsif host['platform'] =~ /windows/
|
274
|
+
version = host[:pe_ver] || opts['pe_ver_win']
|
275
|
+
should_install_64bit = !(version_is_less(version, '3.4')) && host.is_x86_64? && !host['install_32'] && !opts['install_32']
|
276
|
+
#only install 64bit builds if
|
277
|
+
# - we are on pe version 3.4+
|
278
|
+
# - we do not have install_32 set on host
|
279
|
+
# - we do not have install_32 set globally
|
280
|
+
if !(version_is_less(version, '4.0'))
|
281
|
+
if should_install_64bit
|
282
|
+
host['dist'] = "puppet-agent-#{version}-x64"
|
283
|
+
else
|
284
|
+
host['dist'] = "puppet-agent-#{version}-x86"
|
285
|
+
end
|
286
|
+
elsif should_install_64bit
|
287
|
+
host['dist'] = "puppet-enterprise-#{version}-x64"
|
288
|
+
else
|
289
|
+
host['dist'] = "puppet-enterprise-#{version}"
|
290
|
+
end
|
291
|
+
end
|
292
|
+
host['working_dir'] = host.tmpdir(Time.new.strftime("%Y-%m-%d_%H.%M.%S"))
|
293
|
+
end
|
294
|
+
|
295
|
+
fetch_pe(hosts, opts)
|
296
|
+
|
297
|
+
install_hosts = hosts.dup
|
298
|
+
unless masterless
|
299
|
+
# If we're installing a database version less than 3.0, ignore the database host
|
300
|
+
install_hosts.delete(database) if pre30database and database != master and database != dashboard
|
301
|
+
end
|
302
|
+
|
303
|
+
install_hosts.each do |host|
|
304
|
+
if host['platform'] =~ /windows/
|
305
|
+
on host, installer_cmd(host, opts)
|
306
|
+
if not host.is_cygwin?
|
307
|
+
# HACK: for some reason, post install we need to refresh the connection to make puppet available for execution
|
308
|
+
host.close
|
309
|
+
end
|
310
|
+
else
|
311
|
+
# We only need answers if we're using the classic installer
|
312
|
+
version = host['pe_ver'] || opts[:pe_ver]
|
313
|
+
if host['roles'].include?('frictionless') && (! version_is_less(version, '3.2.0'))
|
314
|
+
# If We're *not* running the classic installer, we want
|
315
|
+
# to make sure the master has packages for us.
|
316
|
+
deploy_frictionless_to_master(host)
|
317
|
+
on host, installer_cmd(host, opts)
|
318
|
+
elsif host['platform'] =~ /osx|eos/
|
319
|
+
# If we're not frictionless, we need to run the OSX special-case
|
320
|
+
on host, installer_cmd(host, opts)
|
321
|
+
#set the certname and master
|
322
|
+
on host, puppet("config set server #{master}")
|
323
|
+
on host, puppet("config set certname #{host}")
|
324
|
+
#run once to request cert
|
325
|
+
acceptable_codes = host['platform'] =~ /osx/ ? [1] : [0, 1]
|
326
|
+
on host, puppet_agent('-t'), :acceptable_exit_codes => acceptable_codes
|
327
|
+
else
|
328
|
+
answers = Beaker::Answers.create(opts[:pe_ver] || host['pe_ver'], hosts, opts)
|
329
|
+
create_remote_file host, "#{host['working_dir']}/answers", answers.answer_string(host)
|
330
|
+
on host, installer_cmd(host, opts)
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
# On each agent, we ensure the certificate is signed then shut down the agent
|
335
|
+
sign_certificate_for(host) unless masterless
|
336
|
+
stop_agent_on(host)
|
337
|
+
end
|
338
|
+
|
339
|
+
unless masterless
|
340
|
+
# Wait for PuppetDB to be totally up and running (post 3.0 version of pe only)
|
341
|
+
sleep_until_puppetdb_started(database) unless pre30database
|
342
|
+
|
343
|
+
# Run the agent once to ensure everything is in the dashboard
|
344
|
+
install_hosts.each do |host|
|
345
|
+
on host, puppet_agent('-t'), :acceptable_exit_codes => [0,2]
|
346
|
+
|
347
|
+
# Workaround for PE-1105 when deploying 3.0.0
|
348
|
+
# The installer did not respect our database host answers in 3.0.0,
|
349
|
+
# and would cause puppetdb to be bounced by the agent run. By sleeping
|
350
|
+
# again here, we ensure that if that bounce happens during an upgrade
|
351
|
+
# test we won't fail early in the install process.
|
352
|
+
if host['pe_ver'] == '3.0.0' and host == database
|
353
|
+
sleep_until_puppetdb_started(database)
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
install_hosts.each do |host|
|
358
|
+
wait_for_host_in_dashboard(host)
|
359
|
+
end
|
360
|
+
|
361
|
+
if pre30master
|
362
|
+
task = 'nodegroup:add_all_nodes group=default'
|
363
|
+
else
|
364
|
+
task = 'defaultgroup:ensure_default_group'
|
365
|
+
end
|
366
|
+
on dashboard, "/opt/puppet/bin/rake -sf /opt/puppet/share/puppet-dashboard/Rakefile #{task} RAILS_ENV=production"
|
367
|
+
|
368
|
+
# Now that all hosts are in the dashbaord, run puppet one more
|
369
|
+
# time to configure mcollective
|
370
|
+
on install_hosts, puppet_agent('-t'), :acceptable_exit_codes => [0,2]
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
#Install PE based upon host configuration and options
|
375
|
+
# @example
|
376
|
+
# install_pe
|
377
|
+
#
|
378
|
+
# @note Either pe_ver and pe_dir should be set in the ENV or each host should have pe_ver and pe_dir set individually.
|
379
|
+
# Install file names are assumed to be of the format puppet-enterprise-VERSION-PLATFORM.(tar)|(tar.gz)
|
380
|
+
# for Unix like systems and puppet-enterprise-VERSION.msi for Windows systems.
|
381
|
+
#
|
382
|
+
def install_pe
|
383
|
+
#process the version files if necessary
|
384
|
+
hosts.each do |host|
|
385
|
+
host['pe_dir'] ||= options[:pe_dir]
|
386
|
+
if host['platform'] =~ /windows/
|
387
|
+
host['pe_ver'] = host['pe_ver'] || options['pe_ver'] ||
|
388
|
+
Beaker::Options::PEVersionScraper.load_pe_version(host[:pe_dir] || options[:pe_dir], options[:pe_version_file_win])
|
389
|
+
else
|
390
|
+
host['pe_ver'] = host['pe_ver'] || options['pe_ver'] ||
|
391
|
+
Beaker::Options::PEVersionScraper.load_pe_version(host[:pe_dir] || options[:pe_dir], options[:pe_version_file])
|
392
|
+
end
|
393
|
+
end
|
394
|
+
#send in the global options hash
|
395
|
+
do_install sorted_hosts, options
|
396
|
+
end
|
397
|
+
|
398
|
+
#Upgrade PE based upon host configuration and options
|
399
|
+
# @param [String] path A path (either local directory or a URL to a listing of PE builds).
|
400
|
+
# Will contain a LATEST file indicating the latest build to install.
|
401
|
+
# This is ignored if a pe_upgrade_ver and pe_upgrade_dir are specified
|
402
|
+
# in the host configuration file.
|
403
|
+
# @example
|
404
|
+
# upgrade_pe("http://neptune.puppetlabs.lan/3.0/ci-ready/")
|
405
|
+
#
|
406
|
+
# @note Install file names are assumed to be of the format puppet-enterprise-VERSION-PLATFORM.(tar)|(tar.gz)
|
407
|
+
# for Unix like systems and puppet-enterprise-VERSION.msi for Windows systems.
|
408
|
+
def upgrade_pe path=nil
|
409
|
+
set_console_password = false
|
410
|
+
# if we are upgrading from something lower than 3.4 then we need to set the pe console password
|
411
|
+
if (dashboard[:pe_ver] ? version_is_less(dashboard[:pe_ver], "3.4.0") : true)
|
412
|
+
set_console_password = true
|
413
|
+
end
|
414
|
+
# get new version information
|
415
|
+
hosts.each do |host|
|
416
|
+
host['pe_dir'] = host['pe_upgrade_dir'] || path
|
417
|
+
if host['platform'] =~ /windows/
|
418
|
+
host['pe_ver'] = host['pe_upgrade_ver'] || options['pe_upgrade_ver'] ||
|
419
|
+
Options::PEVersionScraper.load_pe_version(host['pe_dir'], options[:pe_version_file_win])
|
420
|
+
else
|
421
|
+
host['pe_ver'] = host['pe_upgrade_ver'] || options['pe_upgrade_ver'] ||
|
422
|
+
Options::PEVersionScraper.load_pe_version(host['pe_dir'], options[:pe_version_file])
|
423
|
+
end
|
424
|
+
if version_is_less(host['pe_ver'], '3.0')
|
425
|
+
host['pe_installer'] ||= 'puppet-enterprise-upgrader'
|
426
|
+
end
|
427
|
+
end
|
428
|
+
# send in the global options hash
|
429
|
+
do_install(sorted_hosts, options.merge({:type => :upgrade, :set_console_password => set_console_password}))
|
430
|
+
options['upgrade'] = true
|
431
|
+
end
|
432
|
+
|
433
|
+
#Create the Higgs install command string based upon the host and options settings. Installation command will be run as a
|
434
|
+
#background process. The output of the command will be stored in the provided host['higgs_file'].
|
435
|
+
# @param [Host] host The host that Higgs is to be installed on
|
436
|
+
# The host object must have the 'working_dir', 'dist' and 'pe_installer' field set correctly.
|
437
|
+
# @api private
|
438
|
+
def higgs_installer_cmd host
|
439
|
+
|
440
|
+
"cd #{host['working_dir']}/#{host['dist']} ; nohup ./#{host['pe_installer']} <<<Y > #{host['higgs_file']} 2>&1 &"
|
441
|
+
|
442
|
+
end
|
443
|
+
|
444
|
+
#Perform a Puppet Enterprise Higgs install up until web browser interaction is required, runs on linux hosts only.
|
445
|
+
# @param [Host] host The host to install higgs on
|
446
|
+
# @param [Hash{Symbol=>Symbol, String}] opts The options
|
447
|
+
# @option opts [String] :pe_dir Default directory or URL to pull PE package from
|
448
|
+
# (Otherwise uses individual hosts pe_dir)
|
449
|
+
# @option opts [String] :pe_ver Default PE version to install
|
450
|
+
# (Otherwise uses individual hosts pe_ver)
|
451
|
+
# @raise [StandardError] When installation times out
|
452
|
+
#
|
453
|
+
# @example
|
454
|
+
# do_higgs_install(master, {:pe_dir => path, :pe_ver => version})
|
455
|
+
#
|
456
|
+
# @api private
|
457
|
+
#
|
458
|
+
def do_higgs_install host, opts
|
459
|
+
use_all_tar = ENV['PE_USE_ALL_TAR'] == 'true'
|
460
|
+
platform = use_all_tar ? 'all' : host['platform']
|
461
|
+
version = host['pe_ver'] || opts[:pe_ver]
|
462
|
+
host['dist'] = "puppet-enterprise-#{version}-#{platform}"
|
463
|
+
|
464
|
+
use_all_tar = ENV['PE_USE_ALL_TAR'] == 'true'
|
465
|
+
host['pe_installer'] ||= 'puppet-enterprise-installer'
|
466
|
+
host['working_dir'] = host.tmpdir(Time.new.strftime("%Y-%m-%d_%H.%M.%S"))
|
467
|
+
|
468
|
+
fetch_pe([host], opts)
|
469
|
+
|
470
|
+
host['higgs_file'] = "higgs_#{File.basename(host['working_dir'])}.log"
|
471
|
+
on host, higgs_installer_cmd(host), opts
|
472
|
+
|
473
|
+
#wait for output to host['higgs_file']
|
474
|
+
#we're all done when we find this line in the PE installation log
|
475
|
+
higgs_re = /Please\s+go\s+to\s+https:\/\/.*\s+in\s+your\s+browser\s+to\s+continue\s+installation/m
|
476
|
+
res = Result.new(host, 'tmp cmd')
|
477
|
+
tries = 10
|
478
|
+
attempts = 0
|
479
|
+
prev_sleep = 0
|
480
|
+
cur_sleep = 1
|
481
|
+
while (res.stdout !~ higgs_re) and (attempts < tries)
|
482
|
+
res = on host, "cd #{host['working_dir']}/#{host['dist']} && cat #{host['higgs_file']}", :acceptable_exit_codes => (0..255)
|
483
|
+
attempts += 1
|
484
|
+
sleep( cur_sleep )
|
485
|
+
prev_sleep = cur_sleep
|
486
|
+
cur_sleep = cur_sleep + prev_sleep
|
487
|
+
end
|
488
|
+
|
489
|
+
if attempts >= tries
|
490
|
+
raise "Failed to kick off PE (Higgs) web installation"
|
491
|
+
end
|
492
|
+
end
|
493
|
+
|
494
|
+
#Install Higgs up till the point where you need to continue installation in a web browser, defaults to execution
|
495
|
+
#on the master node.
|
496
|
+
#@param [Host] higgs_host The host to install Higgs on (supported on linux platform only)
|
497
|
+
# @example
|
498
|
+
# install_higgs
|
499
|
+
#
|
500
|
+
# @note Either pe_ver and pe_dir should be set in the ENV or each host should have pe_ver and pe_dir set individually.
|
501
|
+
# Install file names are assumed to be of the format puppet-enterprise-VERSION-PLATFORM.(tar)|(tar.gz).
|
502
|
+
#
|
503
|
+
def install_higgs( higgs_host = master )
|
504
|
+
#process the version files if necessary
|
505
|
+
master['pe_dir'] ||= options[:pe_dir]
|
506
|
+
master['pe_ver'] = master['pe_ver'] || options['pe_ver'] ||
|
507
|
+
Beaker::Options::PEVersionScraper.load_pe_version(master[:pe_dir] || options[:pe_dir], options[:pe_version_file])
|
508
|
+
if higgs_host['platform'] =~ /osx|windows/
|
509
|
+
raise "Attempting higgs installation on host #{higgs_host.name} with unsupported platform #{higgs_host['platform']}"
|
510
|
+
end
|
511
|
+
#send in the global options hash
|
512
|
+
do_higgs_install higgs_host, options
|
513
|
+
end
|
514
|
+
|
515
|
+
end
|
516
|
+
end
|
517
|
+
end
|
518
|
+
end
|