beaker-puppet 1.29.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|