beaker 0.0.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.travis.yml +8 -0
- data/README.md +6 -6
- data/beaker.gemspec +6 -2
- data/lib/beaker.rb +1 -1
- data/lib/beaker/answers.rb +34 -7
- data/lib/beaker/answers/version20.rb +124 -0
- data/lib/beaker/answers/version28.rb +21 -0
- data/lib/beaker/answers/version30.rb +24 -5
- data/lib/beaker/cli.rb +55 -41
- data/lib/beaker/command.rb +2 -2
- data/lib/beaker/dsl/helpers.rb +320 -106
- data/lib/beaker/dsl/install_utils.rb +202 -81
- data/lib/beaker/dsl/roles.rb +40 -0
- data/lib/beaker/host.rb +28 -20
- data/lib/beaker/host/unix.rb +7 -4
- data/lib/beaker/host/unix/pkg.rb +42 -12
- data/lib/beaker/host/windows.rb +9 -5
- data/lib/beaker/host/windows/group.rb +1 -1
- data/lib/beaker/host/windows/pkg.rb +41 -8
- data/lib/beaker/hypervisor.rb +23 -10
- data/lib/beaker/hypervisor/aixer.rb +15 -19
- data/lib/beaker/hypervisor/blimper.rb +71 -72
- data/lib/beaker/hypervisor/fusion.rb +11 -10
- data/lib/beaker/hypervisor/solaris.rb +17 -23
- data/lib/beaker/hypervisor/vagrant.rb +27 -12
- data/lib/beaker/hypervisor/vcloud.rb +154 -138
- data/lib/beaker/hypervisor/vcloud_pooled.rb +97 -0
- data/lib/beaker/hypervisor/vsphere.rb +8 -5
- data/lib/beaker/hypervisor/vsphere_helper.rb +43 -33
- data/lib/beaker/network_manager.rb +16 -12
- data/lib/beaker/options/command_line_parser.rb +199 -0
- data/lib/beaker/options/hosts_file_parser.rb +39 -0
- data/lib/beaker/options/options_file_parser.rb +45 -0
- data/lib/beaker/options/options_hash.rb +294 -0
- data/lib/beaker/options/parser.rb +288 -0
- data/lib/beaker/options/pe_version_scraper.rb +35 -0
- data/lib/beaker/options/presets.rb +70 -0
- data/lib/beaker/shared.rb +2 -1
- data/lib/beaker/shared/host_handler.rb +7 -2
- data/lib/beaker/shared/repetition.rb +1 -0
- data/lib/beaker/shared/timed.rb +14 -0
- data/lib/beaker/test_case.rb +2 -38
- data/lib/beaker/test_suite.rb +11 -25
- data/lib/beaker/utils/repo_control.rb +6 -8
- data/lib/beaker/utils/setup_helper.rb +9 -20
- data/spec/beaker/answers_spec.rb +109 -0
- data/spec/beaker/command_spec.rb +2 -2
- data/spec/beaker/dsl/assertions_spec.rb +1 -3
- data/spec/beaker/dsl/helpers_spec.rb +519 -84
- data/spec/beaker/dsl/install_utils_spec.rb +265 -16
- data/spec/beaker/dsl/roles_spec.rb +31 -10
- data/spec/beaker/host/windows/group_spec.rb +55 -0
- data/spec/beaker/host_spec.rb +130 -40
- data/spec/beaker/hypervisor/aixer_spec.rb +34 -0
- data/spec/beaker/hypervisor/blimper_spec.rb +77 -0
- data/spec/beaker/hypervisor/fusion_spec.rb +26 -0
- data/spec/beaker/hypervisor/hypervisor_spec.rb +66 -0
- data/spec/beaker/hypervisor/solaris_spec.rb +39 -0
- data/spec/beaker/hypervisor/vagrant_spec.rb +105 -0
- data/spec/beaker/hypervisor/vcloud_pooled_spec.rb +60 -0
- data/spec/beaker/hypervisor/vcloud_spec.rb +70 -0
- data/spec/beaker/hypervisor/vsphere_helper_spec.rb +162 -0
- data/spec/beaker/hypervisor/vsphere_spec.rb +76 -0
- data/spec/beaker/options/command_line_parser_spec.rb +25 -0
- data/spec/beaker/options/data/LATEST +1 -0
- data/spec/beaker/options/data/badyaml.cfg +21 -0
- data/spec/beaker/options/data/hosts.cfg +21 -0
- data/spec/beaker/options/data/opts.txt +6 -0
- data/spec/beaker/options/hosts_file_parser_spec.rb +30 -0
- data/spec/beaker/options/options_file_parser_spec.rb +23 -0
- data/spec/beaker/options/options_hash_spec.rb +111 -0
- data/spec/beaker/options/parser_spec.rb +172 -0
- data/spec/beaker/options/pe_version_scaper_spec.rb +15 -0
- data/spec/beaker/options/presets_spec.rb +24 -0
- data/spec/beaker/puppet_command_spec.rb +54 -21
- data/spec/beaker/shared/error_handler_spec.rb +40 -0
- data/spec/beaker/shared/host_handler_spec.rb +104 -0
- data/spec/beaker/shared/repetition_spec.rb +72 -0
- data/spec/beaker/test_suite_spec.rb +3 -16
- data/spec/beaker/utils/ntp_control_spec.rb +42 -0
- data/spec/beaker/utils/repo_control_spec.rb +168 -0
- data/spec/beaker/utils/setup_helper_spec.rb +82 -0
- data/spec/beaker/utils/validator_spec.rb +58 -0
- data/spec/helpers.rb +97 -0
- data/spec/matchers.rb +39 -0
- data/spec/mock_blimpy.rb +48 -0
- data/spec/mock_fission.rb +60 -0
- data/spec/mock_vsphere.rb +310 -0
- data/spec/mock_vsphere_helper.rb +183 -0
- data/spec/mocks.rb +83 -0
- data/spec/spec_helper.rb +8 -1
- metadata +106 -13
- data/beaker.rb +0 -10
- data/lib/beaker/options_parsing.rb +0 -323
- data/lib/beaker/test_config.rb +0 -148
- data/spec/beaker/options_parsing_spec.rb +0 -37
- data/spec/mocks_and_helpers.rb +0 -34
@@ -129,106 +129,159 @@ module Beaker
|
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
132
|
+
#Create the PE install command string based upon the host and options settings
|
133
|
+
# @param [Host] host The host that PE is to be installed on
|
134
|
+
# @param [Hash{Symbol=>String}] options The options
|
135
|
+
# @option options [String] :installer The name of the installer to use for upgrading/installing
|
136
|
+
# @option options [String] :pe_ver_win Default PE version to install or upgrade to on Windows hosts
|
137
|
+
# (Othersie uses individual Windows hosts pe_ver)
|
138
|
+
# @option options [String :pe_ver Default PE version to install or upgrade to
|
139
|
+
# (Otherwise uses individual hosts pe_ver)
|
140
|
+
# @example
|
141
|
+
# on host, "#{installer_cmd(host, options)} -a #{host['working_dir']}/answers"
|
142
|
+
# @api private
|
143
|
+
def installer_cmd(host, options)
|
144
|
+
if host['platform'] =~ /windows/
|
145
|
+
version = options[:pe_ver_win] || host['pe_ver']
|
146
|
+
"cd #{host['working_dir']} && msiexec.exe /qn /i puppet-enterprise-#{version}.msi"
|
147
|
+
else
|
148
|
+
version = options[:pe_ver] || host['pe_ver']
|
149
|
+
"cd #{host['working_dir']}/#{host['dist']} && ./#{options[:installer]}"
|
141
150
|
end
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
151
|
+
end
|
152
|
+
|
153
|
+
#Determine is a given URL is accessible
|
154
|
+
#@param [String] link The URL to examine
|
155
|
+
#@return [Boolean] true if the URL has a '200' HTTP response code, false otherwise
|
156
|
+
#@example
|
157
|
+
# extension = link_exists?("#{URL}.tar.gz") ? ".tar.gz" : ".tar"
|
158
|
+
# @api private
|
159
|
+
def link_exists?(link)
|
160
|
+
require "net/http"
|
161
|
+
require "open-uri"
|
162
|
+
url = URI.parse(link)
|
163
|
+
Net::HTTP.start(url.host, url.port) do |http|
|
164
|
+
return http.head(url.request_uri).code == "200"
|
149
165
|
end
|
150
|
-
|
166
|
+
end
|
167
|
+
|
168
|
+
#Determine the PE package to download/upload per-host, download/upload that package onto the host
|
169
|
+
#and unpack it.
|
170
|
+
# @param [Array<Host>] hosts The hosts to download/upload and unpack PE onto
|
171
|
+
# @param [Hash{Symbol=>Symbol, String}] options The options
|
172
|
+
# @option options [String] :pe_dir Default directory or URL to pull PE package from
|
173
|
+
# (Otherwise uses individual hosts pe_dir)
|
174
|
+
# @option options [String] :pe_ver Default PE version to install or upgrade to
|
175
|
+
# (Otherwise uses individual hosts pe_ver)
|
176
|
+
# @option options [String] :pe_ver_win Default PE version to install or upgrade to on Windows hosts
|
177
|
+
# (Otherwise uses individual Windows hosts pe_ver)
|
178
|
+
# @api private
|
179
|
+
def fetch_puppet(hosts, options)
|
180
|
+
hosts.each do |host|
|
181
|
+
windows = host['platform'] =~ /windows/
|
182
|
+
path = options[:pe_dir] || host['pe_dir']
|
151
183
|
local = File.directory?(path)
|
152
|
-
|
153
|
-
|
184
|
+
filename = ""
|
185
|
+
extension = ""
|
186
|
+
if windows
|
187
|
+
version = options[:pe_ver_win] || host['pe_ver']
|
188
|
+
filename = "puppet-enterprise-#{version}"
|
189
|
+
extension = ".msi"
|
190
|
+
else
|
191
|
+
filename = "#{host['dist']}"
|
154
192
|
extension = ""
|
155
|
-
if host['platform'] =~ /windows/
|
156
|
-
filename = "puppet-enterprise-#{version}"
|
157
|
-
extension = ".msi"
|
158
|
-
else
|
159
|
-
filename = "#{host['dist']}"
|
160
|
-
extension = ""
|
161
|
-
if local
|
162
|
-
extension = File.exists?("#{path}/#{filename}.tar.gz") ? ".tar.gz" : ".tar"
|
163
|
-
else
|
164
|
-
extension = link_exists?("#{path}/#{filename}.tar.gz") ? ".tar.gz" : ".tar"
|
165
|
-
end
|
166
|
-
end
|
167
193
|
if local
|
168
|
-
|
169
|
-
raise "attempting installation on #{host}, #{path}/#{filename}#{extension} does not exist"
|
170
|
-
end
|
171
|
-
scp_to host, "#{path}/#{filename}#{extension}", "#{host['working_dir']}/#{filename}#{extension}"
|
194
|
+
extension = File.exists?("#{path}/#{filename}.tar.gz") ? ".tar.gz" : ".tar"
|
172
195
|
else
|
173
|
-
|
174
|
-
raise "attempting installation on #{host}, #{path}/#{filename}#{extension} does not exist"
|
175
|
-
end
|
176
|
-
on host, "cd #{host['working_dir']}; curl #{path}/#{filename}#{extension} -o #{filename}#{extension}"
|
177
|
-
end
|
178
|
-
if extension =~ /gz/
|
179
|
-
on host, "cd #{host['working_dir']}; gunzip #{filename}#{extension}"
|
180
|
-
end
|
181
|
-
if extension =~ /tar/
|
182
|
-
on host, "cd #{host['working_dir']}; tar -xvf #{filename}.tar"
|
196
|
+
extension = link_exists?("#{path}/#{filename}.tar.gz") ? ".tar.gz" : ".tar"
|
183
197
|
end
|
184
198
|
end
|
199
|
+
if local
|
200
|
+
if not File.exists?("#{path}/#{filename}#{extension}")
|
201
|
+
raise "attempting installation on #{host}, #{path}/#{filename}#{extension} does not exist"
|
202
|
+
end
|
203
|
+
scp_to host, "#{path}/#{filename}#{extension}", "#{host['working_dir']}/#{filename}#{extension}"
|
204
|
+
else
|
205
|
+
if not link_exists?("#{path}/#{filename}#{extension}")
|
206
|
+
raise "attempting installation on #{host}, #{path}/#{filename}#{extension} does not exist"
|
207
|
+
end
|
208
|
+
on host, "cd #{host['working_dir']}; curl #{path}/#{filename}#{extension} -o #{filename}#{extension}"
|
209
|
+
end
|
210
|
+
if extension =~ /gz/
|
211
|
+
on host, "cd #{host['working_dir']}; gunzip #{filename}#{extension}"
|
212
|
+
end
|
213
|
+
if extension =~ /tar/
|
214
|
+
on host, "cd #{host['working_dir']}; tar -xvf #{filename}.tar"
|
215
|
+
end
|
185
216
|
end
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
217
|
+
end
|
218
|
+
|
219
|
+
#Perform a Puppet Enterprise upgrade or install
|
220
|
+
# @param [Array<Host>] hosts The hosts to install or upgrade PE on
|
221
|
+
# @param [Hash{Symbol=>Symbol, String}] options The options
|
222
|
+
# @option options [String] :pe_dir Default directory or URL to pull PE package from
|
223
|
+
# (Otherwise uses individual hosts pe_dir)
|
224
|
+
# @option options [String] :pe_ver Default PE version to install or upgrade to
|
225
|
+
# (Otherwise uses individual hosts pe_ver)
|
226
|
+
# @option options [String] :pe_ver_win Default PE version to install or upgrade to on Windows hosts
|
227
|
+
# (Otherwise uses individual Windows hosts pe_ver)
|
228
|
+
# @option options [String] :installer ('puppet-enterprise-installer') The name of the installer to use for upgrading/installing
|
229
|
+
# @option options [Symbol] :type (:install) One of :upgrade or :install
|
230
|
+
#
|
231
|
+
#
|
232
|
+
# @example
|
233
|
+
# do_install(hosts, {:type => :upgrade, :pe_dir => path, :pe_ver => version, :pe_ver_win => version_win})
|
234
|
+
#
|
235
|
+
# @api private
|
236
|
+
#
|
237
|
+
def do_install hosts, options = {}
|
238
|
+
options[:installer] = options[:installer] || 'puppet-enterprise-installer'
|
239
|
+
options[:type] = options[:type] || :install
|
190
240
|
hostcert='uname | grep -i sunos > /dev/null && hostname || hostname -s'
|
191
241
|
master_certname = on(master, hostcert).stdout.strip
|
192
|
-
|
193
|
-
|
194
|
-
real_agents = agents - special_nodes
|
242
|
+
pre30database = version_is_less(options[:pe_ver] || database['pe_ver'], '3.0')
|
243
|
+
pre30master = version_is_less(options[:pe_ver] || master['pe_ver'], '3.0')
|
195
244
|
|
196
245
|
# Set PE distribution for all the hosts, create working dir
|
197
246
|
use_all_tar = ENV['PE_USE_ALL_TAR'] == 'true'
|
198
247
|
hosts.each do |host|
|
199
|
-
|
200
|
-
|
248
|
+
if host['platform'] !~ /windows/
|
249
|
+
platform = use_all_tar ? 'all' : host['platform']
|
250
|
+
version = options[:pe_ver] || host['pe_ver']
|
251
|
+
host['dist'] = "puppet-enterprise-#{version}-#{platform}"
|
252
|
+
end
|
201
253
|
host['working_dir'] = "/tmp/" + Time.new.strftime("%Y-%m-%d_%H.%M.%S") #unique working dirs make me happy
|
202
254
|
on host, "mkdir #{host['working_dir']}"
|
203
255
|
end
|
204
256
|
|
205
|
-
fetch_puppet(hosts,
|
257
|
+
fetch_puppet(hosts, options)
|
206
258
|
|
207
259
|
hosts.each do |host|
|
208
260
|
# Database host was added in 3.0. Skip it if installing an older version
|
209
|
-
next if host == database and host != master and host != dashboard and
|
261
|
+
next if host == database and host != master and host != dashboard and pre30database
|
210
262
|
if host['platform'] =~ /windows/
|
211
|
-
on host, "#{installer_cmd(host,
|
263
|
+
on host, "#{installer_cmd(host, options)} PUPPET_MASTER_SERVER=#{master} PUPPET_AGENT_CERTNAME=#{host}"
|
212
264
|
else
|
265
|
+
answers = Beaker::Answers.answers(options[:pe_ver] || host['pe_ver'], hosts, master_certname, options)
|
213
266
|
create_remote_file host, "#{host['working_dir']}/answers", Beaker::Answers.answer_string(host, answers)
|
214
267
|
|
215
|
-
on host, "#{installer_cmd(host,
|
268
|
+
on host, "#{installer_cmd(host, options)} -a #{host['working_dir']}/answers"
|
216
269
|
end
|
217
270
|
end
|
218
271
|
|
219
272
|
|
220
|
-
# If we're installing a version less than 3.0, ignore the database host
|
273
|
+
# If we're installing a database version less than 3.0, ignore the database host
|
221
274
|
install_hosts = hosts.dup
|
222
|
-
install_hosts.delete(database) if
|
275
|
+
install_hosts.delete(database) if pre30database and database != master and database != dashboard
|
223
276
|
|
224
277
|
# On each agent, we ensure the certificate is signed then shut down the agent
|
225
278
|
install_hosts.each do |host|
|
226
|
-
|
227
|
-
|
279
|
+
sign_certificate_for(host)
|
280
|
+
stop_agent_on(host)
|
228
281
|
end
|
229
282
|
|
230
|
-
# Wait for PuppetDB to be totally up and running
|
231
|
-
sleep_until_puppetdb_started(database) unless
|
283
|
+
# Wait for PuppetDB to be totally up and running (post 3.0 version of pe only)
|
284
|
+
sleep_until_puppetdb_started(database) unless pre30database
|
232
285
|
|
233
286
|
# Run the agent once to ensure everything is in the dashboard
|
234
287
|
install_hosts.each do |host|
|
@@ -239,7 +292,7 @@ module Beaker
|
|
239
292
|
# and would cause puppetdb to be bounced by the agent run. By sleeping
|
240
293
|
# again here, we ensure that if that bounce happens during an upgrade
|
241
294
|
# test we won't fail early in the install process.
|
242
|
-
if
|
295
|
+
if host['pe_ver'] == '3.0.0' and host == database
|
243
296
|
sleep_until_puppetdb_started(database)
|
244
297
|
end
|
245
298
|
end
|
@@ -248,7 +301,7 @@ module Beaker
|
|
248
301
|
wait_for_host_in_dashboard(host)
|
249
302
|
end
|
250
303
|
|
251
|
-
if
|
304
|
+
if pre30master
|
252
305
|
task = 'nodegroup:add_all_nodes group=default'
|
253
306
|
else
|
254
307
|
task = 'defaultgroup:ensure_default_group'
|
@@ -260,37 +313,105 @@ module Beaker
|
|
260
313
|
on install_hosts, puppet_agent('-t'), :acceptable_exit_codes => [0,2]
|
261
314
|
end
|
262
315
|
|
263
|
-
#
|
264
|
-
|
316
|
+
#Is PE version a less than PE version b
|
317
|
+
#@param [String] a A PE version of the from '\d.\d.\d.*'
|
318
|
+
#@param [String] b A PE version of the form '\d.\d.\d.*'
|
319
|
+
#@return [Boolean] true if a is less than b, otherwise return false
|
320
|
+
#
|
321
|
+
#@note 3.0.0-160-gac44cfb is greater than 3.0.0, and 2.8.2
|
322
|
+
# @!visibility private
|
265
323
|
def version_is_less a, b
|
266
|
-
|
267
|
-
|
268
|
-
(0...
|
269
|
-
if i <
|
270
|
-
if
|
324
|
+
a_nums = a.split('-')[0].split('.')
|
325
|
+
b_nums = b.split('-')[0].split('.')
|
326
|
+
(0...a_nums.length).each do |i|
|
327
|
+
if i < b_nums.length
|
328
|
+
if a_nums[i] < b_nums[i]
|
271
329
|
return true
|
272
|
-
elsif
|
330
|
+
elsif a_nums[i] > b_nums[i]
|
273
331
|
return false
|
274
332
|
end
|
275
333
|
else
|
276
334
|
return false
|
277
335
|
end
|
278
336
|
end
|
337
|
+
#checks all dots, they are equal so examine the rest
|
338
|
+
a_rest = a.split('-', 2)[1]
|
339
|
+
b_rest = b.split('-', 2)[1]
|
340
|
+
if a_rest and b_rest and a_rest < b_rest
|
341
|
+
return false
|
342
|
+
elsif a_rest and not b_rest
|
343
|
+
return false
|
344
|
+
elsif not a_rest and b_rest
|
345
|
+
return true
|
346
|
+
end
|
279
347
|
return false
|
280
348
|
end
|
281
349
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
350
|
+
#Sort array of hosts so that it has the correct order for PE installation based upon each host's role
|
351
|
+
# @example
|
352
|
+
# h = sorted_hosts
|
353
|
+
#
|
354
|
+
# @note Order for installation should be
|
355
|
+
# First : master
|
356
|
+
# Second: database host (if not same as master)
|
357
|
+
# Third: dashboard (if not same as master or database)
|
358
|
+
# Fourth: everything else
|
359
|
+
#
|
360
|
+
# @!visibility private
|
361
|
+
def sorted_hosts
|
362
|
+
special_nodes = [master, database, dashboard].uniq
|
363
|
+
real_agents = agents - special_nodes
|
364
|
+
special_nodes + real_agents
|
286
365
|
end
|
287
366
|
|
288
|
-
|
367
|
+
#Install PE based upon host configuration and options
|
368
|
+
# @example
|
369
|
+
# install_pe
|
370
|
+
#
|
371
|
+
# @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.
|
372
|
+
# Install file names are assumed to be of the format puppet-enterprise-VERSION-PLATFORM.(tar)|(tar.gz)
|
373
|
+
# for Unix like systems and puppet-enterprise-VERSION.msi for Windows systems.
|
374
|
+
#
|
375
|
+
# @api dsl
|
376
|
+
def install_pe
|
377
|
+
#process the version files if necessary
|
378
|
+
hosts.each do |host|
|
379
|
+
if host['platform'] =~ /windows/
|
380
|
+
host['pe_ver'] = host['pe_ver'] ||
|
381
|
+
Beaker::Options::PEVersionScraper.load_pe_version(host[:pe_dir] || options[:pe_dir], options[:pe_version_file_win])
|
382
|
+
else
|
383
|
+
host['pe_ver'] = host['pe_ver'] ||
|
384
|
+
Beaker::Options::PEVersionScraper.load_pe_version(host[:pe_dir] || options[:pe_dir], options[:pe_version_file])
|
385
|
+
end
|
386
|
+
end
|
387
|
+
do_install sorted_hosts
|
388
|
+
end
|
389
|
+
|
390
|
+
#Upgrade PE based upon host configuration and options
|
391
|
+
# @param [String] path A path (either local directory or a URL to a listing of PE builds).
|
392
|
+
# Will contain a LATEST file indicating the latest build to install.
|
393
|
+
# @example
|
394
|
+
# upgrade_pe("http://neptune.puppetlabs.lan/3.0/ci-ready/")
|
395
|
+
#
|
396
|
+
# @note Install file names are assumed to be of the format puppet-enterprise-VERSION-PLATFORM.(tar)|(tar.gz)
|
397
|
+
# for Unix like systems and puppet-enterprise-VERSION.msi for Windows systems.
|
398
|
+
# @api dsl
|
399
|
+
def upgrade_pe path
|
400
|
+
version = Options::PEVersionScraper.load_pe_version(path, options[:pe_version_file])
|
401
|
+
version_win = Options::PEVersionScraper.load_pe_version(path, options[:pe_version_file_win])
|
289
402
|
pre_30 = version_is_less(version, '3.0')
|
290
403
|
if pre_30
|
291
|
-
do_install(
|
404
|
+
do_install(sorted_hosts, {:type => :upgrade, :pe_dir => path, :pe_ver => version, :pe_ver_win => version_win, :installer => 'puppet-enterprise-upgrader'})
|
292
405
|
else
|
293
|
-
do_install(
|
406
|
+
do_install(sorted_hosts, {:type => :upgrade, :pe_dir => path, :pe_ver => version, :pe_ver_win => version_win})
|
407
|
+
end
|
408
|
+
#at this point we've completed a successful upgrade, update the host pe_ver to reflect that
|
409
|
+
hosts.each do |host|
|
410
|
+
if host['platform'] =~ /windows/
|
411
|
+
host['pe_ver'] = version_win
|
412
|
+
else
|
413
|
+
host['pe_ver'] = version
|
414
|
+
end
|
294
415
|
end
|
295
416
|
end
|
296
417
|
|
data/lib/beaker/dsl/roles.rb
CHANGED
@@ -68,6 +68,44 @@ module Beaker
|
|
68
68
|
find_only_one :dashboard
|
69
69
|
end
|
70
70
|
|
71
|
+
# The default host
|
72
|
+
# - if only one host defined, then that host
|
73
|
+
# OR
|
74
|
+
# - host with 'default' as a role
|
75
|
+
# OR
|
76
|
+
# - host with 'master' as a role
|
77
|
+
#
|
78
|
+
# @return [Array<Host>]
|
79
|
+
# @raise [Beaker::DSL::Outcomes::FailTest] if no default host is found
|
80
|
+
#
|
81
|
+
# @example Basic usage
|
82
|
+
# on, default, "curl https://#{database}/nodes/#{agent}"
|
83
|
+
#
|
84
|
+
def default
|
85
|
+
if hosts.length == 1
|
86
|
+
return hosts[0]
|
87
|
+
elsif any_hosts_as? :default
|
88
|
+
return find_only_one :default
|
89
|
+
elsif any_hosts_as? :master
|
90
|
+
return find_only_one :master
|
91
|
+
else
|
92
|
+
raise DSL::Outcomes::FailTest, "no default host specified"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Determine if there is a host or hosts with the given role defined
|
97
|
+
# @return [Boolean] True if there is a host with role, false otherwise
|
98
|
+
#
|
99
|
+
# @example Usage
|
100
|
+
# if any_hosts_as?(:master)
|
101
|
+
# puts "master is defined"
|
102
|
+
# end
|
103
|
+
#
|
104
|
+
# @api public
|
105
|
+
def any_hosts_as?(role)
|
106
|
+
hosts_as(role).length > 0
|
107
|
+
end
|
108
|
+
|
71
109
|
# Select hosts that include a desired role from #hosts
|
72
110
|
#
|
73
111
|
# @param [String, Symbol] desired_role The role to select for
|
@@ -91,6 +129,8 @@ module Beaker
|
|
91
129
|
# the specified role is NOT found.
|
92
130
|
def find_only_one role
|
93
131
|
only_host_with_role(hosts, role)
|
132
|
+
rescue ArgumentError => e
|
133
|
+
raise DSL::Outcomes::FailTest, e.to_s
|
94
134
|
end
|
95
135
|
end
|
96
136
|
end
|
data/lib/beaker/host.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'socket'
|
2
|
-
require 'timeout'
|
3
2
|
|
4
3
|
%w(command ssh_connection).each do |lib|
|
5
4
|
begin
|
@@ -11,6 +10,7 @@ end
|
|
11
10
|
|
12
11
|
module Beaker
|
13
12
|
class Host
|
13
|
+
SELECT_TIMEOUT = 30
|
14
14
|
|
15
15
|
# This class providers array syntax for using puppet --configprint on a host
|
16
16
|
class PuppetConfigReader
|
@@ -25,34 +25,34 @@ module Beaker
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
def self.create name, options
|
29
|
-
case
|
28
|
+
def self.create name, options
|
29
|
+
case options['HOSTS'][name]['platform']
|
30
30
|
when /windows/
|
31
|
-
Windows::Host.new name, options
|
31
|
+
Windows::Host.new name, options
|
32
32
|
when /aix/
|
33
|
-
Aix::Host.new name, options
|
33
|
+
Aix::Host.new name, options
|
34
34
|
else
|
35
|
-
Unix::Host.new name, options
|
35
|
+
Unix::Host.new name, options
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
attr_accessor :logger
|
40
40
|
attr_reader :name, :defaults
|
41
|
-
def initialize name, options
|
41
|
+
def initialize name, options
|
42
42
|
@logger = options[:logger]
|
43
|
-
@name, @options
|
43
|
+
@name, @options = name.to_s, options.dup
|
44
44
|
|
45
45
|
# This is annoying and its because of drift/lack of enforcement/lack of having
|
46
46
|
# a explict relationship between our defaults, our setup steps and how they're
|
47
47
|
# related through 'type' and the differences between the assumption of our two
|
48
48
|
# configurations we have for many of our products
|
49
49
|
type = is_pe? ? :pe : :foss
|
50
|
-
@defaults = merge_defaults_for_type @
|
50
|
+
@defaults = merge_defaults_for_type @options, type
|
51
51
|
end
|
52
52
|
|
53
|
-
def merge_defaults_for_type
|
53
|
+
def merge_defaults_for_type options, type
|
54
54
|
defaults = self.class.send "#{type}_defaults".to_sym
|
55
|
-
defaults.merge(
|
55
|
+
defaults.merge(options.merge((options['HOSTS'][name])))
|
56
56
|
end
|
57
57
|
|
58
58
|
def node_name
|
@@ -63,18 +63,26 @@ module Beaker
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def port_open? port
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
66
|
+
s = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
67
|
+
sa = Socket.sockaddr_in(port, reachable_name)
|
68
|
+
|
69
|
+
begin
|
70
|
+
s.connect_nonblock(sa)
|
71
|
+
rescue Errno::EINPROGRESS
|
72
|
+
if IO.select(nil, [s], nil, SELECT_TIMEOUT)
|
73
|
+
begin
|
74
|
+
s.connect_nonblock(sa)
|
75
|
+
rescue Errno::EISCONN
|
76
|
+
return true
|
77
|
+
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
|
78
|
+
return false
|
79
|
+
end
|
72
80
|
end
|
73
81
|
end
|
82
|
+
return false
|
74
83
|
end
|
75
84
|
|
76
85
|
def up?
|
77
|
-
require 'socket'
|
78
86
|
begin
|
79
87
|
Socket.getaddrinfo( reachable_name, nil )
|
80
88
|
return true
|
@@ -120,7 +128,7 @@ module Beaker
|
|
120
128
|
end
|
121
129
|
|
122
130
|
def is_pe?
|
123
|
-
@
|
131
|
+
@options.is_pe?
|
124
132
|
end
|
125
133
|
|
126
134
|
def connection
|
@@ -161,7 +169,7 @@ module Beaker
|
|
161
169
|
# No, TestCase has the knowledge about whether its failed, checking acceptable
|
162
170
|
# exit codes at the host level and then raising...
|
163
171
|
# is it necessary to break execution??
|
164
|
-
unless result.exit_code_in?(options[:acceptable_exit_codes] ||
|
172
|
+
unless result.exit_code_in?(Array(options[:acceptable_exit_codes] || 0))
|
165
173
|
limit = 10
|
166
174
|
raise "Host '#{self}' exited with #{result.exit_code} running:\n #{cmdline}\nLast #{limit} lines of output were:\n#{result.formatted_output(limit)}"
|
167
175
|
end
|