beaker 2.7.1 → 2.8.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 +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
|