beaker-puppet 1.29.0 → 2.0.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 +4 -4
- data/.github/dependabot.yml +9 -0
- data/.github/workflows/release.yml +2 -2
- data/.github/workflows/test.yml +28 -7
- data/.rubocop.yml +5 -0
- data/.rubocop_todo.yml +842 -0
- data/CHANGELOG.md +31 -0
- data/Gemfile +5 -20
- data/Rakefile +64 -169
- data/acceptance/config/acceptance-options.rb +3 -3
- data/acceptance/config/gem/acceptance-options.rb +8 -8
- data/acceptance/config/git/acceptance-options.rb +8 -8
- data/acceptance/config/pkg/acceptance-options.rb +7 -7
- data/acceptance/pre_suite/gem/install.rb +6 -6
- data/acceptance/pre_suite/git/install.rb +22 -22
- data/acceptance/pre_suite/pkg/install.rb +3 -3
- data/acceptance/tests/backwards_compatible.rb +6 -7
- data/acceptance/tests/clone_git_repo_on_test.rb +12 -13
- data/acceptance/tests/create_tmpdir_on_test.rb +13 -9
- data/acceptance/tests/install_smoke_test.rb +5 -4
- data/acceptance/tests/stub_host.rb +11 -10
- data/acceptance/tests/web_helpers_test.rb +11 -10
- data/beaker-puppet.gemspec +16 -23
- data/bin/beaker-puppet +2 -4
- data/lib/beaker-puppet/helpers/facter_helpers.rb +9 -7
- data/lib/beaker-puppet/helpers/host_helpers.rb +10 -7
- data/lib/beaker-puppet/helpers/puppet_helpers.rb +151 -160
- data/lib/beaker-puppet/helpers/rake_helpers.rb +1 -1
- data/lib/beaker-puppet/helpers/tk_helpers.rb +22 -28
- data/lib/beaker-puppet/install_utils/aio_defaults.rb +39 -43
- data/lib/beaker-puppet/install_utils/ezbake_utils.rb +34 -42
- data/lib/beaker-puppet/install_utils/foss_defaults.rb +134 -138
- data/lib/beaker-puppet/install_utils/foss_utils.rb +293 -320
- data/lib/beaker-puppet/install_utils/module_utils.rb +58 -70
- data/lib/beaker-puppet/install_utils/puppet5.rb +30 -35
- data/lib/beaker-puppet/install_utils/puppet_utils.rb +58 -68
- data/lib/beaker-puppet/install_utils/windows_utils.rb +34 -36
- data/lib/beaker-puppet/version.rb +1 -1
- data/lib/beaker-puppet/wrappers.rb +13 -14
- data/lib/beaker-puppet.rb +4 -5
- data/setup/aio/010_Install_Puppet_Agent.rb +5 -6
- data/setup/common/000-delete-puppet-when-none.rb +2 -4
- data/setup/common/003_solaris_cert_fix.rb +74 -70
- data/setup/common/005_redhat_subscription_fix.rb +3 -2
- data/setup/common/011_Install_Puppet_Server.rb +7 -9
- data/setup/common/012_Finalize_Installs.rb +5 -5
- data/setup/common/025_StopFirewall.rb +1 -1
- data/setup/common/030_StopSssd.rb +2 -2
- data/setup/common/040_ValidateSignCert.rb +10 -12
- data/setup/common/045_EnsureMasterStarted.rb +2 -2
- data/setup/gem/010_GemInstall.rb +5 -4
- data/setup/git/000_EnvSetup.rb +48 -48
- data/setup/git/010_TestSetup.rb +13 -12
- data/setup/git/020_PuppetUserAndGroup.rb +3 -2
- data/setup/git/060_InstallModules.rb +14 -14
- data/setup/git/070_InstallCACerts.rb +82 -82
- data/spec/beaker-puppet/helpers/facter_helpers_spec.rb +22 -24
- data/spec/beaker-puppet/helpers/host_helpers_spec.rb +10 -6
- data/spec/beaker-puppet/helpers/puppet_helpers_spec.rb +506 -517
- data/spec/beaker-puppet/helpers/tk_helpers_spec.rb +20 -24
- data/spec/beaker-puppet/install_utils/ezbake_utils_spec.rb +86 -90
- data/spec/beaker-puppet/install_utils/foss_utils_spec.rb +636 -599
- data/spec/beaker-puppet/install_utils/module_utils_spec.rb +125 -116
- data/spec/beaker-puppet/install_utils/puppet5_spec.rb +159 -165
- data/spec/beaker-puppet/install_utils/puppet_utils_spec.rb +92 -77
- data/spec/beaker-puppet/install_utils/windows_utils_spec.rb +101 -89
- data/spec/beaker-puppet/wrappers_spec.rb +10 -10
- data/spec/helpers.rb +85 -91
- data/tasks/ci.rake +171 -179
- metadata +33 -62
- data/setup/common/020_InstallCumulusModules.rb +0 -13
- data/setup/common/021_InstallAristaModuleMasters.rb +0 -12
- data/setup/common/022_InstallAristaModuleAgents.rb +0 -13
@@ -1,4 +1,3 @@
|
|
1
|
-
# coding: utf-8
|
2
1
|
require 'timeout'
|
3
2
|
require 'inifile'
|
4
3
|
require 'resolv'
|
@@ -9,10 +8,9 @@ module Beaker
|
|
9
8
|
# Methods that help you interact with your puppet installation, puppet must be installed
|
10
9
|
# for these methods to execute correctly
|
11
10
|
module PuppetHelpers
|
12
|
-
|
13
11
|
# Return the regular expression pattern for an IPv4 address
|
14
12
|
def ipv4_regex
|
15
|
-
|
13
|
+
/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/
|
16
14
|
end
|
17
15
|
|
18
16
|
# Return the IP address that given hostname returns when resolved on
|
@@ -23,8 +21,8 @@ module Beaker
|
|
23
21
|
#
|
24
22
|
# @return [String, nil] An IP address, or nil.
|
25
23
|
def resolve_hostname_on(host, hostname)
|
26
|
-
match = curl_on(host, "--verbose #{hostname}", :
|
27
|
-
|
24
|
+
match = curl_on(host, "--verbose #{hostname}", accept_all_exit_codes: true).stderr.match(ipv4_regex)
|
25
|
+
match ? match[0] : nil
|
28
26
|
end
|
29
27
|
|
30
28
|
# @!macro [new] common_opts
|
@@ -152,13 +150,19 @@ module Beaker
|
|
152
150
|
# end
|
153
151
|
#
|
154
152
|
def with_puppet_running_on(host, conf_opts, testdir = host.tmpdir(File.basename(@path)), &block)
|
155
|
-
|
153
|
+
unless conf_opts.is_a?(Hash)
|
154
|
+
raise(ArgumentError,
|
155
|
+
"with_puppet_running_on's conf_opts must be a Hash. You provided a #{conf_opts.class}: '#{conf_opts}'")
|
156
|
+
end
|
157
|
+
|
156
158
|
cmdline_args = conf_opts[:__commandline_args__]
|
157
159
|
service_args = conf_opts[:__service_args__] || {}
|
158
160
|
restart_when_done = true
|
159
161
|
restart_when_done = host[:restart_when_done] if host.has_key?(:restart_when_done)
|
160
162
|
restart_when_done = conf_opts.fetch(:restart_when_done, restart_when_done)
|
161
|
-
conf_opts = conf_opts.reject
|
163
|
+
conf_opts = conf_opts.reject do |k, v|
|
164
|
+
%i[__commandline_args__ __service_args__ restart_when_done].include?(k)
|
165
|
+
end
|
162
166
|
|
163
167
|
curl_retries = host['master-start-curl-retries'] || options['master-start-curl-retries']
|
164
168
|
logger.debug "Setting curl retries to #{curl_retries}"
|
@@ -168,29 +172,29 @@ module Beaker
|
|
168
172
|
vardir = puppet_config(host, 'vardir', section: 'master')
|
169
173
|
|
170
174
|
if cmdline_args
|
171
|
-
split_args = cmdline_args.split
|
175
|
+
split_args = cmdline_args.split
|
172
176
|
|
173
177
|
split_args.each do |arg|
|
174
178
|
case arg
|
175
179
|
when /--confdir=(.*)/
|
176
|
-
confdir =
|
180
|
+
confdir = ::Regexp.last_match(1)
|
177
181
|
when /--vardir=(.*)/
|
178
|
-
vardir =
|
182
|
+
vardir = ::Regexp.last_match(1)
|
179
183
|
end
|
180
184
|
end
|
181
185
|
end
|
182
186
|
|
183
187
|
puppetserver_opts = {
|
184
|
-
|
185
|
-
|
186
|
-
|
188
|
+
'jruby-puppet' => {
|
189
|
+
'master-conf-dir' => confdir,
|
190
|
+
'master-var-dir' => vardir,
|
191
|
+
},
|
192
|
+
'certificate-authority' => {
|
193
|
+
'allow-subject-alt-names' => true,
|
187
194
|
},
|
188
|
-
"certificate-authority" => {
|
189
|
-
"allow-subject-alt-names" => true
|
190
|
-
}
|
191
195
|
}
|
192
196
|
|
193
|
-
puppetserver_conf = File.join("#{host['puppetserver-confdir']}",
|
197
|
+
puppetserver_conf = File.join("#{host['puppetserver-confdir']}", 'puppetserver.conf')
|
194
198
|
modify_tk_config(host, puppetserver_conf, puppetserver_opts)
|
195
199
|
end
|
196
200
|
begin
|
@@ -201,14 +205,14 @@ module Beaker
|
|
201
205
|
lay_down_new_puppet_conf host, conf_opts, testdir
|
202
206
|
|
203
207
|
if host.use_service_scripts? && !service_args[:bypass_service_script]
|
204
|
-
bounce_service(
|
208
|
+
bounce_service(host, host['puppetservice'], curl_retries)
|
205
209
|
else
|
206
|
-
puppet_master_started = start_puppet_from_source_on!(
|
210
|
+
puppet_master_started = start_puppet_from_source_on!(host, cmdline_args)
|
207
211
|
end
|
208
212
|
|
209
213
|
yield self if block_given?
|
210
214
|
|
211
|
-
|
215
|
+
# FIXME: these test-flow-control exceptions should be using throw
|
212
216
|
# they can be caught in test_case. current layout dows not allow it
|
213
217
|
rescue Beaker::DSL::Outcomes::PassTest => early_assertion
|
214
218
|
pass_test(early_assertion)
|
@@ -223,41 +227,34 @@ module Beaker
|
|
223
227
|
rescue Exception => early_exception
|
224
228
|
original_exception = RuntimeError.new("PuppetAcceptance::DSL::Helpers.with_puppet_running_on failed (check backtrace for location) because: #{early_exception}\n#{early_exception.backtrace.join("\n")}\n")
|
225
229
|
raise(original_exception)
|
226
|
-
|
227
230
|
ensure
|
228
231
|
begin
|
229
|
-
|
230
232
|
if host.use_service_scripts? && !service_args[:bypass_service_script]
|
231
|
-
restore_puppet_conf_from_backup(
|
233
|
+
restore_puppet_conf_from_backup(host, backup_file)
|
232
234
|
if restart_when_done
|
233
|
-
bounce_service(
|
235
|
+
bounce_service(host, host['puppetservice'], curl_retries)
|
234
236
|
else
|
235
237
|
host.exec puppet_resource('service', host['puppetservice'], 'ensure=stopped')
|
236
238
|
end
|
237
239
|
else
|
238
240
|
if puppet_master_started
|
239
|
-
stop_puppet_from_source_on(
|
241
|
+
stop_puppet_from_source_on(host)
|
240
242
|
else
|
241
243
|
dump_puppet_log(host)
|
242
244
|
end
|
243
|
-
restore_puppet_conf_from_backup(
|
245
|
+
restore_puppet_conf_from_backup(host, backup_file)
|
244
246
|
end
|
245
|
-
|
246
247
|
rescue Exception => teardown_exception
|
247
248
|
begin
|
248
|
-
|
249
|
-
dump_puppet_log(host)
|
250
|
-
end
|
249
|
+
dump_puppet_log(host) unless host.is_pe?
|
251
250
|
rescue Exception => dumping_exception
|
252
251
|
logger.error("Raised during attempt to dump puppet logs: #{dumping_exception}")
|
253
252
|
end
|
254
253
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
raise teardown_exception
|
260
|
-
end
|
254
|
+
raise teardown_exception unless original_exception
|
255
|
+
|
256
|
+
logger.error("Raised during attempt to teardown with_puppet_running_on: #{teardown_exception}\n---\n")
|
257
|
+
raise original_exception
|
261
258
|
end
|
262
259
|
end
|
263
260
|
end
|
@@ -265,44 +262,44 @@ module Beaker
|
|
265
262
|
# Test Puppet running in a certain run mode with specific options,
|
266
263
|
# on the default host
|
267
264
|
# @see #with_puppet_running_on
|
268
|
-
def with_puppet_running
|
265
|
+
def with_puppet_running(conf_opts, testdir = host.tmpdir(File.basename(@path)), &block)
|
269
266
|
with_puppet_running_on(default, conf_opts, testdir, &block)
|
270
267
|
end
|
271
268
|
|
272
269
|
# @!visibility private
|
273
|
-
def restore_puppet_conf_from_backup(
|
270
|
+
def restore_puppet_conf_from_backup(host, backup_file)
|
274
271
|
puppet_conf = puppet_config(host, 'config', section: 'master')
|
275
272
|
|
276
273
|
if backup_file
|
277
|
-
host.exec(
|
274
|
+
host.exec(Command.new("if [ -f '#{backup_file}' ]; then " +
|
278
275
|
"cat '#{backup_file}' > " +
|
279
276
|
"'#{puppet_conf}'; " +
|
280
277
|
"rm -f '#{backup_file}'; " +
|
281
|
-
|
278
|
+
'fi'))
|
282
279
|
else
|
283
|
-
host.exec(
|
280
|
+
host.exec(Command.new("rm -f '#{puppet_conf}'"))
|
284
281
|
end
|
285
|
-
|
286
282
|
end
|
287
283
|
|
288
284
|
# @!visibility private
|
289
|
-
def start_puppet_from_source_on!
|
290
|
-
host.exec(
|
285
|
+
def start_puppet_from_source_on!(host, args = '')
|
286
|
+
host.exec(puppet('master', args))
|
291
287
|
|
292
288
|
logger.debug 'Waiting for the puppet master to start'
|
293
|
-
unless port_open_within?(
|
294
|
-
|
295
|
-
|
289
|
+
raise Beaker::DSL::FailTest, 'Puppet master did not start in a timely fashion' unless port_open_within?(
|
290
|
+
host, 8140, 10
|
291
|
+
)
|
292
|
+
|
296
293
|
logger.debug 'The puppet master has started'
|
297
|
-
|
294
|
+
true
|
298
295
|
end
|
299
296
|
|
300
297
|
# @!visibility private
|
301
|
-
def stop_puppet_from_source_on(
|
302
|
-
pid = host.exec(
|
303
|
-
host.exec(
|
298
|
+
def stop_puppet_from_source_on(host)
|
299
|
+
pid = host.exec(Command.new('cat `puppet config print --section master pidfile`')).stdout.chomp
|
300
|
+
host.exec(Command.new("kill #{pid}"))
|
304
301
|
Timeout.timeout(10) do
|
305
|
-
while host.exec(
|
302
|
+
while host.exec(Command.new("kill -0 #{pid}"), acceptable_exit_codes: [0, 1]).exit_code == 0
|
306
303
|
# until kill -0 finds no process and we know that puppet has finished cleaning up
|
307
304
|
sleep 1
|
308
305
|
end
|
@@ -312,40 +309,38 @@ module Beaker
|
|
312
309
|
# @!visibility private
|
313
310
|
def dump_puppet_log(host)
|
314
311
|
syslogfile = case host['platform']
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
312
|
+
when /fedora|centos|el|redhat|scientific/ then '/var/log/messages'
|
313
|
+
when /ubuntu|debian/ then '/var/log/syslog'
|
314
|
+
else return
|
315
|
+
end
|
319
316
|
|
320
317
|
logger.notify "\n*************************"
|
321
|
-
logger.notify
|
322
|
-
logger.notify
|
323
|
-
host.exec(
|
318
|
+
logger.notify '* Dumping master log *'
|
319
|
+
logger.notify '*************************'
|
320
|
+
host.exec(Command.new("tail -n 100 #{syslogfile}"), acceptable_exit_codes: [0, 1])
|
324
321
|
logger.notify "*************************\n"
|
325
322
|
end
|
326
323
|
|
327
324
|
# @!visibility private
|
328
|
-
def lay_down_new_puppet_conf(
|
325
|
+
def lay_down_new_puppet_conf(host, configuration_options, testdir)
|
329
326
|
puppetconf_main = puppet_config(host, 'config', section: 'master')
|
330
327
|
puppetconf_filename = File.basename(puppetconf_main)
|
331
328
|
puppetconf_test = File.join(testdir, puppetconf_filename)
|
332
329
|
|
333
|
-
new_conf = puppet_conf_for(
|
330
|
+
new_conf = puppet_conf_for(host, configuration_options)
|
334
331
|
create_remote_file host, puppetconf_test, new_conf.to_s
|
335
332
|
|
336
333
|
host.exec(
|
337
|
-
Command.new(
|
338
|
-
:
|
334
|
+
Command.new("cat #{puppetconf_test} > #{puppetconf_main}"),
|
335
|
+
silent: true,
|
339
336
|
)
|
340
|
-
host.exec(
|
337
|
+
host.exec(Command.new("cat #{puppetconf_main}"))
|
341
338
|
end
|
342
339
|
|
343
340
|
# @!visibility private
|
344
|
-
def puppet_conf_for
|
345
|
-
puppetconf = host.exec(
|
346
|
-
|
347
|
-
|
348
|
-
new_conf
|
341
|
+
def puppet_conf_for(host, conf_opts)
|
342
|
+
puppetconf = host.exec(Command.new("cat #{puppet_config(host, 'config', section: 'master')}")).stdout
|
343
|
+
IniFile.new(default: 'main', content: puppetconf).merge(conf_opts)
|
349
344
|
end
|
350
345
|
|
351
346
|
# Restarts the named puppet service
|
@@ -357,7 +352,7 @@ module Beaker
|
|
357
352
|
#
|
358
353
|
# @return [Result] Result of last status check
|
359
354
|
# @!visibility private
|
360
|
-
def bounce_service
|
355
|
+
def bounce_service(host, service, curl_retries = nil, port = nil)
|
361
356
|
curl_retries = 120 if curl_retries.nil?
|
362
357
|
port = options[:puppetserver_port] if port.nil?
|
363
358
|
if host.graceful_restarts?
|
@@ -366,13 +361,12 @@ module Beaker
|
|
366
361
|
host.exec(Command.new("#{apachectl_path} graceful"))
|
367
362
|
else
|
368
363
|
result = host.exec(Command.new("service #{service} reload"),
|
369
|
-
:
|
370
|
-
if result.exit_code == 0
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
end
|
364
|
+
acceptable_exit_codes: [0, 1, 3])
|
365
|
+
return result if result.exit_code == 0
|
366
|
+
|
367
|
+
host.exec puppet_resource('service', service, 'ensure=stopped')
|
368
|
+
host.exec puppet_resource('service', service, 'ensure=running')
|
369
|
+
|
376
370
|
end
|
377
371
|
curl_with_retries(" #{service} ", host, "https://localhost:#{port}", [35, 60], curl_retries)
|
378
372
|
end
|
@@ -454,7 +448,7 @@ module Beaker
|
|
454
448
|
# object, or nil. Check {Beaker::Shared::HostManager#run_block_on} for
|
455
449
|
# more details on this.
|
456
450
|
def apply_manifest_on(host, manifest, opts = {}, &block)
|
457
|
-
block_on host, opts do |
|
451
|
+
block_on host, opts do |host|
|
458
452
|
on_options = {}
|
459
453
|
on_options[:acceptable_exit_codes] = Array(opts[:acceptable_exit_codes])
|
460
454
|
|
@@ -475,7 +469,8 @@ module Beaker
|
|
475
469
|
# "... an exit code of '2' means there were changes, an exit code of
|
476
470
|
# '4' means there were failures during the transaction, and an exit
|
477
471
|
# code of '6' means there were both changes and failures."
|
478
|
-
if [opts[:catch_changes],opts[:catch_failures],opts[:expect_failures],
|
472
|
+
if [opts[:catch_changes], opts[:catch_failures], opts[:expect_failures],
|
473
|
+
opts[:expect_changes],].compact.length > 1
|
479
474
|
raise(ArgumentError,
|
480
475
|
'Cannot specify more than one of `catch_failures`, ' +
|
481
476
|
'`catch_changes`, `expect_failures`, or `expect_changes` ' +
|
@@ -515,15 +510,13 @@ module Beaker
|
|
515
510
|
# that they want to set for the puppet command. If so, we set the final
|
516
511
|
# value of *args to a new hash with just one entry (the value of which
|
517
512
|
# is our environment variables hash)
|
518
|
-
if opts.has_key?(:environment)
|
519
|
-
puppet_apply_opts['ENV'] = opts[:environment]
|
520
|
-
end
|
513
|
+
puppet_apply_opts['ENV'] = opts[:environment] if opts.has_key?(:environment)
|
521
514
|
|
522
|
-
file_path = host.tmpfile(%(apply_manifest_#{Time.now.strftime(
|
515
|
+
file_path = host.tmpfile(%(apply_manifest_#{Time.now.strftime('%H%M%S%L')}.pp))
|
523
516
|
create_remote_file(host, file_path, manifest + "\n")
|
524
517
|
|
525
518
|
if host[:default_apply_opts].respond_to? :merge
|
526
|
-
puppet_apply_opts = host[:default_apply_opts].merge(
|
519
|
+
puppet_apply_opts = host[:default_apply_opts].merge(puppet_apply_opts)
|
527
520
|
end
|
528
521
|
|
529
522
|
on host, puppet('apply', file_path, puppet_apply_opts), on_options, &block
|
@@ -537,9 +530,9 @@ module Beaker
|
|
537
530
|
end
|
538
531
|
|
539
532
|
# @deprecated
|
540
|
-
def run_agent_on(host, arg='--no-daemonize --verbose --onetime --test',
|
541
|
-
options={}, &block)
|
542
|
-
block_on host do |
|
533
|
+
def run_agent_on(host, arg = '--no-daemonize --verbose --onetime --test',
|
534
|
+
options = {}, &block)
|
535
|
+
block_on host do |host|
|
543
536
|
on host, puppet_agent(arg), options, &block
|
544
537
|
end
|
545
538
|
end
|
@@ -557,11 +550,11 @@ module Beaker
|
|
557
550
|
# @param alias_spec [Hash{String=>Array[String]] an hash containing the host to alias(es) mappings to apply
|
558
551
|
# @example Stub puppetlabs.com on the master to 127.0.0.1 with an alias example.com
|
559
552
|
# stub_hosts_on(master, {'puppetlabs.com' => '127.0.0.1'}, {'puppetlabs.com' => ['example.com']})
|
560
|
-
def stub_hosts_on(machine, ip_spec, alias_spec={})
|
561
|
-
block_on machine do |
|
553
|
+
def stub_hosts_on(machine, ip_spec, alias_spec = {})
|
554
|
+
block_on machine do |host|
|
562
555
|
ip_spec.each do |address, ip|
|
563
556
|
aliases = alias_spec[address] || []
|
564
|
-
manifest
|
557
|
+
manifest = <<-EOS.gsub /^\s+/, ''
|
565
558
|
host { '#{address}':
|
566
559
|
\tensure => present,
|
567
560
|
\tip => '#{ip}',
|
@@ -569,13 +562,13 @@ module Beaker
|
|
569
562
|
}
|
570
563
|
EOS
|
571
564
|
logger.notify("Stubbing address #{address} to IP #{ip} on machine #{host}")
|
572
|
-
apply_manifest_on(
|
565
|
+
apply_manifest_on(host, manifest)
|
573
566
|
end
|
574
567
|
|
575
568
|
teardown do
|
576
569
|
ip_spec.each do |address, ip|
|
577
570
|
logger.notify("Unstubbing address #{address} to IP #{ip} on machine #{host}")
|
578
|
-
on(
|
571
|
+
on(host, puppet('resource', 'host', address, 'ensure=absent'))
|
579
572
|
end
|
580
573
|
end
|
581
574
|
end
|
@@ -593,35 +586,32 @@ module Beaker
|
|
593
586
|
# with_host_stubbed_on(master, {'forgeapi.puppetlabs.com' => '127.0.0.1'}, {'forgeapi.puppetlabs.com' => ['forgeapi.example.com']}) do
|
594
587
|
# puppet( "module install puppetlabs-stdlib" )
|
595
588
|
# end
|
596
|
-
def with_host_stubbed_on(host, ip_spec, alias_spec={}, &block)
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
manifest =<<-EOS.gsub /^\s+/, ""
|
589
|
+
def with_host_stubbed_on(host, ip_spec, alias_spec = {}, &block)
|
590
|
+
block_on host do |host|
|
591
|
+
# this code is duplicated from the `stub_hosts_on` method. The
|
592
|
+
# `stub_hosts_on` method itself is not used here because this
|
593
|
+
# method is used by modules tests using `beaker-rspec`. Since
|
594
|
+
# the `stub_hosts_on` method contains a `teardown` step, it is
|
595
|
+
# incompatible with `beaker_rspec`.
|
596
|
+
ip_spec.each do |address, ip|
|
597
|
+
aliases = alias_spec[address] || []
|
598
|
+
manifest = <<-EOS.gsub /^\s+/, ''
|
607
599
|
host { '#{address}':
|
608
600
|
\tensure => present,
|
609
601
|
\tip => '#{ip}',
|
610
602
|
\thost_aliases => #{aliases},
|
611
603
|
}
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
end
|
604
|
+
EOS
|
605
|
+
logger.notify("Stubbing address #{address} to IP #{ip} on machine #{host}")
|
606
|
+
apply_manifest_on(host, manifest)
|
616
607
|
end
|
608
|
+
end
|
617
609
|
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
on( host, puppet('resource', 'host', address, 'ensure=absent') )
|
624
|
-
end
|
610
|
+
block.call
|
611
|
+
ensure
|
612
|
+
ip_spec.each do |address, ip|
|
613
|
+
logger.notify("Unstubbing address #{address} to IP #{ip} on machine #{host}")
|
614
|
+
on(host, puppet('resource', 'host', address, 'ensure=absent'))
|
625
615
|
end
|
626
616
|
end
|
627
617
|
|
@@ -648,14 +638,16 @@ module Beaker
|
|
648
638
|
# @param forge_host [String] The URL to use as the forge alias, will default to using :forge_host in the
|
649
639
|
# global options hash
|
650
640
|
def stub_forge_on(machine, forge_host = nil)
|
651
|
-
#use global options hash
|
641
|
+
# use global options hash
|
652
642
|
primary_forge_name = 'forge.puppetlabs.com'
|
653
643
|
forge_host ||= options[:forge_host]
|
654
644
|
forge_ip = resolve_hostname_on(machine, forge_host)
|
655
645
|
raise "Failed to resolve forge host '#{forge_host}'" unless forge_ip
|
646
|
+
|
656
647
|
@forge_ip ||= forge_ip
|
657
|
-
block_on machine do |
|
658
|
-
stub_hosts_on(host, {primary_forge_name => @forge_ip},
|
648
|
+
block_on machine do |host|
|
649
|
+
stub_hosts_on(host, { primary_forge_name => @forge_ip },
|
650
|
+
{ primary_forge_name => ['forge.puppet.com', 'forgeapi.puppetlabs.com', 'forgeapi.puppet.com'] })
|
659
651
|
end
|
660
652
|
end
|
661
653
|
|
@@ -671,14 +663,16 @@ module Beaker
|
|
671
663
|
# @param host [String] the host to perform the stub on
|
672
664
|
# @param forge_host [String] The URL to use as the forge alias, will default to using :forge_host in the
|
673
665
|
# global options hash
|
674
|
-
def with_forge_stubbed_on(
|
675
|
-
#use global options hash
|
666
|
+
def with_forge_stubbed_on(host, forge_host = nil, &block)
|
667
|
+
# use global options hash
|
676
668
|
primary_forge_name = 'forge.puppetlabs.com'
|
677
669
|
forge_host ||= options[:forge_host]
|
678
670
|
forge_ip = resolve_hostname_on(host, forge_host)
|
679
671
|
raise "Failed to resolve forge host '#{forge_host}'" unless forge_ip
|
672
|
+
|
680
673
|
@forge_ip ||= forge_ip
|
681
|
-
with_host_stubbed_on(
|
674
|
+
with_host_stubbed_on(host, { primary_forge_name => @forge_ip },
|
675
|
+
{ primary_forge_name => ['forge.puppet.com', 'forgeapi.puppetlabs.com', 'forgeapi.puppet.com'] }, &block)
|
682
676
|
end
|
683
677
|
|
684
678
|
# This wraps `with_forge_stubbed_on` and provides it the default host
|
@@ -686,8 +680,8 @@ module Beaker
|
|
686
680
|
#
|
687
681
|
# @deprecated this method should not be used because stubbing the host
|
688
682
|
# breaks TLS validation.
|
689
|
-
def with_forge_stubbed(
|
690
|
-
with_forge_stubbed_on(
|
683
|
+
def with_forge_stubbed(forge_host = nil, &block)
|
684
|
+
with_forge_stubbed_on(default, forge_host, &block)
|
691
685
|
end
|
692
686
|
|
693
687
|
# This wraps the method `stub_hosts` and makes the stub specific to
|
@@ -698,7 +692,7 @@ module Beaker
|
|
698
692
|
#
|
699
693
|
# @see #stub_forge_on
|
700
694
|
def stub_forge(forge_host = nil)
|
701
|
-
#use global options hash
|
695
|
+
# use global options hash
|
702
696
|
forge_host ||= options[:forge_host]
|
703
697
|
stub_forge_on(default, forge_host)
|
704
698
|
end
|
@@ -714,7 +708,7 @@ module Beaker
|
|
714
708
|
nonssl_port = options[:puppetdb_port_nonssl] if nonssl_port.nil?
|
715
709
|
ssl_port = options[:puppetdb_port_ssl] if ssl_port.nil?
|
716
710
|
pe_ver = host['pe_ver'] || '0'
|
717
|
-
if version_is_less(pe_ver, '2016.1.0')
|
711
|
+
if version_is_less(pe_ver, '2016.1.0')
|
718
712
|
# the status endpoint was introduced in puppetdb 4.0. The earliest
|
719
713
|
# PE release with the 4.x pdb version was 2016.1.0
|
720
714
|
endpoint = 'pdb/meta/v1/version'
|
@@ -725,8 +719,8 @@ module Beaker
|
|
725
719
|
end
|
726
720
|
retry_on(host,
|
727
721
|
"curl -m 1 http://localhost:#{nonssl_port}/#{endpoint} | grep '#{expected_regex}'",
|
728
|
-
{:
|
729
|
-
curl_with_retries(
|
722
|
+
{ max_retries: 120 })
|
723
|
+
curl_with_retries('start puppetdb (ssl)',
|
730
724
|
host, "https://#{host.node_name}:#{ssl_port}", [35, 60])
|
731
725
|
end
|
732
726
|
|
@@ -738,7 +732,7 @@ module Beaker
|
|
738
732
|
# @return [Result] Result of the last HTTPS status check
|
739
733
|
def sleep_until_puppetserver_started(host, port = nil)
|
740
734
|
port = options[:puppetserver_port] if port.nil?
|
741
|
-
curl_with_retries(
|
735
|
+
curl_with_retries('start puppetserver (ssl)',
|
742
736
|
host, "https://#{host.node_name}:#{port}", [35, 60])
|
743
737
|
end
|
744
738
|
|
@@ -750,22 +744,22 @@ module Beaker
|
|
750
744
|
# @return [Result] Result of the last HTTPS status check
|
751
745
|
def sleep_until_nc_started(host, port = nil)
|
752
746
|
port = options[:nodeclassifier_port] if port.nil?
|
753
|
-
curl_with_retries(
|
747
|
+
curl_with_retries('start nodeclassifier (ssl)',
|
754
748
|
host, "https://#{host.node_name}:#{port}", [35, 60])
|
755
749
|
end
|
756
750
|
|
757
|
-
#stops the puppet agent running on the host
|
751
|
+
# stops the puppet agent running on the host
|
758
752
|
# @param [Host, Array<Host>, String, Symbol] agent One or more hosts to act upon,
|
759
753
|
# or a role (String or Symbol) that identifies one or more hosts.
|
760
754
|
# @param [Hash{Symbol=>String}] opts Options to alter execution.
|
761
755
|
# @option opts [Boolean] :run_in_parallel Whether to run on each host in parallel.
|
762
756
|
def stop_agent_on(agent, opts = {})
|
763
|
-
block_on agent, opts do |
|
757
|
+
block_on agent, opts do |host|
|
764
758
|
vardir = host.puppet_configprint['vardir']
|
765
759
|
|
766
760
|
# In 4.0 this was changed to just be `puppet`
|
767
761
|
agent_service = 'puppet'
|
768
|
-
|
762
|
+
unless aio_version?(host)
|
769
763
|
# The agent service is `pe-puppet` everywhere EXCEPT certain linux distros on PE 2.8
|
770
764
|
# In all the case that it is different, this init script will exist. So we can assume
|
771
765
|
# that if the script doesn't exist, we should just use `pe-puppet`
|
@@ -778,37 +772,34 @@ module Beaker
|
|
778
772
|
# the init script or system on that particular configuration.
|
779
773
|
avoid_puppet_at_all_costs = false
|
780
774
|
avoid_puppet_at_all_costs ||= host['platform'] =~ /el-4/
|
781
|
-
avoid_puppet_at_all_costs ||= host['pe_ver'] && version_is_less(host['pe_ver'],
|
775
|
+
avoid_puppet_at_all_costs ||= host['pe_ver'] && version_is_less(host['pe_ver'],
|
776
|
+
'3.2') && host['platform'] =~ /sles/
|
782
777
|
|
783
778
|
if avoid_puppet_at_all_costs
|
784
779
|
# When upgrading, puppet is already stopped. On EL4, this causes an exit code of '1'
|
785
|
-
on host, "/etc/init.d/#{agent_service} stop", :
|
780
|
+
on host, "/etc/init.d/#{agent_service} stop", acceptable_exit_codes: [0, 1]
|
786
781
|
else
|
787
782
|
on host, puppet_resource('service', agent_service, 'ensure=stopped')
|
788
783
|
end
|
789
784
|
|
790
|
-
#Ensure that a puppet run that was started before the last lock check is completed
|
785
|
+
# Ensure that a puppet run that was started before the last lock check is completed
|
791
786
|
agent_running = true
|
792
787
|
while agent_running
|
793
788
|
agent_running = host.file_exist?("#{vardir}/state/agent_catalog_run.lock")
|
794
|
-
if agent_running
|
795
|
-
sleep 2
|
796
|
-
end
|
789
|
+
sleep 2 if agent_running
|
797
790
|
end
|
798
|
-
|
799
791
|
end
|
800
792
|
end
|
801
793
|
|
802
|
-
#stops the puppet agent running on the default host
|
794
|
+
# stops the puppet agent running on the default host
|
803
795
|
# @see #stop_agent_on
|
804
796
|
def stop_agent
|
805
797
|
stop_agent_on(default)
|
806
798
|
end
|
807
799
|
|
808
|
-
#wait for a given host to appear in the dashboard
|
800
|
+
# wait for a given host to appear in the dashboard
|
809
801
|
# @deprecated this method should be removed in the next release since we don't believe the check is necessary.
|
810
802
|
def wait_for_host_in_dashboard(host)
|
811
|
-
|
812
803
|
hostname = host.node_name
|
813
804
|
hostcert = dashboard.puppet['hostcert']
|
814
805
|
key = dashboard.puppet['hostprivkey']
|
@@ -829,26 +820,26 @@ module Beaker
|
|
829
820
|
hostnames = []
|
830
821
|
hosts = host.is_a?(Array) ? host : [host]
|
831
822
|
puppet_version = on(master, puppet('--version')).stdout.chomp
|
832
|
-
hosts.each
|
823
|
+
hosts.each do |current_host|
|
833
824
|
if [master, dashboard, database].include? current_host
|
834
|
-
on current_host, puppet(
|
825
|
+
on current_host, puppet('agent -t'), acceptable_exit_codes: [0, 1, 2]
|
835
826
|
|
836
827
|
if version_is_less(puppet_version, '5.99')
|
837
|
-
on master, puppet("cert --allow-dns-alt-names sign #{current_host}"
|
828
|
+
on master, puppet("cert --allow-dns-alt-names sign #{current_host}"), acceptable_exit_codes: [0, 24]
|
838
829
|
else
|
839
830
|
on master, "puppetserver ca sign --certname #{current_host}"
|
840
831
|
end
|
841
832
|
else
|
842
|
-
hostnames << Regexp.escape(
|
833
|
+
hostnames << Regexp.escape(current_host.node_name)
|
843
834
|
end
|
844
|
-
|
835
|
+
end
|
845
836
|
|
846
837
|
if hostnames.size < 1
|
847
838
|
if version_is_less(puppet_version, '5.99')
|
848
|
-
on master, puppet(
|
849
|
-
|
839
|
+
on master, puppet('cert --sign --all --allow-dns-alt-names'),
|
840
|
+
acceptable_exit_codes: [0, 24]
|
850
841
|
else
|
851
|
-
on master, 'puppetserver ca sign --all', :
|
842
|
+
on master, 'puppetserver ca sign --all', acceptable_exit_codes: [0, 24]
|
852
843
|
end
|
853
844
|
return
|
854
845
|
end
|
@@ -856,21 +847,21 @@ module Beaker
|
|
856
847
|
while hostnames.size > 0
|
857
848
|
last_sleep = 0
|
858
849
|
next_sleep = 1
|
859
|
-
|
850
|
+
11.times do |i|
|
860
851
|
if i == 10
|
861
852
|
fail_test("Failed to sign cert for #{hostnames}")
|
862
853
|
hostnames.clear
|
863
854
|
end
|
864
855
|
|
865
856
|
if version_is_less(puppet_version, '5.99')
|
866
|
-
on master, puppet(
|
867
|
-
out = on(master, puppet(
|
857
|
+
on master, puppet('cert --sign --all --allow-dns-alt-names'), acceptable_exit_codes: [0, 24]
|
858
|
+
out = on(master, puppet('cert --list --all')).stdout
|
868
859
|
if hostnames.all? { |hostname| out =~ /\+ "?#{hostname}"?/ }
|
869
860
|
hostnames.clear
|
870
861
|
break
|
871
862
|
end
|
872
863
|
else
|
873
|
-
on master, 'puppetserver ca sign --all', :
|
864
|
+
on master, 'puppetserver ca sign --all', acceptable_exit_codes: [0, 24]
|
874
865
|
out = on(master, 'puppetserver ca list --all').stdout
|
875
866
|
if out !~ /.*Requested.*/ && hostnames.all? { |hostname| out =~ /\b#{hostname}\b/ }
|
876
867
|
hostnames.clear
|
@@ -879,14 +870,14 @@ module Beaker
|
|
879
870
|
end
|
880
871
|
|
881
872
|
sleep next_sleep
|
882
|
-
(last_sleep, next_sleep) = next_sleep, last_sleep+next_sleep
|
873
|
+
(last_sleep, next_sleep) = next_sleep, last_sleep + next_sleep
|
883
874
|
end
|
884
875
|
end
|
885
876
|
host
|
886
877
|
end
|
887
878
|
|
888
|
-
#prompt the master to sign certs then check to confirm the cert for the default host is signed
|
889
|
-
|
879
|
+
# prompt the master to sign certs then check to confirm the cert for the default host is signed
|
880
|
+
# @see #sign_certificate_for
|
890
881
|
def sign_certificate
|
891
882
|
sign_certificate_for(default)
|
892
883
|
end
|
@@ -907,14 +898,14 @@ module Beaker
|
|
907
898
|
# @note While tempting, this method should not be "optimized" to coalesce calls to
|
908
899
|
# chown user:group when both options are passed, as doing so will muddy the spec.
|
909
900
|
def create_tmpdir_on(hosts, path_prefix = '', user = nil, group = nil)
|
910
|
-
block_on hosts do |
|
901
|
+
block_on hosts do |host|
|
911
902
|
# create the directory
|
912
903
|
dir = host.tmpdir(path_prefix)
|
913
904
|
# only chown if explicitly passed; don't make assumptions about perms
|
914
905
|
# only `chown user` for cleaner codepaths
|
915
906
|
if user
|
916
907
|
# ensure user exists
|
917
|
-
|
908
|
+
unless host.user_get(user).success?
|
918
909
|
# clean up
|
919
910
|
host.rm_rf("#{dir}")
|
920
911
|
raise "User #{user} does not exist on #{host}."
|
@@ -926,7 +917,7 @@ module Beaker
|
|
926
917
|
# only chgrp if explicitly passed; don't make assumptions about perms
|
927
918
|
if group
|
928
919
|
# ensure group exists
|
929
|
-
|
920
|
+
unless host.group_get(group).success?
|
930
921
|
# clean up
|
931
922
|
# on host, "rmdir #{dir}"
|
932
923
|
host.rm_rf(dir)
|
@@ -953,7 +944,7 @@ module Beaker
|
|
953
944
|
# if this puppet command returns a non-zero exit code.
|
954
945
|
#
|
955
946
|
# @return [String] Returns the name of the newly-created dir.
|
956
|
-
def create_tmpdir_for_user(host, name='/tmp/beaker', user=nil)
|
947
|
+
def create_tmpdir_for_user(host, name = '/tmp/beaker', user = nil)
|
957
948
|
user ||= puppet_config(host, 'user', section: 'master')
|
958
949
|
create_tmpdir_on(host, name, user)
|
959
950
|
end
|