beaker-puppet 1.29.0 → 3.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 +3 -3
- data/.github/workflows/test.yml +28 -7
- data/.github_changelog_generator +3 -0
- data/.rubocop.yml +5 -0
- data/.rubocop_todo.yml +887 -0
- data/CHANGELOG.md +50 -0
- data/CODEOWNERS +1 -0
- data/Gemfile +5 -20
- data/README.md +4 -13
- 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 +17 -24
- 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 +145 -229
- 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 +269 -480
- 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 +53 -80
- 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/release-prep.sh +11 -0
- data/setup/aio/010_Install_Puppet_Agent.rb +22 -9
- 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 +9 -18
- data/setup/common/045_EnsureMasterStarted.rb +2 -2
- data/setup/gem/010_GemInstall.rb +6 -5
- 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 +463 -724
- 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 +471 -863
- 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 +89 -97
- 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 +188 -188
- metadata +38 -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
|
@@ -83,21 +81,13 @@ module Beaker
|
|
83
81
|
# Test Puppet running in a certain run mode with specific options.
|
84
82
|
# This ensures the following steps are performed:
|
85
83
|
# 1. The pre-test Puppet configuration is backed up
|
86
|
-
# 2.
|
84
|
+
# 2. Lay down a new Puppet configuraton file
|
87
85
|
# 3. Puppet is started or restarted in the specified run mode
|
88
86
|
# 4. Ensure Puppet has started correctly
|
89
87
|
# 5. Further tests are yielded to
|
90
88
|
# 6. Revert Puppet to the pre-test state
|
91
89
|
# 7. Testing artifacts are saved in a folder named for the test
|
92
90
|
#
|
93
|
-
# @note Whether Puppet is started or restarted depends on what kind of
|
94
|
-
# server you're running. Passenger and puppetserver are restarted before.
|
95
|
-
# Webrick is started before and stopped after yielding, unless you're using
|
96
|
-
# service scripts, then it'll behave like passenger & puppetserver.
|
97
|
-
# Passenger and puppetserver (or webrick using service scripts)
|
98
|
-
# restart after yielding by default. You can stop this from happening
|
99
|
-
# by setting the :restart_when_done flag of the conf_opts argument.
|
100
|
-
#
|
101
91
|
# @param [Host] host One object that act like Host
|
102
92
|
#
|
103
93
|
# @param [Hash{Symbol=>String}] conf_opts Represents puppet settings.
|
@@ -114,22 +104,11 @@ module Beaker
|
|
114
104
|
#
|
115
105
|
# These will only be applied when starting a FOSS
|
116
106
|
# master, as a pe master is just bounced.
|
117
|
-
# @option conf_opts [Hash] :__service_args__ A special setting of options
|
118
|
-
# for controlling how the puppet master service is
|
119
|
-
# handled. The only setting currently is
|
120
|
-
# :bypass_service_script, which if set true will
|
121
|
-
# force stopping and starting a webrick master
|
122
|
-
# using the start_puppet_from_source_* methods,
|
123
|
-
# even if it seems the host has passenger.
|
124
|
-
# This is needed in FOSS tests to initialize
|
125
|
-
# SSL.
|
126
107
|
# @option conf_opts [Boolean] :restart_when_done determines whether a restart
|
127
108
|
# should be run after the test has been yielded to.
|
128
109
|
# Will stop puppet if false. Default behavior
|
129
110
|
# is to restart, but you can override this on the
|
130
111
|
# host or with this option.
|
131
|
-
# (Note: only works for passenger & puppetserver
|
132
|
-
# masters (or webrick using the service scripts))
|
133
112
|
# @param [File] testdir The temporary directory which will hold backup
|
134
113
|
# configuration, and other test artifacts.
|
135
114
|
#
|
@@ -152,13 +131,18 @@ module Beaker
|
|
152
131
|
# end
|
153
132
|
#
|
154
133
|
def with_puppet_running_on(host, conf_opts, testdir = host.tmpdir(File.basename(@path)), &block)
|
155
|
-
|
134
|
+
unless conf_opts.is_a?(Hash)
|
135
|
+
raise(ArgumentError,
|
136
|
+
"with_puppet_running_on's conf_opts must be a Hash. You provided a #{conf_opts.class}: '#{conf_opts}'")
|
137
|
+
end
|
138
|
+
|
156
139
|
cmdline_args = conf_opts[:__commandline_args__]
|
157
|
-
service_args = conf_opts[:__service_args__] || {}
|
158
140
|
restart_when_done = true
|
159
141
|
restart_when_done = host[:restart_when_done] if host.has_key?(:restart_when_done)
|
160
142
|
restart_when_done = conf_opts.fetch(:restart_when_done, restart_when_done)
|
161
|
-
conf_opts = conf_opts.reject
|
143
|
+
conf_opts = conf_opts.reject do |k, v|
|
144
|
+
%i[__commandline_args__ restart_when_done].include?(k)
|
145
|
+
end
|
162
146
|
|
163
147
|
curl_retries = host['master-start-curl-retries'] || options['master-start-curl-retries']
|
164
148
|
logger.debug "Setting curl retries to #{curl_retries}"
|
@@ -168,29 +152,29 @@ module Beaker
|
|
168
152
|
vardir = puppet_config(host, 'vardir', section: 'master')
|
169
153
|
|
170
154
|
if cmdline_args
|
171
|
-
split_args = cmdline_args.split
|
155
|
+
split_args = cmdline_args.split
|
172
156
|
|
173
157
|
split_args.each do |arg|
|
174
158
|
case arg
|
175
159
|
when /--confdir=(.*)/
|
176
|
-
confdir =
|
160
|
+
confdir = ::Regexp.last_match(1)
|
177
161
|
when /--vardir=(.*)/
|
178
|
-
vardir =
|
162
|
+
vardir = ::Regexp.last_match(1)
|
179
163
|
end
|
180
164
|
end
|
181
165
|
end
|
182
166
|
|
183
167
|
puppetserver_opts = {
|
184
|
-
|
185
|
-
|
186
|
-
|
168
|
+
'jruby-puppet' => {
|
169
|
+
'master-conf-dir' => confdir,
|
170
|
+
'master-var-dir' => vardir,
|
171
|
+
},
|
172
|
+
'certificate-authority' => {
|
173
|
+
'allow-subject-alt-names' => true,
|
187
174
|
},
|
188
|
-
"certificate-authority" => {
|
189
|
-
"allow-subject-alt-names" => true
|
190
|
-
}
|
191
175
|
}
|
192
176
|
|
193
|
-
puppetserver_conf = File.join("#{host['puppetserver-confdir']}",
|
177
|
+
puppetserver_conf = File.join("#{host['puppetserver-confdir']}", 'puppetserver.conf')
|
194
178
|
modify_tk_config(host, puppetserver_conf, puppetserver_opts)
|
195
179
|
end
|
196
180
|
begin
|
@@ -198,17 +182,12 @@ module Beaker
|
|
198
182
|
puppet_config(host, 'confdir', section: 'master'),
|
199
183
|
testdir,
|
200
184
|
'puppet.conf')
|
201
|
-
lay_down_new_puppet_conf
|
202
|
-
|
203
|
-
if host.use_service_scripts? && !service_args[:bypass_service_script]
|
204
|
-
bounce_service( host, host['puppetservice'], curl_retries )
|
205
|
-
else
|
206
|
-
puppet_master_started = start_puppet_from_source_on!( host, cmdline_args )
|
207
|
-
end
|
185
|
+
lay_down_new_puppet_conf(host, conf_opts, testdir)
|
186
|
+
bounce_service(host, host['puppetservice'], curl_retries)
|
208
187
|
|
209
188
|
yield self if block_given?
|
210
189
|
|
211
|
-
|
190
|
+
# FIXME: these test-flow-control exceptions should be using throw
|
212
191
|
# they can be caught in test_case. current layout dows not allow it
|
213
192
|
rescue Beaker::DSL::Outcomes::PassTest => early_assertion
|
214
193
|
pass_test(early_assertion)
|
@@ -223,41 +202,25 @@ module Beaker
|
|
223
202
|
rescue Exception => early_exception
|
224
203
|
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
204
|
raise(original_exception)
|
226
|
-
|
227
205
|
ensure
|
228
206
|
begin
|
229
|
-
|
230
|
-
if
|
231
|
-
|
232
|
-
if restart_when_done
|
233
|
-
bounce_service( host, host['puppetservice'], curl_retries )
|
234
|
-
else
|
235
|
-
host.exec puppet_resource('service', host['puppetservice'], 'ensure=stopped')
|
236
|
-
end
|
207
|
+
restore_puppet_conf_from_backup(host, backup_file)
|
208
|
+
if restart_when_done
|
209
|
+
bounce_service(host, host['puppetservice'], curl_retries)
|
237
210
|
else
|
238
|
-
|
239
|
-
stop_puppet_from_source_on( host )
|
240
|
-
else
|
241
|
-
dump_puppet_log(host)
|
242
|
-
end
|
243
|
-
restore_puppet_conf_from_backup( host, backup_file )
|
211
|
+
host.exec puppet_resource('service', host['puppetservice'], 'ensure=stopped')
|
244
212
|
end
|
245
|
-
|
246
213
|
rescue Exception => teardown_exception
|
247
214
|
begin
|
248
|
-
|
249
|
-
dump_puppet_log(host)
|
250
|
-
end
|
215
|
+
dump_puppet_log(host) unless host.is_pe?
|
251
216
|
rescue Exception => dumping_exception
|
252
217
|
logger.error("Raised during attempt to dump puppet logs: #{dumping_exception}")
|
253
218
|
end
|
254
219
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
raise teardown_exception
|
260
|
-
end
|
220
|
+
raise teardown_exception unless original_exception
|
221
|
+
|
222
|
+
logger.error("Raised during attempt to teardown with_puppet_running_on: #{teardown_exception}\n---\n")
|
223
|
+
raise original_exception
|
261
224
|
end
|
262
225
|
end
|
263
226
|
end
|
@@ -265,44 +228,31 @@ module Beaker
|
|
265
228
|
# Test Puppet running in a certain run mode with specific options,
|
266
229
|
# on the default host
|
267
230
|
# @see #with_puppet_running_on
|
268
|
-
def with_puppet_running
|
231
|
+
def with_puppet_running(conf_opts, testdir = host.tmpdir(File.basename(@path)), &block)
|
269
232
|
with_puppet_running_on(default, conf_opts, testdir, &block)
|
270
233
|
end
|
271
234
|
|
272
235
|
# @!visibility private
|
273
|
-
def restore_puppet_conf_from_backup(
|
236
|
+
def restore_puppet_conf_from_backup(host, backup_file)
|
274
237
|
puppet_conf = puppet_config(host, 'config', section: 'master')
|
275
238
|
|
276
239
|
if backup_file
|
277
|
-
host.exec(
|
240
|
+
host.exec(Command.new("if [ -f '#{backup_file}' ]; then " +
|
278
241
|
"cat '#{backup_file}' > " +
|
279
242
|
"'#{puppet_conf}'; " +
|
280
243
|
"rm -f '#{backup_file}'; " +
|
281
|
-
|
244
|
+
'fi'))
|
282
245
|
else
|
283
|
-
host.exec(
|
284
|
-
end
|
285
|
-
|
286
|
-
end
|
287
|
-
|
288
|
-
# @!visibility private
|
289
|
-
def start_puppet_from_source_on! host, args = ''
|
290
|
-
host.exec( puppet( 'master', args ) )
|
291
|
-
|
292
|
-
logger.debug 'Waiting for the puppet master to start'
|
293
|
-
unless port_open_within?( host, 8140, 10 )
|
294
|
-
raise Beaker::DSL::FailTest, 'Puppet master did not start in a timely fashion'
|
246
|
+
host.exec(Command.new("rm -f '#{puppet_conf}'"))
|
295
247
|
end
|
296
|
-
logger.debug 'The puppet master has started'
|
297
|
-
return true
|
298
248
|
end
|
299
249
|
|
300
250
|
# @!visibility private
|
301
|
-
def stop_puppet_from_source_on(
|
302
|
-
pid = host.exec(
|
303
|
-
host.exec(
|
251
|
+
def stop_puppet_from_source_on(host)
|
252
|
+
pid = host.exec(Command.new('cat `puppet config print --section master pidfile`')).stdout.chomp
|
253
|
+
host.exec(Command.new("kill #{pid}"))
|
304
254
|
Timeout.timeout(10) do
|
305
|
-
while host.exec(
|
255
|
+
while host.exec(Command.new("kill -0 #{pid}"), acceptable_exit_codes: [0, 1]).exit_code == 0
|
306
256
|
# until kill -0 finds no process and we know that puppet has finished cleaning up
|
307
257
|
sleep 1
|
308
258
|
end
|
@@ -312,40 +262,38 @@ module Beaker
|
|
312
262
|
# @!visibility private
|
313
263
|
def dump_puppet_log(host)
|
314
264
|
syslogfile = case host['platform']
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
265
|
+
when /fedora|centos|el|redhat|scientific/ then '/var/log/messages'
|
266
|
+
when /ubuntu|debian/ then '/var/log/syslog'
|
267
|
+
else return
|
268
|
+
end
|
319
269
|
|
320
270
|
logger.notify "\n*************************"
|
321
|
-
logger.notify
|
322
|
-
logger.notify
|
323
|
-
host.exec(
|
271
|
+
logger.notify '* Dumping master log *'
|
272
|
+
logger.notify '*************************'
|
273
|
+
host.exec(Command.new("tail -n 100 #{syslogfile}"), acceptable_exit_codes: [0, 1])
|
324
274
|
logger.notify "*************************\n"
|
325
275
|
end
|
326
276
|
|
327
277
|
# @!visibility private
|
328
|
-
def lay_down_new_puppet_conf(
|
278
|
+
def lay_down_new_puppet_conf(host, configuration_options, testdir)
|
329
279
|
puppetconf_main = puppet_config(host, 'config', section: 'master')
|
330
280
|
puppetconf_filename = File.basename(puppetconf_main)
|
331
281
|
puppetconf_test = File.join(testdir, puppetconf_filename)
|
332
282
|
|
333
|
-
new_conf = puppet_conf_for(
|
283
|
+
new_conf = puppet_conf_for(host, configuration_options)
|
334
284
|
create_remote_file host, puppetconf_test, new_conf.to_s
|
335
285
|
|
336
286
|
host.exec(
|
337
|
-
Command.new(
|
338
|
-
:
|
287
|
+
Command.new("cat #{puppetconf_test} > #{puppetconf_main}"),
|
288
|
+
silent: true,
|
339
289
|
)
|
340
|
-
host.exec(
|
290
|
+
host.exec(Command.new("cat #{puppetconf_main}"))
|
341
291
|
end
|
342
292
|
|
343
293
|
# @!visibility private
|
344
|
-
def puppet_conf_for
|
345
|
-
puppetconf = host.exec(
|
346
|
-
|
347
|
-
|
348
|
-
new_conf
|
294
|
+
def puppet_conf_for(host, conf_opts)
|
295
|
+
puppetconf = host.exec(Command.new("cat #{puppet_config(host, 'config', section: 'master')}")).stdout
|
296
|
+
IniFile.new(default: 'main', content: puppetconf).merge(conf_opts)
|
349
297
|
end
|
350
298
|
|
351
299
|
# Restarts the named puppet service
|
@@ -357,23 +305,15 @@ module Beaker
|
|
357
305
|
#
|
358
306
|
# @return [Result] Result of last status check
|
359
307
|
# @!visibility private
|
360
|
-
def bounce_service
|
308
|
+
def bounce_service(host, service, curl_retries = nil, port = nil)
|
361
309
|
curl_retries = 120 if curl_retries.nil?
|
362
310
|
port = options[:puppetserver_port] if port.nil?
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
:acceptable_exit_codes => [0,1,3])
|
370
|
-
if result.exit_code == 0
|
371
|
-
return result
|
372
|
-
else
|
373
|
-
host.exec puppet_resource('service', service, 'ensure=stopped')
|
374
|
-
host.exec puppet_resource('service', service, 'ensure=running')
|
375
|
-
end
|
376
|
-
end
|
311
|
+
result = host.exec(Command.new("service #{service} reload"), acceptable_exit_codes: [0, 1, 3])
|
312
|
+
return result if result.exit_code == 0
|
313
|
+
|
314
|
+
host.exec puppet_resource('service', service, 'ensure=stopped')
|
315
|
+
host.exec puppet_resource('service', service, 'ensure=running')
|
316
|
+
|
377
317
|
curl_with_retries(" #{service} ", host, "https://localhost:#{port}", [35, 60], curl_retries)
|
378
318
|
end
|
379
319
|
|
@@ -454,7 +394,7 @@ module Beaker
|
|
454
394
|
# object, or nil. Check {Beaker::Shared::HostManager#run_block_on} for
|
455
395
|
# more details on this.
|
456
396
|
def apply_manifest_on(host, manifest, opts = {}, &block)
|
457
|
-
block_on host, opts do |
|
397
|
+
block_on host, opts do |host|
|
458
398
|
on_options = {}
|
459
399
|
on_options[:acceptable_exit_codes] = Array(opts[:acceptable_exit_codes])
|
460
400
|
|
@@ -475,7 +415,8 @@ module Beaker
|
|
475
415
|
# "... an exit code of '2' means there were changes, an exit code of
|
476
416
|
# '4' means there were failures during the transaction, and an exit
|
477
417
|
# code of '6' means there were both changes and failures."
|
478
|
-
if [opts[:catch_changes],opts[:catch_failures],opts[:expect_failures],
|
418
|
+
if [opts[:catch_changes], opts[:catch_failures], opts[:expect_failures],
|
419
|
+
opts[:expect_changes],].compact.length > 1
|
479
420
|
raise(ArgumentError,
|
480
421
|
'Cannot specify more than one of `catch_failures`, ' +
|
481
422
|
'`catch_changes`, `expect_failures`, or `expect_changes` ' +
|
@@ -515,15 +456,13 @@ module Beaker
|
|
515
456
|
# that they want to set for the puppet command. If so, we set the final
|
516
457
|
# value of *args to a new hash with just one entry (the value of which
|
517
458
|
# is our environment variables hash)
|
518
|
-
if opts.has_key?(:environment)
|
519
|
-
puppet_apply_opts['ENV'] = opts[:environment]
|
520
|
-
end
|
459
|
+
puppet_apply_opts['ENV'] = opts[:environment] if opts.has_key?(:environment)
|
521
460
|
|
522
|
-
file_path = host.tmpfile(%(apply_manifest_#{Time.now.strftime(
|
461
|
+
file_path = host.tmpfile(%(apply_manifest_#{Time.now.strftime('%H%M%S%L')}.pp))
|
523
462
|
create_remote_file(host, file_path, manifest + "\n")
|
524
463
|
|
525
464
|
if host[:default_apply_opts].respond_to? :merge
|
526
|
-
puppet_apply_opts = host[:default_apply_opts].merge(
|
465
|
+
puppet_apply_opts = host[:default_apply_opts].merge(puppet_apply_opts)
|
527
466
|
end
|
528
467
|
|
529
468
|
on host, puppet('apply', file_path, puppet_apply_opts), on_options, &block
|
@@ -537,9 +476,9 @@ module Beaker
|
|
537
476
|
end
|
538
477
|
|
539
478
|
# @deprecated
|
540
|
-
def run_agent_on(host, arg='--no-daemonize --verbose --onetime --test',
|
541
|
-
options={}, &block)
|
542
|
-
block_on host do |
|
479
|
+
def run_agent_on(host, arg = '--no-daemonize --verbose --onetime --test',
|
480
|
+
options = {}, &block)
|
481
|
+
block_on host do |host|
|
543
482
|
on host, puppet_agent(arg), options, &block
|
544
483
|
end
|
545
484
|
end
|
@@ -557,11 +496,11 @@ module Beaker
|
|
557
496
|
# @param alias_spec [Hash{String=>Array[String]] an hash containing the host to alias(es) mappings to apply
|
558
497
|
# @example Stub puppetlabs.com on the master to 127.0.0.1 with an alias example.com
|
559
498
|
# 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 |
|
499
|
+
def stub_hosts_on(machine, ip_spec, alias_spec = {})
|
500
|
+
block_on machine do |host|
|
562
501
|
ip_spec.each do |address, ip|
|
563
502
|
aliases = alias_spec[address] || []
|
564
|
-
manifest
|
503
|
+
manifest = <<-EOS.gsub /^\s+/, ''
|
565
504
|
host { '#{address}':
|
566
505
|
\tensure => present,
|
567
506
|
\tip => '#{ip}',
|
@@ -569,13 +508,13 @@ module Beaker
|
|
569
508
|
}
|
570
509
|
EOS
|
571
510
|
logger.notify("Stubbing address #{address} to IP #{ip} on machine #{host}")
|
572
|
-
apply_manifest_on(
|
511
|
+
apply_manifest_on(host, manifest)
|
573
512
|
end
|
574
513
|
|
575
514
|
teardown do
|
576
515
|
ip_spec.each do |address, ip|
|
577
516
|
logger.notify("Unstubbing address #{address} to IP #{ip} on machine #{host}")
|
578
|
-
on(
|
517
|
+
on(host, puppet('resource', 'host', address, 'ensure=absent'))
|
579
518
|
end
|
580
519
|
end
|
581
520
|
end
|
@@ -593,35 +532,32 @@ module Beaker
|
|
593
532
|
# with_host_stubbed_on(master, {'forgeapi.puppetlabs.com' => '127.0.0.1'}, {'forgeapi.puppetlabs.com' => ['forgeapi.example.com']}) do
|
594
533
|
# puppet( "module install puppetlabs-stdlib" )
|
595
534
|
# 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+/, ""
|
535
|
+
def with_host_stubbed_on(host, ip_spec, alias_spec = {}, &block)
|
536
|
+
block_on host do |host|
|
537
|
+
# this code is duplicated from the `stub_hosts_on` method. The
|
538
|
+
# `stub_hosts_on` method itself is not used here because this
|
539
|
+
# method is used by modules tests using `beaker-rspec`. Since
|
540
|
+
# the `stub_hosts_on` method contains a `teardown` step, it is
|
541
|
+
# incompatible with `beaker_rspec`.
|
542
|
+
ip_spec.each do |address, ip|
|
543
|
+
aliases = alias_spec[address] || []
|
544
|
+
manifest = <<-EOS.gsub /^\s+/, ''
|
607
545
|
host { '#{address}':
|
608
546
|
\tensure => present,
|
609
547
|
\tip => '#{ip}',
|
610
548
|
\thost_aliases => #{aliases},
|
611
549
|
}
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
end
|
550
|
+
EOS
|
551
|
+
logger.notify("Stubbing address #{address} to IP #{ip} on machine #{host}")
|
552
|
+
apply_manifest_on(host, manifest)
|
616
553
|
end
|
554
|
+
end
|
617
555
|
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
on( host, puppet('resource', 'host', address, 'ensure=absent') )
|
624
|
-
end
|
556
|
+
block.call
|
557
|
+
ensure
|
558
|
+
ip_spec.each do |address, ip|
|
559
|
+
logger.notify("Unstubbing address #{address} to IP #{ip} on machine #{host}")
|
560
|
+
on(host, puppet('resource', 'host', address, 'ensure=absent'))
|
625
561
|
end
|
626
562
|
end
|
627
563
|
|
@@ -648,14 +584,16 @@ module Beaker
|
|
648
584
|
# @param forge_host [String] The URL to use as the forge alias, will default to using :forge_host in the
|
649
585
|
# global options hash
|
650
586
|
def stub_forge_on(machine, forge_host = nil)
|
651
|
-
#use global options hash
|
587
|
+
# use global options hash
|
652
588
|
primary_forge_name = 'forge.puppetlabs.com'
|
653
589
|
forge_host ||= options[:forge_host]
|
654
590
|
forge_ip = resolve_hostname_on(machine, forge_host)
|
655
591
|
raise "Failed to resolve forge host '#{forge_host}'" unless forge_ip
|
592
|
+
|
656
593
|
@forge_ip ||= forge_ip
|
657
|
-
block_on machine do |
|
658
|
-
stub_hosts_on(host, {primary_forge_name => @forge_ip},
|
594
|
+
block_on machine do |host|
|
595
|
+
stub_hosts_on(host, { primary_forge_name => @forge_ip },
|
596
|
+
{ primary_forge_name => ['forge.puppet.com', 'forgeapi.puppetlabs.com', 'forgeapi.puppet.com'] })
|
659
597
|
end
|
660
598
|
end
|
661
599
|
|
@@ -671,14 +609,16 @@ module Beaker
|
|
671
609
|
# @param host [String] the host to perform the stub on
|
672
610
|
# @param forge_host [String] The URL to use as the forge alias, will default to using :forge_host in the
|
673
611
|
# global options hash
|
674
|
-
def with_forge_stubbed_on(
|
675
|
-
#use global options hash
|
612
|
+
def with_forge_stubbed_on(host, forge_host = nil, &block)
|
613
|
+
# use global options hash
|
676
614
|
primary_forge_name = 'forge.puppetlabs.com'
|
677
615
|
forge_host ||= options[:forge_host]
|
678
616
|
forge_ip = resolve_hostname_on(host, forge_host)
|
679
617
|
raise "Failed to resolve forge host '#{forge_host}'" unless forge_ip
|
618
|
+
|
680
619
|
@forge_ip ||= forge_ip
|
681
|
-
with_host_stubbed_on(
|
620
|
+
with_host_stubbed_on(host, { primary_forge_name => @forge_ip },
|
621
|
+
{ primary_forge_name => ['forge.puppet.com', 'forgeapi.puppetlabs.com', 'forgeapi.puppet.com'] }, &block)
|
682
622
|
end
|
683
623
|
|
684
624
|
# This wraps `with_forge_stubbed_on` and provides it the default host
|
@@ -686,8 +626,8 @@ module Beaker
|
|
686
626
|
#
|
687
627
|
# @deprecated this method should not be used because stubbing the host
|
688
628
|
# breaks TLS validation.
|
689
|
-
def with_forge_stubbed(
|
690
|
-
with_forge_stubbed_on(
|
629
|
+
def with_forge_stubbed(forge_host = nil, &block)
|
630
|
+
with_forge_stubbed_on(default, forge_host, &block)
|
691
631
|
end
|
692
632
|
|
693
633
|
# This wraps the method `stub_hosts` and makes the stub specific to
|
@@ -698,7 +638,7 @@ module Beaker
|
|
698
638
|
#
|
699
639
|
# @see #stub_forge_on
|
700
640
|
def stub_forge(forge_host = nil)
|
701
|
-
#use global options hash
|
641
|
+
# use global options hash
|
702
642
|
forge_host ||= options[:forge_host]
|
703
643
|
stub_forge_on(default, forge_host)
|
704
644
|
end
|
@@ -714,7 +654,7 @@ module Beaker
|
|
714
654
|
nonssl_port = options[:puppetdb_port_nonssl] if nonssl_port.nil?
|
715
655
|
ssl_port = options[:puppetdb_port_ssl] if ssl_port.nil?
|
716
656
|
pe_ver = host['pe_ver'] || '0'
|
717
|
-
if version_is_less(pe_ver, '2016.1.0')
|
657
|
+
if version_is_less(pe_ver, '2016.1.0')
|
718
658
|
# the status endpoint was introduced in puppetdb 4.0. The earliest
|
719
659
|
# PE release with the 4.x pdb version was 2016.1.0
|
720
660
|
endpoint = 'pdb/meta/v1/version'
|
@@ -725,8 +665,8 @@ module Beaker
|
|
725
665
|
end
|
726
666
|
retry_on(host,
|
727
667
|
"curl -m 1 http://localhost:#{nonssl_port}/#{endpoint} | grep '#{expected_regex}'",
|
728
|
-
{:
|
729
|
-
curl_with_retries(
|
668
|
+
{ max_retries: 120 })
|
669
|
+
curl_with_retries('start puppetdb (ssl)',
|
730
670
|
host, "https://#{host.node_name}:#{ssl_port}", [35, 60])
|
731
671
|
end
|
732
672
|
|
@@ -738,7 +678,7 @@ module Beaker
|
|
738
678
|
# @return [Result] Result of the last HTTPS status check
|
739
679
|
def sleep_until_puppetserver_started(host, port = nil)
|
740
680
|
port = options[:puppetserver_port] if port.nil?
|
741
|
-
curl_with_retries(
|
681
|
+
curl_with_retries('start puppetserver (ssl)',
|
742
682
|
host, "https://#{host.node_name}:#{port}", [35, 60])
|
743
683
|
end
|
744
684
|
|
@@ -750,22 +690,22 @@ module Beaker
|
|
750
690
|
# @return [Result] Result of the last HTTPS status check
|
751
691
|
def sleep_until_nc_started(host, port = nil)
|
752
692
|
port = options[:nodeclassifier_port] if port.nil?
|
753
|
-
curl_with_retries(
|
693
|
+
curl_with_retries('start nodeclassifier (ssl)',
|
754
694
|
host, "https://#{host.node_name}:#{port}", [35, 60])
|
755
695
|
end
|
756
696
|
|
757
|
-
#stops the puppet agent running on the host
|
697
|
+
# stops the puppet agent running on the host
|
758
698
|
# @param [Host, Array<Host>, String, Symbol] agent One or more hosts to act upon,
|
759
699
|
# or a role (String or Symbol) that identifies one or more hosts.
|
760
700
|
# @param [Hash{Symbol=>String}] opts Options to alter execution.
|
761
701
|
# @option opts [Boolean] :run_in_parallel Whether to run on each host in parallel.
|
762
702
|
def stop_agent_on(agent, opts = {})
|
763
|
-
block_on agent, opts do |
|
703
|
+
block_on agent, opts do |host|
|
764
704
|
vardir = host.puppet_configprint['vardir']
|
765
705
|
|
766
706
|
# In 4.0 this was changed to just be `puppet`
|
767
707
|
agent_service = 'puppet'
|
768
|
-
|
708
|
+
unless aio_version?(host)
|
769
709
|
# The agent service is `pe-puppet` everywhere EXCEPT certain linux distros on PE 2.8
|
770
710
|
# In all the case that it is different, this init script will exist. So we can assume
|
771
711
|
# that if the script doesn't exist, we should just use `pe-puppet`
|
@@ -778,37 +718,34 @@ module Beaker
|
|
778
718
|
# the init script or system on that particular configuration.
|
779
719
|
avoid_puppet_at_all_costs = false
|
780
720
|
avoid_puppet_at_all_costs ||= host['platform'] =~ /el-4/
|
781
|
-
avoid_puppet_at_all_costs ||= host['pe_ver'] && version_is_less(host['pe_ver'],
|
721
|
+
avoid_puppet_at_all_costs ||= host['pe_ver'] && version_is_less(host['pe_ver'],
|
722
|
+
'3.2') && host['platform'] =~ /sles/
|
782
723
|
|
783
724
|
if avoid_puppet_at_all_costs
|
784
725
|
# When upgrading, puppet is already stopped. On EL4, this causes an exit code of '1'
|
785
|
-
on host, "/etc/init.d/#{agent_service} stop", :
|
726
|
+
on host, "/etc/init.d/#{agent_service} stop", acceptable_exit_codes: [0, 1]
|
786
727
|
else
|
787
728
|
on host, puppet_resource('service', agent_service, 'ensure=stopped')
|
788
729
|
end
|
789
730
|
|
790
|
-
#Ensure that a puppet run that was started before the last lock check is completed
|
731
|
+
# Ensure that a puppet run that was started before the last lock check is completed
|
791
732
|
agent_running = true
|
792
733
|
while agent_running
|
793
734
|
agent_running = host.file_exist?("#{vardir}/state/agent_catalog_run.lock")
|
794
|
-
if agent_running
|
795
|
-
sleep 2
|
796
|
-
end
|
735
|
+
sleep 2 if agent_running
|
797
736
|
end
|
798
|
-
|
799
737
|
end
|
800
738
|
end
|
801
739
|
|
802
|
-
#stops the puppet agent running on the default host
|
740
|
+
# stops the puppet agent running on the default host
|
803
741
|
# @see #stop_agent_on
|
804
742
|
def stop_agent
|
805
743
|
stop_agent_on(default)
|
806
744
|
end
|
807
745
|
|
808
|
-
#wait for a given host to appear in the dashboard
|
746
|
+
# wait for a given host to appear in the dashboard
|
809
747
|
# @deprecated this method should be removed in the next release since we don't believe the check is necessary.
|
810
748
|
def wait_for_host_in_dashboard(host)
|
811
|
-
|
812
749
|
hostname = host.node_name
|
813
750
|
hostcert = dashboard.puppet['hostcert']
|
814
751
|
key = dashboard.puppet['hostprivkey']
|
@@ -828,65 +765,44 @@ module Beaker
|
|
828
765
|
def sign_certificate_for(host = [])
|
829
766
|
hostnames = []
|
830
767
|
hosts = host.is_a?(Array) ? host : [host]
|
831
|
-
|
832
|
-
hosts.each{ |current_host|
|
768
|
+
hosts.each do |current_host|
|
833
769
|
if [master, dashboard, database].include? current_host
|
834
|
-
on
|
835
|
-
|
836
|
-
if version_is_less(puppet_version, '5.99')
|
837
|
-
on master, puppet("cert --allow-dns-alt-names sign #{current_host}" ), :acceptable_exit_codes => [0,24]
|
838
|
-
else
|
839
|
-
on master, "puppetserver ca sign --certname #{current_host}"
|
840
|
-
end
|
770
|
+
on(current_host, puppet('agent -t'), acceptable_exit_codes: [0, 1, 2])
|
771
|
+
on(master, "puppetserver ca sign --certname #{current_host}")
|
841
772
|
else
|
842
|
-
hostnames << Regexp.escape(
|
773
|
+
hostnames << Regexp.escape(current_host.node_name)
|
843
774
|
end
|
844
|
-
|
775
|
+
end
|
845
776
|
|
846
777
|
if hostnames.size < 1
|
847
|
-
|
848
|
-
on master, puppet("cert --sign --all --allow-dns-alt-names"),
|
849
|
-
:acceptable_exit_codes => [0,24]
|
850
|
-
else
|
851
|
-
on master, 'puppetserver ca sign --all', :acceptable_exit_codes => [0, 24]
|
852
|
-
end
|
778
|
+
on(master, 'puppetserver ca sign --all', acceptable_exit_codes: [0, 24])
|
853
779
|
return
|
854
780
|
end
|
855
781
|
|
856
782
|
while hostnames.size > 0
|
857
783
|
last_sleep = 0
|
858
784
|
next_sleep = 1
|
859
|
-
|
785
|
+
11.times do |i|
|
860
786
|
if i == 10
|
861
787
|
fail_test("Failed to sign cert for #{hostnames}")
|
862
788
|
hostnames.clear
|
863
789
|
end
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
hostnames.clear
|
870
|
-
break
|
871
|
-
end
|
872
|
-
else
|
873
|
-
on master, 'puppetserver ca sign --all', :acceptable_exit_codes => [0, 24]
|
874
|
-
out = on(master, 'puppetserver ca list --all').stdout
|
875
|
-
if out !~ /.*Requested.*/ && hostnames.all? { |hostname| out =~ /\b#{hostname}\b/ }
|
876
|
-
hostnames.clear
|
877
|
-
break
|
878
|
-
end
|
790
|
+
on(master, 'puppetserver ca sign --all', acceptable_exit_codes: [0, 24])
|
791
|
+
out = on(master, 'puppetserver ca list --all').stdout
|
792
|
+
if out !~ /.*Requested.*/ && hostnames.all? { |hostname| out =~ /\b#{hostname}\b/ }
|
793
|
+
hostnames.clear
|
794
|
+
break
|
879
795
|
end
|
880
796
|
|
881
797
|
sleep next_sleep
|
882
|
-
(last_sleep, next_sleep) = next_sleep, last_sleep+next_sleep
|
798
|
+
(last_sleep, next_sleep) = next_sleep, last_sleep + next_sleep
|
883
799
|
end
|
884
800
|
end
|
885
801
|
host
|
886
802
|
end
|
887
803
|
|
888
|
-
#prompt the master to sign certs then check to confirm the cert for the default host is signed
|
889
|
-
|
804
|
+
# prompt the master to sign certs then check to confirm the cert for the default host is signed
|
805
|
+
# @see #sign_certificate_for
|
890
806
|
def sign_certificate
|
891
807
|
sign_certificate_for(default)
|
892
808
|
end
|
@@ -907,14 +823,14 @@ module Beaker
|
|
907
823
|
# @note While tempting, this method should not be "optimized" to coalesce calls to
|
908
824
|
# chown user:group when both options are passed, as doing so will muddy the spec.
|
909
825
|
def create_tmpdir_on(hosts, path_prefix = '', user = nil, group = nil)
|
910
|
-
block_on hosts do |
|
826
|
+
block_on hosts do |host|
|
911
827
|
# create the directory
|
912
828
|
dir = host.tmpdir(path_prefix)
|
913
829
|
# only chown if explicitly passed; don't make assumptions about perms
|
914
830
|
# only `chown user` for cleaner codepaths
|
915
831
|
if user
|
916
832
|
# ensure user exists
|
917
|
-
|
833
|
+
unless host.user_get(user).success?
|
918
834
|
# clean up
|
919
835
|
host.rm_rf("#{dir}")
|
920
836
|
raise "User #{user} does not exist on #{host}."
|
@@ -926,7 +842,7 @@ module Beaker
|
|
926
842
|
# only chgrp if explicitly passed; don't make assumptions about perms
|
927
843
|
if group
|
928
844
|
# ensure group exists
|
929
|
-
|
845
|
+
unless host.group_get(group).success?
|
930
846
|
# clean up
|
931
847
|
# on host, "rmdir #{dir}"
|
932
848
|
host.rm_rf(dir)
|
@@ -953,7 +869,7 @@ module Beaker
|
|
953
869
|
# if this puppet command returns a non-zero exit code.
|
954
870
|
#
|
955
871
|
# @return [String] Returns the name of the newly-created dir.
|
956
|
-
def create_tmpdir_for_user(host, name='/tmp/beaker', user=nil)
|
872
|
+
def create_tmpdir_for_user(host, name = '/tmp/beaker', user = nil)
|
957
873
|
user ||= puppet_config(host, 'user', section: 'master')
|
958
874
|
create_tmpdir_on(host, name, user)
|
959
875
|
end
|