beaker 0.0.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.travis.yml +8 -0
- data/README.md +6 -6
- data/beaker.gemspec +6 -2
- data/lib/beaker.rb +1 -1
- data/lib/beaker/answers.rb +34 -7
- data/lib/beaker/answers/version20.rb +124 -0
- data/lib/beaker/answers/version28.rb +21 -0
- data/lib/beaker/answers/version30.rb +24 -5
- data/lib/beaker/cli.rb +55 -41
- data/lib/beaker/command.rb +2 -2
- data/lib/beaker/dsl/helpers.rb +320 -106
- data/lib/beaker/dsl/install_utils.rb +202 -81
- data/lib/beaker/dsl/roles.rb +40 -0
- data/lib/beaker/host.rb +28 -20
- data/lib/beaker/host/unix.rb +7 -4
- data/lib/beaker/host/unix/pkg.rb +42 -12
- data/lib/beaker/host/windows.rb +9 -5
- data/lib/beaker/host/windows/group.rb +1 -1
- data/lib/beaker/host/windows/pkg.rb +41 -8
- data/lib/beaker/hypervisor.rb +23 -10
- data/lib/beaker/hypervisor/aixer.rb +15 -19
- data/lib/beaker/hypervisor/blimper.rb +71 -72
- data/lib/beaker/hypervisor/fusion.rb +11 -10
- data/lib/beaker/hypervisor/solaris.rb +17 -23
- data/lib/beaker/hypervisor/vagrant.rb +27 -12
- data/lib/beaker/hypervisor/vcloud.rb +154 -138
- data/lib/beaker/hypervisor/vcloud_pooled.rb +97 -0
- data/lib/beaker/hypervisor/vsphere.rb +8 -5
- data/lib/beaker/hypervisor/vsphere_helper.rb +43 -33
- data/lib/beaker/network_manager.rb +16 -12
- data/lib/beaker/options/command_line_parser.rb +199 -0
- data/lib/beaker/options/hosts_file_parser.rb +39 -0
- data/lib/beaker/options/options_file_parser.rb +45 -0
- data/lib/beaker/options/options_hash.rb +294 -0
- data/lib/beaker/options/parser.rb +288 -0
- data/lib/beaker/options/pe_version_scraper.rb +35 -0
- data/lib/beaker/options/presets.rb +70 -0
- data/lib/beaker/shared.rb +2 -1
- data/lib/beaker/shared/host_handler.rb +7 -2
- data/lib/beaker/shared/repetition.rb +1 -0
- data/lib/beaker/shared/timed.rb +14 -0
- data/lib/beaker/test_case.rb +2 -38
- data/lib/beaker/test_suite.rb +11 -25
- data/lib/beaker/utils/repo_control.rb +6 -8
- data/lib/beaker/utils/setup_helper.rb +9 -20
- data/spec/beaker/answers_spec.rb +109 -0
- data/spec/beaker/command_spec.rb +2 -2
- data/spec/beaker/dsl/assertions_spec.rb +1 -3
- data/spec/beaker/dsl/helpers_spec.rb +519 -84
- data/spec/beaker/dsl/install_utils_spec.rb +265 -16
- data/spec/beaker/dsl/roles_spec.rb +31 -10
- data/spec/beaker/host/windows/group_spec.rb +55 -0
- data/spec/beaker/host_spec.rb +130 -40
- data/spec/beaker/hypervisor/aixer_spec.rb +34 -0
- data/spec/beaker/hypervisor/blimper_spec.rb +77 -0
- data/spec/beaker/hypervisor/fusion_spec.rb +26 -0
- data/spec/beaker/hypervisor/hypervisor_spec.rb +66 -0
- data/spec/beaker/hypervisor/solaris_spec.rb +39 -0
- data/spec/beaker/hypervisor/vagrant_spec.rb +105 -0
- data/spec/beaker/hypervisor/vcloud_pooled_spec.rb +60 -0
- data/spec/beaker/hypervisor/vcloud_spec.rb +70 -0
- data/spec/beaker/hypervisor/vsphere_helper_spec.rb +162 -0
- data/spec/beaker/hypervisor/vsphere_spec.rb +76 -0
- data/spec/beaker/options/command_line_parser_spec.rb +25 -0
- data/spec/beaker/options/data/LATEST +1 -0
- data/spec/beaker/options/data/badyaml.cfg +21 -0
- data/spec/beaker/options/data/hosts.cfg +21 -0
- data/spec/beaker/options/data/opts.txt +6 -0
- data/spec/beaker/options/hosts_file_parser_spec.rb +30 -0
- data/spec/beaker/options/options_file_parser_spec.rb +23 -0
- data/spec/beaker/options/options_hash_spec.rb +111 -0
- data/spec/beaker/options/parser_spec.rb +172 -0
- data/spec/beaker/options/pe_version_scaper_spec.rb +15 -0
- data/spec/beaker/options/presets_spec.rb +24 -0
- data/spec/beaker/puppet_command_spec.rb +54 -21
- data/spec/beaker/shared/error_handler_spec.rb +40 -0
- data/spec/beaker/shared/host_handler_spec.rb +104 -0
- data/spec/beaker/shared/repetition_spec.rb +72 -0
- data/spec/beaker/test_suite_spec.rb +3 -16
- data/spec/beaker/utils/ntp_control_spec.rb +42 -0
- data/spec/beaker/utils/repo_control_spec.rb +168 -0
- data/spec/beaker/utils/setup_helper_spec.rb +82 -0
- data/spec/beaker/utils/validator_spec.rb +58 -0
- data/spec/helpers.rb +97 -0
- data/spec/matchers.rb +39 -0
- data/spec/mock_blimpy.rb +48 -0
- data/spec/mock_fission.rb +60 -0
- data/spec/mock_vsphere.rb +310 -0
- data/spec/mock_vsphere_helper.rb +183 -0
- data/spec/mocks.rb +83 -0
- data/spec/spec_helper.rb +8 -1
- metadata +106 -13
- data/beaker.rb +0 -10
- data/lib/beaker/options_parsing.rb +0 -323
- data/lib/beaker/test_config.rb +0 -148
- data/spec/beaker/options_parsing_spec.rb +0 -37
- data/spec/mocks_and_helpers.rb +0 -34
data/lib/beaker/command.rb
CHANGED
@@ -91,7 +91,7 @@ module Beaker
|
|
91
91
|
"#{env_string} #{cmd} #{options_string} #{args_string}"
|
92
92
|
end
|
93
93
|
|
94
|
-
# @param [Hash]
|
94
|
+
# @param [Hash] opts These are the options that the command takes
|
95
95
|
#
|
96
96
|
# @return [String] String of the options and flags for command.
|
97
97
|
#
|
@@ -150,7 +150,7 @@ module Beaker
|
|
150
150
|
# knowledge contained here. Really the relationship should be
|
151
151
|
# reversed where a host is asked for an appropriate Command when
|
152
152
|
# given a generic Command.
|
153
|
-
def environment_string_for host, env
|
153
|
+
def environment_string_for host, env
|
154
154
|
return '' if env.empty?
|
155
155
|
|
156
156
|
env_array = parse_env_hash_for( host, env ).compact
|
data/lib/beaker/dsl/helpers.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'resolv'
|
2
|
+
require 'inifile'
|
3
|
+
require 'timeout'
|
2
4
|
require 'beaker/dsl/outcomes'
|
3
5
|
|
4
6
|
module Beaker
|
@@ -13,6 +15,9 @@ module Beaker
|
|
13
15
|
# {Beaker::Host}'s interface to act upon.
|
14
16
|
# * a method *logger* that yields a logger implementing
|
15
17
|
# {Beaker::Logger}'s interface.
|
18
|
+
# * the module {Beaker::DSL::Roles} that provides access to the various hosts implementing
|
19
|
+
# {Beaker::Host}'s interface to act upon
|
20
|
+
# * the module {Beaker::DSL::Wrappers} the provides convenience methods for {Beaker::DSL::Command} creation
|
16
21
|
#
|
17
22
|
#
|
18
23
|
# @api dsl
|
@@ -31,7 +36,8 @@ module Beaker
|
|
31
36
|
|
32
37
|
# The primary method for executing commands *on* some set of hosts.
|
33
38
|
#
|
34
|
-
# @param [Host, Array<Host
|
39
|
+
# @param [Host, Array<Host>, String, Symbol] host One or more hosts to act upon,
|
40
|
+
# or a role (String or Symbol) that identifies one or more hosts.
|
35
41
|
# @param [String, Command] command The command to execute on *host*.
|
36
42
|
# @param [Proc] block Additional actions or assertions.
|
37
43
|
# @!macro common_opts
|
@@ -54,6 +60,12 @@ module Beaker
|
|
54
60
|
# end
|
55
61
|
# end
|
56
62
|
#
|
63
|
+
# @example Using a role (defined in a String) to identify the host
|
64
|
+
# on "master", "echo hello"
|
65
|
+
#
|
66
|
+
# @example Using a role (defined in a Symbol) to identify the host
|
67
|
+
# on :dashboard, "echo hello"
|
68
|
+
#
|
57
69
|
# @return [Result] An object representing the outcome of *command*.
|
58
70
|
# @raise [FailTest] Raises an exception if *command* obviously fails.
|
59
71
|
def on(host, command, opts = {}, &block)
|
@@ -61,6 +73,9 @@ module Beaker
|
|
61
73
|
cmd_opts = opts[:environment] ? { 'ENV' => opts.delete(:environment) } : Hash.new
|
62
74
|
command = Command.new(command.to_s, [], cmd_opts)
|
63
75
|
end
|
76
|
+
if host.is_a? String or host.is_a? Symbol
|
77
|
+
host = hosts_as(host) #check by role
|
78
|
+
end
|
64
79
|
if host.is_a? Array
|
65
80
|
host.map { |h| on h, command, opts, &block }
|
66
81
|
else
|
@@ -73,6 +88,66 @@ module Beaker
|
|
73
88
|
end
|
74
89
|
end
|
75
90
|
|
91
|
+
# The method for executing commands on the default host
|
92
|
+
#
|
93
|
+
# @param [String, Command] command The command to execute on *host*.
|
94
|
+
# @param [Proc] block Additional actions or assertions.
|
95
|
+
# @!macro common_opts
|
96
|
+
#
|
97
|
+
# @example Most basic usage
|
98
|
+
# shell 'ls /tmp'
|
99
|
+
#
|
100
|
+
# @example Allowing additional exit codes to pass
|
101
|
+
# shell 'puppet agent -t', :acceptable_exit_codes => [0,2]
|
102
|
+
#
|
103
|
+
# @example Using the returned result for any kind of checking
|
104
|
+
# if shell('ls -la ~').stdout =~ /\.bin/
|
105
|
+
# ...do some action...
|
106
|
+
# end
|
107
|
+
#
|
108
|
+
# @example Using TestCase helpers from within a test.
|
109
|
+
# agents.each do |agent|
|
110
|
+
# shell('cat /etc/puppet/puppet.conf') do |result|
|
111
|
+
# assert_match result.stdout, /server = #{master}/, 'WTF Mate'
|
112
|
+
# end
|
113
|
+
# end
|
114
|
+
#
|
115
|
+
# @return [Result] An object representing the outcome of *command*.
|
116
|
+
# @raise [FailTest] Raises an exception if *command* obviously fails.
|
117
|
+
def shell(command, opts = {}, &block)
|
118
|
+
on(default, command, opts, &block)
|
119
|
+
end
|
120
|
+
|
121
|
+
# @deprecated
|
122
|
+
# An proxy for the last {Beaker::Result#stdout} returned by
|
123
|
+
# a method that makes remote calls. Use the {Beaker::Result}
|
124
|
+
# object returned by the method directly instead. For Usage see
|
125
|
+
# {Beaker::Result}.
|
126
|
+
def stdout
|
127
|
+
return nil if @result.nil?
|
128
|
+
@result.stdout
|
129
|
+
end
|
130
|
+
|
131
|
+
# @deprecated
|
132
|
+
# An proxy for the last {Beaker::Result#stderr} returned by
|
133
|
+
# a method that makes remote calls. Use the {Beaker::Result}
|
134
|
+
# object returned by the method directly instead. For Usage see
|
135
|
+
# {Beaker::Result}.
|
136
|
+
def stderr
|
137
|
+
return nil if @result.nil?
|
138
|
+
@result.stderr
|
139
|
+
end
|
140
|
+
|
141
|
+
# @deprecated
|
142
|
+
# An proxy for the last {Beaker::Result#exit_code} returned by
|
143
|
+
# a method that makes remote calls. Use the {Beaker::Result}
|
144
|
+
# object returned by the method directly instead. For Usage see
|
145
|
+
# {Beaker::Result}.
|
146
|
+
def exit_code
|
147
|
+
return nil if @result.nil?
|
148
|
+
@result.exit_code
|
149
|
+
end
|
150
|
+
|
76
151
|
# Move a file from a remote to a local path
|
77
152
|
# @note If using {Beaker::Host} for the hosts *scp* is not
|
78
153
|
# required on the system as it uses Ruby's net/scp library. The
|
@@ -119,17 +194,17 @@ module Beaker
|
|
119
194
|
|
120
195
|
# Check to see if a package is installed on a remote host
|
121
196
|
#
|
122
|
-
# @param [Host] host A host object
|
197
|
+
# @param [Host] host A host object
|
123
198
|
# @param [String] package_name Name of the package to check for.
|
124
199
|
#
|
125
|
-
# @return [Boolean] true/false if the package is found
|
200
|
+
# @return [Boolean] true/false if the package is found
|
126
201
|
def check_for_package host, package_name
|
127
202
|
host.check_for_package package_name
|
128
203
|
end
|
129
204
|
|
130
205
|
# Install a package on a host
|
131
206
|
#
|
132
|
-
# @param [Host] host A host object
|
207
|
+
# @param [Host] host A host object
|
133
208
|
# @param [String] package_name Name of the package to install
|
134
209
|
#
|
135
210
|
# @return [Result] An object representing the outcome of *install command*.
|
@@ -180,6 +255,12 @@ module Beaker
|
|
180
255
|
on host, remote_path, opts, &block
|
181
256
|
end
|
182
257
|
|
258
|
+
# Move a local script to default host and execute it
|
259
|
+
# @see #run_script_on
|
260
|
+
def run_script(script, opts = {}, &block)
|
261
|
+
run_script_on(default, script, opts, &block)
|
262
|
+
end
|
263
|
+
|
183
264
|
# Limit the hosts a test case is run against
|
184
265
|
# @note This will modify the {Beaker::TestCase#hosts} member
|
185
266
|
# in place unless an array of hosts is passed into it and
|
@@ -198,7 +279,7 @@ module Beaker
|
|
198
279
|
# considered for inclusion or exclusion. The key is any attribute
|
199
280
|
# of the host that will be yielded by {Beaker::Host#[]}.
|
200
281
|
# The value can be any string/regex or array of strings/regexp.
|
201
|
-
# The values are compared using
|
282
|
+
# The values are compared using [Enumerable#any?] so that if one
|
202
283
|
# value of an array matches the host is considered a match for that
|
203
284
|
# criteria.
|
204
285
|
# @param [Array<Host>] host_array This creatively named parameter is
|
@@ -259,6 +340,23 @@ module Beaker
|
|
259
340
|
hosts_to_modify
|
260
341
|
end
|
261
342
|
|
343
|
+
# Ensures that host restrictions as specifid by type, criteria and
|
344
|
+
# host_array are confined to activity within the passed block.
|
345
|
+
# TestCase#hosts is reset after block has executed.
|
346
|
+
#
|
347
|
+
# @see #confine
|
348
|
+
def confine_block(type, criteria, host_array = nil, &block)
|
349
|
+
begin
|
350
|
+
original_hosts = self.hosts.dup
|
351
|
+
confine(type, criteria, host_array)
|
352
|
+
|
353
|
+
yield
|
354
|
+
|
355
|
+
ensure
|
356
|
+
self.hosts = original_hosts
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
262
360
|
# @!visibility private
|
263
361
|
def inspect_host(host, property, one_or_more_values)
|
264
362
|
values = Array(one_or_more_values)
|
@@ -285,14 +383,25 @@ module Beaker
|
|
285
383
|
# 6. Revert Puppet to the pre-test state
|
286
384
|
# 7. Testing artifacts are saved in a folder named for the test
|
287
385
|
#
|
288
|
-
# @param [Host]
|
386
|
+
# @param [Host] host One object that act like Host
|
289
387
|
#
|
290
|
-
# @param [Hash{Symbol=>String}]
|
291
|
-
# config_opts Represent puppet settings.
|
388
|
+
# @param [Hash{Symbol=>String}] conf_opts Represents puppet settings.
|
292
389
|
# Sections of the puppet.conf may be
|
293
390
|
# specified, if no section is specified the
|
294
391
|
# a puppet.conf file will be written with the
|
295
|
-
# options put in a section named after [mode]
|
392
|
+
# options put in a section named after [mode]
|
393
|
+
#
|
394
|
+
# There is a special setting for command_line
|
395
|
+
# arguments such as --debug or --logdest, which
|
396
|
+
# cannot be set in puppet.conf. For example:
|
397
|
+
#
|
398
|
+
# :__commandline_args__ => '--logdest /tmp/a.log'
|
399
|
+
#
|
400
|
+
# These will only be applied when starting a FOSS
|
401
|
+
# master, as a pe master is just bounced.
|
402
|
+
#
|
403
|
+
# @param [File] testdir The temporary directory which will hold backup
|
404
|
+
# configuration, and other test artifacts.
|
296
405
|
#
|
297
406
|
# @param [Block] block The point of this method, yields so
|
298
407
|
# tests may be ran. After the block is finished
|
@@ -314,71 +423,127 @@ module Beaker
|
|
314
423
|
#
|
315
424
|
# @api dsl
|
316
425
|
def with_puppet_running_on host, conf_opts, testdir = host.tmpdir(File.basename(@path)), &block
|
426
|
+
raise(ArgumentError, "with_puppet_running_on's conf_opts must be a Hash. You provided a #{conf_opts.class}: '#{conf_opts}'") if !conf_opts.kind_of?(Hash)
|
427
|
+
cmdline_args = conf_opts.delete(:__commandline_args__)
|
428
|
+
|
317
429
|
begin
|
318
|
-
backup_file host, host['puppetpath'], testdir, 'puppet.conf'
|
430
|
+
backup_file = backup_the_file(host, host['puppetpath'], testdir, 'puppet.conf')
|
319
431
|
lay_down_new_puppet_conf host, conf_opts, testdir
|
320
432
|
|
321
433
|
if host.is_pe?
|
322
|
-
bounce_service( 'pe-httpd' )
|
323
|
-
|
434
|
+
bounce_service( host, 'pe-httpd' )
|
324
435
|
else
|
325
|
-
start_puppet_from_source_on!( host )
|
436
|
+
puppet_master_started = start_puppet_from_source_on!( host, cmdline_args )
|
326
437
|
end
|
327
438
|
|
328
439
|
yield self if block_given?
|
440
|
+
|
441
|
+
rescue Exception => early_exception
|
442
|
+
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")
|
443
|
+
raise(original_exception)
|
444
|
+
|
329
445
|
ensure
|
330
|
-
|
446
|
+
begin
|
447
|
+
restore_puppet_conf_from_backup( host, backup_file )
|
331
448
|
|
332
|
-
|
333
|
-
|
449
|
+
if host.is_pe?
|
450
|
+
bounce_service( host, 'pe-httpd' )
|
451
|
+
else
|
452
|
+
stop_puppet_from_source_on( host ) if puppet_master_started
|
453
|
+
end
|
334
454
|
|
335
|
-
|
336
|
-
|
455
|
+
rescue Exception => teardown_exception
|
456
|
+
if original_exception
|
457
|
+
logger.error("Raised during attempt to teardown with_puppet_running_on: #{teardown_exception}\n---\n")
|
458
|
+
raise original_exception
|
459
|
+
else
|
460
|
+
raise teardown_exception
|
461
|
+
end
|
337
462
|
end
|
338
463
|
end
|
339
464
|
end
|
340
465
|
|
466
|
+
# Test Puppet running in a certain run mode with specific options,
|
467
|
+
# on the default host
|
468
|
+
# @api dsl
|
469
|
+
# @see #with_puppet_running_on
|
470
|
+
def with_puppet_running conf_opts, testdir = host.tmpdir(File.basename(@path)), &block
|
471
|
+
with_puppet_running_on(default, conf_opts, testdir, &block)
|
472
|
+
end
|
473
|
+
|
341
474
|
# @!visibility private
|
342
|
-
def restore_puppet_conf_from_backup( host )
|
475
|
+
def restore_puppet_conf_from_backup( host, backup_file )
|
343
476
|
puppetpath = host['puppetpath']
|
344
477
|
|
345
|
-
host.exec( Command.new( "if [ -f #{
|
346
|
-
"cat #{
|
347
|
-
"#{puppetpath}/puppet.conf; " +
|
348
|
-
"rm -
|
478
|
+
host.exec( Command.new( "if [ -f '#{backup_file}' ]; then " +
|
479
|
+
"cat '#{backup_file}' > " +
|
480
|
+
"'#{puppetpath}/puppet.conf'; " +
|
481
|
+
"rm -f '#{backup_file}'; " +
|
349
482
|
"fi" ) )
|
350
483
|
end
|
351
484
|
|
352
485
|
# @!visibility private
|
353
|
-
def
|
486
|
+
def backup_the_file host, current_dir, new_dir, filename = 'puppet.conf'
|
354
487
|
old_location = current_dir + '/' + filename
|
355
|
-
new_location = new_dir + '/' + filename
|
488
|
+
new_location = new_dir + '/' + filename + '.bak'
|
356
489
|
|
357
490
|
host.exec( Command.new( "cp #{old_location} #{new_location}" ) )
|
491
|
+
|
492
|
+
return new_location
|
358
493
|
end
|
359
494
|
|
360
495
|
# @!visibility private
|
361
|
-
def start_puppet_from_source_on! host
|
362
|
-
host.exec(
|
496
|
+
def start_puppet_from_source_on! host, args = ''
|
497
|
+
host.exec( puppet( 'master', args ) )
|
363
498
|
|
364
499
|
logger.debug 'Waiting for the puppet master to start'
|
365
500
|
unless port_open_within?( host, 8140, 10 )
|
501
|
+
dump_puppet_log(host)
|
366
502
|
raise Beaker::DSL::FailTest, 'Puppet master did not start in a timely fashion'
|
367
503
|
end
|
368
504
|
logger.debug 'The puppet master has started'
|
505
|
+
return true
|
369
506
|
end
|
370
507
|
|
371
508
|
# @!visibility private
|
372
509
|
def stop_puppet_from_source_on( host )
|
373
|
-
host.exec( Command.new(
|
510
|
+
pid = host.exec( Command.new('cat `puppet master --configprint pidfile`') ).stdout.chomp
|
511
|
+
host.exec( Command.new( "kill #{pid}" ) )
|
512
|
+
Timeout.timeout(10) do
|
513
|
+
while host.exec( Command.new( "kill -0 #{pid}"), :acceptable_exit_codes => [0,1] ).exit_code == 0 do
|
514
|
+
# until kill -0 finds no process and we know that puppet has finished cleaning up
|
515
|
+
sleep 1
|
516
|
+
end
|
517
|
+
end
|
518
|
+
rescue RuntimeError => e
|
519
|
+
dump_puppet_log host
|
520
|
+
raise e
|
521
|
+
end
|
522
|
+
|
523
|
+
# @!visibility private
|
524
|
+
def dump_puppet_log(host)
|
525
|
+
syslogfile = case host['platform']
|
526
|
+
when /fedora|centos|el/ then '/var/log/messages'
|
527
|
+
when /ubuntu|debian/ then '/var/log/syslog'
|
528
|
+
else return
|
529
|
+
end
|
530
|
+
|
531
|
+
logger.notify "\n*************************"
|
532
|
+
logger.notify "* Dumping master log *"
|
533
|
+
logger.notify "*************************"
|
534
|
+
host.exec( Command.new( "tail -n 100 #{syslogfile}" ), :acceptable_exit_codes => [0,1])
|
535
|
+
logger.notify "*************************\n"
|
374
536
|
end
|
375
537
|
|
376
538
|
# @!visibility private
|
377
539
|
def lay_down_new_puppet_conf( host, configuration_options, testdir )
|
378
|
-
new_conf = puppet_conf_for( host )
|
540
|
+
new_conf = puppet_conf_for( host, configuration_options )
|
379
541
|
create_remote_file host, "#{testdir}/puppet.conf", new_conf.to_s
|
380
542
|
|
381
|
-
host.exec(
|
543
|
+
host.exec(
|
544
|
+
Command.new( "cat #{testdir}/puppet.conf > #{host['puppetpath']}/puppet.conf" ),
|
545
|
+
:silent => true
|
546
|
+
)
|
382
547
|
host.exec( Command.new( "cat #{host['puppetpath']}/puppet.conf" ) )
|
383
548
|
end
|
384
549
|
|
@@ -467,6 +632,12 @@ module Beaker
|
|
467
632
|
on host, puppet( 'apply', *args), on_options, &block
|
468
633
|
end
|
469
634
|
|
635
|
+
# Runs 'puppet apply' on default host, piping manifest through stdin
|
636
|
+
# @see #apply_manifest_on
|
637
|
+
def apply_manifest(manifest, opts = {}, &block)
|
638
|
+
apply_manifest_on(default, manifest, opts, &block)
|
639
|
+
end
|
640
|
+
|
470
641
|
# @deprecated
|
471
642
|
def run_agent_on(host, arg='--no-daemonize --verbose --onetime --test',
|
472
643
|
options={}, &block)
|
@@ -517,7 +688,7 @@ module Beaker
|
|
517
688
|
# removed always.
|
518
689
|
#
|
519
690
|
# @param machine [String] the host to execute this stub
|
520
|
-
# @param
|
691
|
+
# @param ip_spec [Hash{String=>String}] a hash containing the host to ip
|
521
692
|
# mappings
|
522
693
|
# @example Stub puppetlabs.com on the master to 127.0.0.1
|
523
694
|
# stub_hosts_on(master, 'puppetlabs.com' => '127.0.0.1')
|
@@ -537,6 +708,16 @@ module Beaker
|
|
537
708
|
end
|
538
709
|
end
|
539
710
|
|
711
|
+
# This method accepts a block and using the puppet resource 'host' will
|
712
|
+
# setup host aliases before and after that block on the default host
|
713
|
+
#
|
714
|
+
# @example Stub puppetlabs.com on the default host to 127.0.0.1
|
715
|
+
# stub_hosts('puppetlabs.com' => '127.0.0.1')
|
716
|
+
# @see #stub_hosts_on
|
717
|
+
def stub_hosts(ip_spec)
|
718
|
+
stub_hosts_on(default, ip_spec)
|
719
|
+
end
|
720
|
+
|
540
721
|
# This wraps the method `stub_hosts_on` and makes the stub specific to
|
541
722
|
# the forge alias.
|
542
723
|
#
|
@@ -545,81 +726,114 @@ module Beaker
|
|
545
726
|
@forge_ip ||= Resolv.getaddress(forge)
|
546
727
|
stub_hosts_on(machine, 'forge.puppetlabs.com' => @forge_ip)
|
547
728
|
end
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
729
|
+
|
730
|
+
# This wraps the method `stub_hosts` and makes the stub specific to
|
731
|
+
# the forge alias.
|
732
|
+
#
|
733
|
+
# @see #stub_forge_on
|
734
|
+
def stub_forge
|
735
|
+
stub_forge_on(default)
|
736
|
+
end
|
737
|
+
|
738
|
+
def sleep_until_puppetdb_started(host)
|
739
|
+
curl_with_retries("start puppetdb", host, "http://localhost:8080", 0, 120)
|
740
|
+
curl_with_retries("start puppetdb (ssl)",
|
741
|
+
host, "https://#{host.node_name}:8081", [35, 60])
|
742
|
+
end
|
743
|
+
|
744
|
+
def curl_with_retries(desc, host, url, desired_exit_codes, max_retries = 60, retry_interval = 1)
|
745
|
+
retry_command(desc, host, "curl #{url}", desired_exit_codes, max_retries, retry_interval)
|
746
|
+
end
|
747
|
+
|
748
|
+
def retry_command(desc, host, command, desired_exit_codes = 0, max_retries = 60, retry_interval = 1)
|
749
|
+
desired_exit_codes = [desired_exit_codes].flatten
|
750
|
+
result = on host, command, :acceptable_exit_codes => (0...127)
|
751
|
+
num_retries = 0
|
752
|
+
until desired_exit_codes.include?(result.exit_code)
|
753
|
+
sleep retry_interval
|
754
|
+
result = on host, command, :acceptable_exit_codes => (0...127)
|
755
|
+
num_retries += 1
|
756
|
+
if (num_retries > max_retries)
|
757
|
+
fail("Unable to #{desc}")
|
758
|
+
end
|
759
|
+
end
|
760
|
+
end
|
761
|
+
|
762
|
+
#stops the puppet agent running on the host
|
763
|
+
def stop_agent_on(agent)
|
764
|
+
vardir = agent.puppet['vardir']
|
765
|
+
agent_running = true
|
766
|
+
while agent_running
|
767
|
+
result = on agent, "[ -e '#{vardir}/state/agent_catalog_run.lock' ]", :acceptable_exit_codes => [0,1]
|
768
|
+
agent_running = (result.exit_code == 0)
|
769
|
+
sleep 2 unless agent_running
|
770
|
+
end
|
771
|
+
|
772
|
+
if agent['platform'].include?('solaris')
|
773
|
+
on(agent, '/usr/sbin/svcadm disable -s svc:/network/pe-puppet:default')
|
774
|
+
elsif agent['platform'].include?('aix')
|
775
|
+
on(agent, '/usr/bin/stopsrc -s pe-puppet')
|
776
|
+
elsif agent['platform'].include?('windows')
|
777
|
+
on(agent, 'net stop pe-puppet', :acceptable_exit_codes => [0,2])
|
778
|
+
else
|
779
|
+
# For the sake of not passing the PE version into this method,
|
780
|
+
# we just query the system to find out which service we want to
|
781
|
+
# stop
|
782
|
+
result = on agent, "[ -e /etc/init.d/pe-puppet-agent ]", :acceptable_exit_codes => [0,1]
|
783
|
+
service = (result.exit_code == 0) ? 'pe-puppet-agent' : 'pe-puppet'
|
784
|
+
on(agent, "/etc/init.d/#{service} stop")
|
785
|
+
end
|
786
|
+
end
|
787
|
+
|
788
|
+
#stops the puppet agent running on the default host
|
789
|
+
# @see #stop_agent_on
|
790
|
+
def stop_agent
|
791
|
+
stop_agent_on(default)
|
792
|
+
end
|
793
|
+
|
794
|
+
|
795
|
+
#wait for a given host to appear in the dashboard
|
796
|
+
def wait_for_host_in_dashboard(host)
|
797
|
+
hostname = host.node_name
|
798
|
+
retry_command("Wait for #{hostname} to be in the console", dashboard, "! curl --sslv3 -k -I https://#{dashboard}/nodes/#{hostname} | grep '404 Not Found'")
|
799
|
+
end
|
800
|
+
|
801
|
+
# Ensure the host has requested a cert, then sign it
|
802
|
+
#
|
803
|
+
# @param [Host] host The host to sign for
|
804
|
+
#
|
805
|
+
# @returns nil
|
806
|
+
# @raise [FailTest] if process times out
|
807
|
+
def sign_certificate_for(host)
|
808
|
+
if [master, dashboard, database].include? host
|
809
|
+
|
810
|
+
on host, puppet( 'agent -t' ), :acceptable_exit_codes => [0,1,2]
|
811
|
+
on master, puppet( "cert --allow-dns-alt-names sign #{host}" ), :acceptable_exit_codes => [0,24]
|
812
|
+
|
813
|
+
else
|
814
|
+
|
815
|
+
hostname = Regexp.escape host.node_name
|
816
|
+
|
817
|
+
last_sleep = 0
|
818
|
+
next_sleep = 1
|
819
|
+
(0..10).each do |i|
|
820
|
+
fail_test("Failed to sign cert for #{hostname}") if i == 10
|
821
|
+
|
822
|
+
on master, puppet("cert --sign --all"), :acceptable_exit_codes => [0,24]
|
823
|
+
break if on(master, puppet("cert --list --all")).stdout =~ /\+ "?#{hostname}"?/
|
824
|
+
sleep next_sleep
|
825
|
+
(last_sleep, next_sleep) = next_sleep, last_sleep+next_sleep
|
826
|
+
end
|
827
|
+
|
828
|
+
end
|
829
|
+
end
|
830
|
+
|
831
|
+
#prompt the master to sign certs then check to confirm the cert for the default host is signed
|
832
|
+
#@see #sign_certificate_for
|
833
|
+
def sign_certificate
|
834
|
+
sign_certificate_for(default)
|
835
|
+
end
|
836
|
+
|
623
837
|
end
|
624
838
|
end
|
625
839
|
end
|