beaker 0.0.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +8 -8
  2. data/.travis.yml +8 -0
  3. data/README.md +6 -6
  4. data/beaker.gemspec +6 -2
  5. data/lib/beaker.rb +1 -1
  6. data/lib/beaker/answers.rb +34 -7
  7. data/lib/beaker/answers/version20.rb +124 -0
  8. data/lib/beaker/answers/version28.rb +21 -0
  9. data/lib/beaker/answers/version30.rb +24 -5
  10. data/lib/beaker/cli.rb +55 -41
  11. data/lib/beaker/command.rb +2 -2
  12. data/lib/beaker/dsl/helpers.rb +320 -106
  13. data/lib/beaker/dsl/install_utils.rb +202 -81
  14. data/lib/beaker/dsl/roles.rb +40 -0
  15. data/lib/beaker/host.rb +28 -20
  16. data/lib/beaker/host/unix.rb +7 -4
  17. data/lib/beaker/host/unix/pkg.rb +42 -12
  18. data/lib/beaker/host/windows.rb +9 -5
  19. data/lib/beaker/host/windows/group.rb +1 -1
  20. data/lib/beaker/host/windows/pkg.rb +41 -8
  21. data/lib/beaker/hypervisor.rb +23 -10
  22. data/lib/beaker/hypervisor/aixer.rb +15 -19
  23. data/lib/beaker/hypervisor/blimper.rb +71 -72
  24. data/lib/beaker/hypervisor/fusion.rb +11 -10
  25. data/lib/beaker/hypervisor/solaris.rb +17 -23
  26. data/lib/beaker/hypervisor/vagrant.rb +27 -12
  27. data/lib/beaker/hypervisor/vcloud.rb +154 -138
  28. data/lib/beaker/hypervisor/vcloud_pooled.rb +97 -0
  29. data/lib/beaker/hypervisor/vsphere.rb +8 -5
  30. data/lib/beaker/hypervisor/vsphere_helper.rb +43 -33
  31. data/lib/beaker/network_manager.rb +16 -12
  32. data/lib/beaker/options/command_line_parser.rb +199 -0
  33. data/lib/beaker/options/hosts_file_parser.rb +39 -0
  34. data/lib/beaker/options/options_file_parser.rb +45 -0
  35. data/lib/beaker/options/options_hash.rb +294 -0
  36. data/lib/beaker/options/parser.rb +288 -0
  37. data/lib/beaker/options/pe_version_scraper.rb +35 -0
  38. data/lib/beaker/options/presets.rb +70 -0
  39. data/lib/beaker/shared.rb +2 -1
  40. data/lib/beaker/shared/host_handler.rb +7 -2
  41. data/lib/beaker/shared/repetition.rb +1 -0
  42. data/lib/beaker/shared/timed.rb +14 -0
  43. data/lib/beaker/test_case.rb +2 -38
  44. data/lib/beaker/test_suite.rb +11 -25
  45. data/lib/beaker/utils/repo_control.rb +6 -8
  46. data/lib/beaker/utils/setup_helper.rb +9 -20
  47. data/spec/beaker/answers_spec.rb +109 -0
  48. data/spec/beaker/command_spec.rb +2 -2
  49. data/spec/beaker/dsl/assertions_spec.rb +1 -3
  50. data/spec/beaker/dsl/helpers_spec.rb +519 -84
  51. data/spec/beaker/dsl/install_utils_spec.rb +265 -16
  52. data/spec/beaker/dsl/roles_spec.rb +31 -10
  53. data/spec/beaker/host/windows/group_spec.rb +55 -0
  54. data/spec/beaker/host_spec.rb +130 -40
  55. data/spec/beaker/hypervisor/aixer_spec.rb +34 -0
  56. data/spec/beaker/hypervisor/blimper_spec.rb +77 -0
  57. data/spec/beaker/hypervisor/fusion_spec.rb +26 -0
  58. data/spec/beaker/hypervisor/hypervisor_spec.rb +66 -0
  59. data/spec/beaker/hypervisor/solaris_spec.rb +39 -0
  60. data/spec/beaker/hypervisor/vagrant_spec.rb +105 -0
  61. data/spec/beaker/hypervisor/vcloud_pooled_spec.rb +60 -0
  62. data/spec/beaker/hypervisor/vcloud_spec.rb +70 -0
  63. data/spec/beaker/hypervisor/vsphere_helper_spec.rb +162 -0
  64. data/spec/beaker/hypervisor/vsphere_spec.rb +76 -0
  65. data/spec/beaker/options/command_line_parser_spec.rb +25 -0
  66. data/spec/beaker/options/data/LATEST +1 -0
  67. data/spec/beaker/options/data/badyaml.cfg +21 -0
  68. data/spec/beaker/options/data/hosts.cfg +21 -0
  69. data/spec/beaker/options/data/opts.txt +6 -0
  70. data/spec/beaker/options/hosts_file_parser_spec.rb +30 -0
  71. data/spec/beaker/options/options_file_parser_spec.rb +23 -0
  72. data/spec/beaker/options/options_hash_spec.rb +111 -0
  73. data/spec/beaker/options/parser_spec.rb +172 -0
  74. data/spec/beaker/options/pe_version_scaper_spec.rb +15 -0
  75. data/spec/beaker/options/presets_spec.rb +24 -0
  76. data/spec/beaker/puppet_command_spec.rb +54 -21
  77. data/spec/beaker/shared/error_handler_spec.rb +40 -0
  78. data/spec/beaker/shared/host_handler_spec.rb +104 -0
  79. data/spec/beaker/shared/repetition_spec.rb +72 -0
  80. data/spec/beaker/test_suite_spec.rb +3 -16
  81. data/spec/beaker/utils/ntp_control_spec.rb +42 -0
  82. data/spec/beaker/utils/repo_control_spec.rb +168 -0
  83. data/spec/beaker/utils/setup_helper_spec.rb +82 -0
  84. data/spec/beaker/utils/validator_spec.rb +58 -0
  85. data/spec/helpers.rb +97 -0
  86. data/spec/matchers.rb +39 -0
  87. data/spec/mock_blimpy.rb +48 -0
  88. data/spec/mock_fission.rb +60 -0
  89. data/spec/mock_vsphere.rb +310 -0
  90. data/spec/mock_vsphere_helper.rb +183 -0
  91. data/spec/mocks.rb +83 -0
  92. data/spec/spec_helper.rb +8 -1
  93. metadata +106 -13
  94. data/beaker.rb +0 -10
  95. data/lib/beaker/options_parsing.rb +0 -323
  96. data/lib/beaker/test_config.rb +0 -148
  97. data/spec/beaker/options_parsing_spec.rb +0 -37
  98. data/spec/mocks_and_helpers.rb +0 -34
@@ -91,7 +91,7 @@ module Beaker
91
91
  "#{env_string} #{cmd} #{options_string} #{args_string}"
92
92
  end
93
93
 
94
- # @param [Hash] options These are the options that the command takes
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
@@ -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>] host One or more hosts to act upon.
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 {Enumerable#any?} so that if one
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] hosts One object that act like 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
- restore_puppet_conf_from_backup( host )
446
+ begin
447
+ restore_puppet_conf_from_backup( host, backup_file )
331
448
 
332
- if host.is_pe?
333
- bounce_service( 'pe-httpd' )
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
- else
336
- stop_puppet_from_source_on( host )
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 #{puppetpath}/puppet.conf.bak ]; then " +
346
- "cat #{puppetpath}/puppet.conf.bak > " +
347
- "#{puppetpath}/puppet.conf; " +
348
- "rm -rf #{puppetpath}/puppet.conf.bak; " +
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 backup_file host, current_dir, new_dir, filename = 'puppet.conf'
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( Command.new( puppet( 'master' ) ) )
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( 'kill $(cat `puppet master --configprint pidfile`)' ) )
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( Command.new( "cat #{testdir}/puppet.conf > #{host['puppetpath']}/puppet.conf", :silent => true ) )
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 hosts [Hash{String=>String}] a hash containing the host to ip
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
- def sleep_until_puppetdb_started(host)
549
- curl_with_retries("start puppetdb", host, "http://localhost:8080", 0, 120)
550
- curl_with_retries("start puppetdb (ssl)",
551
- host, "https://#{host.node_name}:8081", [35, 60])
552
- end
553
-
554
- def curl_with_retries(desc, host, url, desired_exit_codes, max_retries = 60, retry_interval = 1)
555
- retry_command(desc, host, "curl #{url}", desired_exit_codes, max_retries, retry_interval)
556
- end
557
-
558
- def retry_command(desc, host, command, desired_exit_codes = 0, max_retries = 60, retry_interval = 1)
559
- desired_exit_codes = [desired_exit_codes].flatten
560
- result = on host, command, :acceptable_exit_codes => (0...127)
561
- num_retries = 0
562
- until desired_exit_codes.include?(result.exit_code)
563
- sleep retry_interval
564
- result = on host, command, :acceptable_exit_codes => (0...127)
565
- num_retries += 1
566
- if (num_retries > max_retries)
567
- fail("Unable to #{desc}")
568
- end
569
- end
570
- end
571
-
572
- #stops the puppet agent running on the host
573
- def stop_agent(agent)
574
- vardir = agent.puppet['vardir']
575
- agent_running = true
576
- while agent_running
577
- result = on agent, "[ -e '#{vardir}/state/agent_catalog_run.lock' ]", :acceptable_exit_codes => [0,1]
578
- agent_running = (result.exit_code == 0)
579
- sleep 2 unless agent_running
580
- end
581
-
582
- if agent['platform'].include?('solaris')
583
- on(agent, '/usr/sbin/svcadm disable -s svc:/network/pe-puppet:default')
584
- elsif agent['platform'].include?('aix')
585
- on(agent, '/usr/bin/stopsrc -s pe-puppet')
586
- elsif agent['platform'].include?('windows')
587
- on(agent, 'net stop pe-puppet', :acceptable_exit_codes => [0,2])
588
- else
589
- # For the sake of not passing the PE version into this method,
590
- # we just query the system to find out which service we want to
591
- # stop
592
- result = on agent, "[ -e /etc/init.d/pe-puppet-agent ]", :acceptable_exit_codes => [0,1]
593
- service = (result.exit_code == 0) ? 'pe-puppet-agent' : 'pe-puppet'
594
- on(agent, "/etc/init.d/#{service} stop")
595
- end
596
- end
597
-
598
-
599
- #wait for a given host to appear in the dashboard
600
- def wait_for_host_in_dashboard(host)
601
- hostname = host.node_name
602
- retry_command("Wait for #{hostname} to be in the console", dashboard, "! curl --sslv3 -k -I https://#{dashboard}/nodes/#{hostname} | grep '404 Not Found'")
603
- end
604
-
605
-
606
- #prompt the master to sign certs then check to confirm the cert for this host is signed
607
- def sign_certificate(host)
608
- return if [master, dashboard, database].include? host
609
-
610
- hostname = Regexp.escape host.node_name
611
-
612
- last_sleep = 0
613
- next_sleep = 1
614
- (0..10).each do |i|
615
- fail_test("Failed to sign cert for #{hostname}") if i == 10
616
-
617
- on master, puppet("cert --sign --all"), :acceptable_exit_codes => [0,24]
618
- break if on(master, puppet("cert --list --all")).stdout =~ /\+ "?#{hostname}"?/
619
- sleep next_sleep
620
- (last_sleep, next_sleep) = next_sleep, last_sleep+next_sleep
621
- end
622
- end
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