beaker 1.21.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +8 -8
  2. data/.gitignore +1 -0
  3. data/.rspec +1 -0
  4. data/CONTRIBUTING.md +1 -0
  5. data/HISTORY.md +17288 -2
  6. data/Rakefile +6 -2
  7. data/beaker.gemspec +15 -19
  8. data/lib/beaker.rb +2 -5
  9. data/lib/beaker/answers.rb +2 -0
  10. data/lib/beaker/answers/version34.rb +37 -1
  11. data/lib/beaker/cli.rb +4 -0
  12. data/lib/beaker/command.rb +16 -84
  13. data/lib/beaker/command_factory.rb +13 -2
  14. data/lib/beaker/dsl/assertions.rb +25 -2
  15. data/lib/beaker/dsl/ezbake_utils.rb +2 -2
  16. data/lib/beaker/dsl/helpers.rb +66 -12
  17. data/lib/beaker/dsl/install_utils.rb +128 -66
  18. data/lib/beaker/dsl/wrappers.rb +41 -3
  19. data/lib/beaker/host.rb +42 -6
  20. data/lib/beaker/host/mac.rb +62 -0
  21. data/lib/beaker/host/mac/group.rb +96 -0
  22. data/lib/beaker/host/mac/user.rb +93 -0
  23. data/lib/beaker/host/unix/exec.rb +1 -1
  24. data/lib/beaker/host/unix/pkg.rb +11 -11
  25. data/lib/beaker/host/windows.rb +4 -4
  26. data/lib/beaker/host_prebuilt_steps.rb +194 -58
  27. data/lib/beaker/hypervisor.rb +16 -9
  28. data/lib/beaker/hypervisor/aws_sdk.rb +61 -17
  29. data/lib/beaker/hypervisor/docker.rb +14 -2
  30. data/lib/beaker/hypervisor/ec2_helper.rb +15 -3
  31. data/lib/beaker/hypervisor/vagrant.rb +22 -10
  32. data/lib/beaker/hypervisor/vagrant_libvirt.rb +11 -0
  33. data/lib/beaker/hypervisor/vagrant_virtualbox.rb +1 -1
  34. data/lib/beaker/hypervisor/vcloud_pooled.rb +8 -39
  35. data/lib/beaker/logger.rb +15 -9
  36. data/lib/beaker/network_manager.rb +2 -2
  37. data/lib/beaker/options/command_line_parser.rb +1 -1
  38. data/lib/beaker/options/parser.rb +1 -8
  39. data/lib/beaker/options/presets.rb +70 -45
  40. data/lib/beaker/perf.rb +3 -4
  41. data/lib/beaker/platform.rb +2 -1
  42. data/lib/beaker/result.rb +3 -9
  43. data/lib/beaker/ssh_connection.rb +2 -0
  44. data/lib/beaker/test_case.rb +2 -21
  45. data/lib/beaker/test_suite.rb +21 -25
  46. data/lib/beaker/version.rb +1 -1
  47. data/spec/beaker/answers_spec.rb +36 -0
  48. data/spec/beaker/cli_spec.rb +45 -45
  49. data/spec/beaker/command_spec.rb +25 -36
  50. data/spec/beaker/dsl/assertions_spec.rb +20 -27
  51. data/spec/beaker/dsl/ezbake_utils_spec.rb +5 -5
  52. data/spec/beaker/dsl/helpers_spec.rb +293 -208
  53. data/spec/beaker/dsl/install_utils_spec.rb +310 -189
  54. data/spec/beaker/dsl/outcomes_spec.rb +6 -6
  55. data/spec/beaker/dsl/roles_spec.rb +27 -18
  56. data/spec/beaker/dsl/structure_spec.rb +11 -11
  57. data/spec/beaker/dsl/wrappers_spec.rb +35 -11
  58. data/spec/beaker/host/mac/group_spec.rb +124 -0
  59. data/spec/beaker/host/mac/user_spec.rb +134 -0
  60. data/spec/beaker/host/unix/pkg_spec.rb +40 -24
  61. data/spec/beaker/host/windows/group_spec.rb +1 -1
  62. data/spec/beaker/host_prebuilt_steps_spec.rb +194 -68
  63. data/spec/beaker/host_spec.rb +145 -67
  64. data/spec/beaker/hypervisor/aixer_spec.rb +6 -6
  65. data/spec/beaker/hypervisor/aws_sdk_spec.rb +22 -7
  66. data/spec/beaker/hypervisor/docker_spec.rb +71 -50
  67. data/spec/beaker/hypervisor/ec2_helper_spec.rb +25 -4
  68. data/spec/beaker/hypervisor/fusion_spec.rb +2 -2
  69. data/spec/beaker/hypervisor/hypervisor_spec.rb +20 -27
  70. data/spec/beaker/hypervisor/hypervisor_spec.rb.orig +80 -0
  71. data/spec/beaker/hypervisor/solaris_spec.rb +8 -8
  72. data/spec/beaker/hypervisor/vagrant_fusion_spec.rb +6 -8
  73. data/spec/beaker/hypervisor/vagrant_libvirt_spec.rb +34 -0
  74. data/spec/beaker/hypervisor/vagrant_spec.rb +34 -33
  75. data/spec/beaker/hypervisor/vagrant_virtualbox_spec.rb +18 -8
  76. data/spec/beaker/hypervisor/vagrant_workstation_spec.rb +6 -8
  77. data/spec/beaker/hypervisor/vcloud_pooled_spec.rb +8 -8
  78. data/spec/beaker/hypervisor/vcloud_spec.rb +10 -10
  79. data/spec/beaker/hypervisor/vsphere_helper_spec.rb +8 -8
  80. data/spec/beaker/hypervisor/vsphere_spec.rb +1 -1
  81. data/spec/beaker/logger_spec.rb +45 -31
  82. data/spec/beaker/options/command_line_parser_spec.rb +10 -2
  83. data/spec/beaker/options/hosts_file_parser_spec.rb +9 -2
  84. data/spec/beaker/options/options_hash_spec.rb +2 -2
  85. data/spec/beaker/options/parser_spec.rb +2 -2
  86. data/spec/beaker/options/pe_version_scaper_spec.rb +6 -1
  87. data/spec/beaker/options/presets_spec.rb +11 -1
  88. data/spec/beaker/shared/error_handler_spec.rb +5 -5
  89. data/spec/beaker/shared/host_manager_spec.rb +3 -2
  90. data/spec/beaker/shared/repetition_spec.rb +18 -18
  91. data/spec/beaker/ssh_connection_spec.rb +33 -4
  92. data/spec/beaker/test_case_spec.rb +9 -9
  93. data/spec/beaker/test_suite_spec.rb +14 -14
  94. data/spec/helpers.rb +4 -4
  95. data/spec/matchers.rb +4 -4
  96. data/spec/mocks.rb +5 -1
  97. data/spec/spec_helper.rb +2 -8
  98. metadata +114 -80
  99. data/lib/beaker/hypervisor/blimper.rb +0 -108
  100. data/spec/beaker/hypervisor/blimper_spec.rb +0 -42
  101. data/spec/beaker/options/data/LATEST +0 -1
  102. data/spec/beaker/puppet_command_spec.rb +0 -161
  103. data/spec/mock_blimpy.rb +0 -48
data/Rakefile CHANGED
@@ -19,11 +19,15 @@ task :travis do
19
19
  end
20
20
 
21
21
  namespace :test do
22
- desc 'Run specs (with coverage on 1.9), alias `spec` & the default'
22
+ desc 'Run specs and check for deprecation warnings'
23
23
  task :spec do
24
24
  original_dir = Dir.pwd
25
25
  Dir.chdir( File.expand_path(File.dirname(__FILE__)) )
26
- sh 'export COVERAGE=true; bundle exec rspec'
26
+ output = `export COVERAGE=true; bundle exec rspec`
27
+ puts output
28
+ if output =~ /Deprecation Warnings/
29
+ raise "Deprecation Warnings in spec generation, please fix!"
30
+ end
27
31
  Dir.chdir( original_dir )
28
32
  end
29
33
  end
@@ -18,39 +18,35 @@ Gem::Specification.new do |s|
18
18
  s.require_paths = ["lib"]
19
19
 
20
20
  # Testing dependencies
21
- s.add_development_dependency 'minitest', '~> 4.0'
22
- s.add_development_dependency 'rspec', '~> 2.14.0'
23
- s.add_development_dependency 'fakefs', '0.4'
24
- s.add_development_dependency 'rake', '~> 10.1.0'
25
- s.add_development_dependency 'simplecov' unless RUBY_VERSION < '1.9'
26
- s.add_development_dependency 'pry', '~> 0.9.12.6'
21
+ s.add_development_dependency 'rspec', '~> 3.0'
22
+ s.add_development_dependency 'rspec-its'
23
+ s.add_development_dependency 'fakefs', '~> 0.6'
24
+ s.add_development_dependency 'rake', '~> 10.1'
25
+ s.add_development_dependency 'simplecov'
26
+ s.add_development_dependency 'pry', '~> 0.10'
27
27
 
28
28
  # Documentation dependencies
29
29
  s.add_development_dependency 'yard'
30
- s.add_development_dependency 'markdown' unless RUBY_VERSION < '1.9'
30
+ s.add_development_dependency 'markdown'
31
31
  s.add_development_dependency 'thin'
32
32
  s.add_development_dependency 'gitlab-grit'
33
33
 
34
34
  # Run time dependencies
35
+ s.add_runtime_dependency 'minitest', '~> 5.4'
35
36
  s.add_runtime_dependency 'json', '~> 1.8'
36
37
  s.add_runtime_dependency 'hocon', '~> 0.0.4'
37
- s.add_runtime_dependency 'net-ssh', '~> 2.6'
38
- s.add_runtime_dependency 'net-scp', '~> 1.1'
38
+ s.add_runtime_dependency 'net-ssh', '~> 2.9'
39
+ s.add_runtime_dependency 'net-scp', '~> 1.2'
39
40
  s.add_runtime_dependency 'inifile', '~> 2.0'
40
41
 
41
42
  # Optional provisioner specific support
42
- s.add_runtime_dependency 'rbvmomi', '1.8.1'
43
- s.add_runtime_dependency 'blimpy', '~> 0.6'
43
+ s.add_runtime_dependency 'rbvmomi', '~> 1.8'
44
44
  s.add_runtime_dependency 'fission', '~> 0.4'
45
- s.add_runtime_dependency 'google-api-client', '~> 0.7.1'
46
- s.add_runtime_dependency 'aws-sdk', '1.42.0'
47
- s.add_runtime_dependency 'docker-api' unless RUBY_VERSION < '1.9'
48
- s.add_runtime_dependency 'fog', '~> 1.22.1'
45
+ s.add_runtime_dependency 'google-api-client', '~> 0.7'
46
+ s.add_runtime_dependency 'aws-sdk', '~> 1.57'
47
+ s.add_runtime_dependency 'docker-api'
48
+ s.add_runtime_dependency 'fog', '~> 1.25'
49
49
 
50
- # These are transitive dependencies that we include or pin to because...
51
- # Ruby 1.8 compatibility
52
- s.add_runtime_dependency 'nokogiri', '~> 1.5.10'
53
- s.add_runtime_dependency 'mime-types', '~> 1.25' # 2.0 won't install on 1.8
54
50
  # So fog doesn't always complain of unmet AWS dependencies
55
51
  s.add_runtime_dependency 'unf', '~> 0.1'
56
52
  end
@@ -33,11 +33,8 @@ module Beaker
33
33
  # Shared methods and helpers
34
34
  require 'beaker/shared'
35
35
 
36
- # utf-8 support in ruby 1.8
37
- if RUBY_VERSION.to_f < 1.9
38
- require 'jcode'
39
- $KCODE="u"
40
- end
36
+ # MiniTest, for including MiniTest::Assertions
37
+ require 'minitest/test'
41
38
 
42
39
  # Add pry support when available
43
40
  begin
@@ -15,6 +15,8 @@ module Beaker
15
15
  # data.
16
16
  def self.create version, hosts, options
17
17
  case version
18
+ when /\A3\.7/
19
+ return Version34.new(version, hosts, options)
18
20
  when /\A3\.4/
19
21
  return Version34.new(version, hosts, options)
20
22
  when /\A3\.[2-3]/
@@ -6,7 +6,43 @@ module Beaker
6
6
  # @api private
7
7
  class Version34 < Version32
8
8
  def generate_answers
9
- super
9
+ dashboard = only_host_with_role(@hosts, 'dashboard')
10
+ database = only_host_with_role(@hosts, 'database')
11
+
12
+ the_answers = super
13
+
14
+ classifier_database_user = answer_for(@options, :q_classifier_database_user, 'DFGhjlkj')
15
+ classifier_database_name = answer_for(@options, :q_database_name, 'pe-classifier')
16
+ classifier_database_password = "'#{@options[:answers][:q_classifier_database_password]}'"
17
+ activity_database_user = answer_for(@options, :q_activity_database_user, 'adsfglkj')
18
+ activity_database_name = answer_for(@options, :q_activity_database_name, 'pe-activity')
19
+ activity_database_password = "'#{@options[:answers][:q_activity_database_password]}'"
20
+ rbac_database_user = answer_for(@options, :q_rbac_database_user, 'RbhNBklm')
21
+ rbac_database_name = answer_for(@options, :q_rbac_database_name, 'pe-rbac')
22
+ rbac_database_password = "'#{@options[:answers][:q_rbac_database_password]}'"
23
+
24
+ console_services_hash = {
25
+ :q_classifier_database_user => classifier_database_user,
26
+ :q_classifier_database_name => classifier_database_name,
27
+ :q_classifier_database_password => classifier_database_password,
28
+ :q_activity_database_user => activity_database_user,
29
+ :q_activity_database_name => activity_database_name,
30
+ :q_activity_database_password => activity_database_password,
31
+ :q_rbac_database_user => rbac_database_user,
32
+ :q_rbac_database_name => rbac_database_name,
33
+ :q_rbac_database_password => rbac_database_password,
34
+ }
35
+
36
+ # If we're installing or upgrading from a non-RBAC version, set the 'admin' password
37
+ if @options[:type] == :upgrade && @options[:HOSTS][dashboard.name][:pe_ver] < "3.4.0"
38
+ dashboard_password = "'#{options[:answers][:q_puppet_enterpriseconsole_auth_password]}'"
39
+ the_answers[dashboard.name][:q_puppet_enterpriseconsole_auth_password] = dashboard_password
40
+ end
41
+
42
+ the_answers[dashboard.name].merge!(console_services_hash)
43
+ the_answers[database.name].merge!(console_services_hash)
44
+
45
+ return the_answers
10
46
  end
11
47
  end
12
48
  end
@@ -43,6 +43,9 @@ module Beaker
43
43
  @options[:helper].each do |helper|
44
44
  require File.expand_path(helper)
45
45
  end
46
+
47
+ @options[:log_dated_dir] = Beaker::Logger.generate_dated_log_folder(@options[:log_dir], @timestamp)
48
+ @options[:xml_dated_dir] = Beaker::Logger.generate_dated_log_folder(@options[:xml_dir], @timestamp)
46
49
  end
47
50
 
48
51
  #Provision, validate and configure all hosts as defined in the hosts file
@@ -51,6 +54,7 @@ module Beaker
51
54
  @hosts = []
52
55
  @network_manager = Beaker::NetworkManager.new(@options, @logger)
53
56
  @hosts = @network_manager.provision
57
+ @network_manager.proxy_package_manager
54
58
  @network_manager.validate
55
59
  @network_manager.configure
56
60
  rescue => e
@@ -5,24 +5,6 @@ module Beaker
5
5
  # @api public
6
6
  class Command
7
7
 
8
- DEFAULT_GIT_RUBYLIB = {
9
- :default => [],
10
- :host => %w(hieralibdir hierapuppetlibdir
11
- pluginlibpath puppetlibdir
12
- facterlibdir),
13
- :opts => { :additive => true,
14
- :separator => {:host => 'pathseparator' }
15
- }
16
- }
17
-
18
- DEFAULT_GIT_PATH = {
19
- :default => [],
20
- :host => %w(puppetbindir facterbindir hierabindir),
21
- :opts => { :additive => true, :separator => ':' }
22
- }
23
-
24
- DEFAULT_GIT_ENV = { :PATH => DEFAULT_GIT_PATH, :RUBYLIB => DEFAULT_GIT_RUBYLIB }
25
-
26
8
  # A string representing the (possibly) incomplete command
27
9
  attr_accessor :command
28
10
 
@@ -67,6 +49,7 @@ module Beaker
67
49
  @options = options
68
50
  @args = args
69
51
  @environment = {}
52
+ @cmdexe = @options.delete(:cmdexe) || false
70
53
 
71
54
  # this is deprecated and will not allow you to use a command line
72
55
  # option of `--environment`, please use ENV instead.
@@ -87,8 +70,10 @@ module Beaker
87
70
  def cmd_line host, cmd = @command, env = @environment
88
71
  env_string = env.nil? ? '' : environment_string_for( host, env )
89
72
 
73
+ cygwin = ((host['platform'] =~ /windows/) and @cmdexe) ? 'cmd.exe /c' : nil
74
+
90
75
  # This will cause things like `puppet -t -v agent` which is maybe bad.
91
- "#{env_string} #{cmd} #{options_string} #{args_string}"
76
+ [env_string, cygwin, cmd, options_string, args_string].compact.reject(&:empty?).join(' ')
92
77
  end
93
78
 
94
79
  # @param [Hash] opts These are the options that the command takes
@@ -133,7 +118,7 @@ module Beaker
133
118
  args.flatten.compact.join(' ')
134
119
  end
135
120
 
136
- # Determine the appropriate env commands for the given host.
121
+ # Construct the environment string for this command
137
122
  #
138
123
  # @param [Host] host A Host object
139
124
  # @param [Hash{String=>String}] env An optional Hash containing
@@ -152,75 +137,22 @@ module Beaker
152
137
  # given a generic Command.
153
138
  def environment_string_for host, env
154
139
  return '' if env.empty?
155
-
156
- env_array = parse_env_hash_for( host, env ).compact
157
-
158
- # cygwin-ism
159
- cmd = host['platform'] =~ /windows/ ? 'cmd.exe /c' : nil
160
- env_array << cmd if cmd
161
-
162
- environment_string = env_array.join(' ')
163
-
164
- "env #{environment_string}"
165
- end
166
-
167
- # @!visibility private
168
- def parse_env_hash_for( host, env = @environment )
169
- # I needlessly love inject
170
- env.inject([]) do |array_of_parsed_vars, key_and_value|
171
- variable, val_in_unknown_format = *key_and_value
172
- if val_in_unknown_format.is_a?(Hash)
173
- value = val_in_unknown_format
174
- elsif val_in_unknown_format.is_a?(Array)
175
- value = { :default => val_in_unknown_format }
140
+ env_array = []
141
+ env.each_key do |key|
142
+ val = env[key]
143
+ if val.is_a?(Array)
144
+ val = val.join(':')
176
145
  else
177
- value = { :default => [ val_in_unknown_format.to_s ] }
146
+ val = val.to_s
178
147
  end
179
-
180
- var_settings = ensure_correct_structure_for( value )
181
- # any default array of variable values ( like [ '/bin', '/usr/bin' ] for PATH )
182
- default_values = var_settings[:default]
183
-
184
- # host specific values, ie :host => [ 'puppetlibdir' ] is evaluated to
185
- # an array with whatever host['puppetlibdir'] is
186
- host_values = var_settings[:host].map { |attr| host[attr] }
187
-
188
- # the two arrays are combined with host specific values first
189
- var_array = ( host_values + default_values ).compact
190
-
191
- # This will add the name of the variable, so :PATH => { ... }
192
- # gets '${PATH}' appended to it if the :additive opt is passed
193
- var_array << "${#{variable}}" if var_settings[:opts][:additive]
194
-
195
- # This is stupid, but because we're using cygwin we sometimes need to use
196
- # ':' and sometimes ';' on windows as a separator
197
- attr_string = join_env_vars_for( var_array, host, var_settings[:opts][:separator] )
198
- var_string = attr_string.empty? ? nil : %Q[#{variable}="#{attr_string}"]
199
-
200
- # Now we append this to our accumulator array ie [ 'RUBYLIB=....', 'PATH=....' ]
201
- array_of_parsed_vars << var_string
202
-
203
- array_of_parsed_vars
148
+ env_array << "#{key.to_s.upcase}=\"#{val}\""
204
149
  end
205
- end
206
150
 
207
- # @!visibility private
208
- def ensure_correct_structure_for( settings )
209
- structure = { :default => [],
210
- :host => [],
211
- :opts => {}
212
- }.merge( settings )
213
- structure[:opts][:separator] ||= ':'
214
- structure
215
- end
151
+ environment_string = env_array.join(' ')
216
152
 
217
- # @!visibility private
218
- def join_env_vars_for( array_of_variables, host, separator = ':' )
219
- if separator.is_a?( Hash )
220
- separator = host[separator[:host]]
221
- end
222
- array_of_variables.join( separator )
153
+ "env #{environment_string}"
223
154
  end
155
+
224
156
  end
225
157
 
226
158
  class PuppetCommand < Command
@@ -228,7 +160,7 @@ module Beaker
228
160
  command = "puppet #{args.shift}"
229
161
  opts = args.last.is_a?(Hash) ? args.pop : Hash.new
230
162
  opts['ENV'] ||= Hash.new
231
- opts['ENV'] = opts['ENV'].merge( DEFAULT_GIT_ENV )
163
+ opts[:cmdexe] = true
232
164
  super( command, args, opts )
233
165
  end
234
166
  end
@@ -1,8 +1,19 @@
1
- require 'test/unit/assertions'
1
+ require 'minitest/test'
2
2
 
3
3
  module Beaker
4
4
  module CommandFactory
5
- include Test::Unit::Assertions
5
+ include Minitest::Assertions
6
+ #Why do we need this accessor?
7
+ # https://github.com/seattlerb/minitest/blob/master/lib/minitest/assertions.rb#L8-L12
8
+ # Protocol: Nearly everything here boils up to +assert+, which
9
+ # expects to be able to increment an instance accessor named
10
+ # +assertions+. This is not provided by Assertions and must be
11
+ # provided by the thing including Assertions. See Minitest::Runnable
12
+ # for an example.
13
+ attr_accessor :assertions
14
+ def assertions
15
+ @assertions || 0
16
+ end
6
17
 
7
18
  def execute(command, options={}, &block)
8
19
  result = self.exec(Command.new(command), options)
@@ -1,4 +1,4 @@
1
- require 'test/unit/assertions'
1
+ require 'minitest/test'
2
2
 
3
3
  module Beaker
4
4
  module DSL
@@ -15,7 +15,19 @@ module Beaker
15
15
  # or direct object for asserting against into your assertion.
16
16
  #
17
17
  module Assertions
18
- include Test::Unit::Assertions
18
+ include Minitest::Assertions
19
+
20
+ #Why do we need this accessor?
21
+ # https://github.com/seattlerb/minitest/blob/master/lib/minitest/assertions.rb#L8-L12
22
+ # Protocol: Nearly everything here boils up to +assert+, which
23
+ # expects to be able to increment an instance accessor named
24
+ # +assertions+. This is not provided by Assertions and must be
25
+ # provided by the thing including Assertions. See Minitest::Runnable
26
+ # for an example.
27
+ attr_accessor :assertions
28
+ def assertions
29
+ @assertions || 0
30
+ end
19
31
 
20
32
  # Make assertions about the content of console output.
21
33
  #
@@ -82,6 +94,17 @@ module Beaker
82
94
  assert_equal our_err, (result.nil? ? '' : result.stderr),
83
95
  'The contents of STDERR did not match expectations'
84
96
  end
97
+
98
+ # Assert that the provided string does not match the provided regular expression, can pass optional message
99
+ # @deprecated This is placed her for backwards compatability for tests that used Test::Unit::Assertions,
100
+ # http://apidock.com/ruby/Test/Unit/Assertions/assert_no_match
101
+ #
102
+ def assert_no_match(regexp, string, msg=nil)
103
+ assert_instance_of(Regexp, regexp, "The first argument to assert_no_match should be a Regexp.")
104
+ msg = message(msg) { "<#{mu_pp(regexp)}> expected to not match\n<#{mu_pp(string)}>" }
105
+ assert(regexp !~ string, msg)
106
+ end
107
+
85
108
  end
86
109
  end
87
110
  end
@@ -106,7 +106,7 @@ module Beaker
106
106
  install_package host, package_name, package_version
107
107
  end
108
108
 
109
- when /^(debian|ubuntu)$/
109
+ when /^(debian|ubuntu|cumulus)$/
110
110
  dependency_list = ezbake[:debian][:additional_dependencies]
111
111
  dependency_list.each do |dependency|
112
112
  package_name, _, package_version = dependency.split
@@ -192,7 +192,7 @@ module Beaker
192
192
  when /^(fedora|el|centos)$/
193
193
  env += "defaultsdir=/etc/sysconfig "
194
194
  on host, cd_to_package_dir + env + "make -e install-rpm-sysv-init"
195
- when /^(debian|ubuntu)$/
195
+ when /^(debian|ubuntu|cumulus)$/
196
196
  env += "defaultsdir=/etc/default "
197
197
  on host, cd_to_package_dir + env + "make -e install-deb-sysv-init"
198
198
  else
@@ -187,6 +187,8 @@ module Beaker
187
187
  # @note If using {Beaker::Host} for the hosts *scp* is not
188
188
  # required on the system as it uses Ruby's net/scp library. The
189
189
  # net-scp gem however is required (and specified in the gemspec.
190
+ # When using SCP with Windows it will now auto expand path when
191
+ # using `cygpath instead of failing or requiring full path
190
192
  #
191
193
  # @param [Host, #do_scp_to] host One or more hosts (or some object
192
194
  # that responds like
@@ -198,6 +200,10 @@ module Beaker
198
200
  # @return [Result] Returns the result of the SCP operation
199
201
  def scp_to host, from_path, to_path, opts = {}
200
202
  block_on host do | host |
203
+ if host['platform'] =~ /windows/ && to_path.match('`cygpath')
204
+ result = on host, "echo #{to_path}"
205
+ to_path = result.raw_output.chomp
206
+ end
201
207
  @result = host.do_scp_to(from_path, to_path, opts)
202
208
  @result.log logger
203
209
  @result
@@ -256,7 +262,7 @@ module Beaker
256
262
  # @return [String] Returns the name of the newly-created file.
257
263
  def create_tmpdir_for_user(host, name='/tmp/beaker', user=nil)
258
264
  if not user
259
- result = on(host, "puppet master --configprint user")
265
+ result = on host, puppet("master --configprint user")
260
266
  if not result.exit_code == 0
261
267
  raise "`puppet master --configprint` failed, check that puppet is installed on #{host} or explicitly pass in a user name."
262
268
  end
@@ -674,7 +680,7 @@ module Beaker
674
680
  def dump_puppet_log(host)
675
681
  syslogfile = case host['platform']
676
682
  when /fedora|centos|el|redhat|scientific/ then '/var/log/messages'
677
- when /ubuntu|debian/ then '/var/log/syslog'
683
+ when /ubuntu|debian|cumulus/ then '/var/log/syslog'
678
684
  else return
679
685
  end
680
686
 
@@ -861,18 +867,25 @@ module Beaker
861
867
  # path separator character. (The POSIX path separator
862
868
  # is ‘:’, and the Windows path separator is ‘;’.)
863
869
  #
870
+ # @option opts [String] :debug (false) If this option exists,
871
+ # the "--debug" command line parameter
872
+ # will be passed to the 'puppet apply' command.
873
+ #
864
874
  # @param [Block] block This method will yield to a block of code passed
865
875
  # by the caller; this can be used for additional
866
876
  # validation, etc.
867
877
  #
868
878
  def apply_manifest_on(host, manifest, opts = {}, &block)
869
879
  block_on host do | host |
870
-
871
880
  on_options = {}
872
881
  on_options[:acceptable_exit_codes] = Array(opts[:acceptable_exit_codes])
873
882
 
874
883
  puppet_apply_opts = {}
875
- puppet_apply_opts[:verbose] = nil
884
+ if opts[:debug]
885
+ puppet_apply_opts[:debug] = nil
886
+ else
887
+ puppet_apply_opts[:verbose] = nil
888
+ end
876
889
  puppet_apply_opts[:parseonly] = nil if opts[:parseonly]
877
890
  puppet_apply_opts[:trace] = nil if opts[:trace]
878
891
  puppet_apply_opts[:parser] = 'future' if opts[:future_parser]
@@ -1115,22 +1128,62 @@ module Beaker
1115
1128
  host, "https://#{host.node_name}:8081", [35, 60])
1116
1129
  end
1117
1130
 
1131
+ def sleep_until_puppetserver_started(host)
1132
+ curl_with_retries("start puppetserver (ssl)",
1133
+ host, "https://#{host.node_name}:8140", [35, 60])
1134
+ end
1135
+
1136
+ def sleep_until_nc_started(host)
1137
+ curl_with_retries("start nodeclassifier (ssl)",
1138
+ host, "https://#{host.node_name}:4433", [35, 60])
1139
+ end
1140
+
1118
1141
  def curl_with_retries(desc, host, url, desired_exit_codes, max_retries = 60, retry_interval = 1)
1119
- retry_command(desc, host, "curl -m 1 #{url}", desired_exit_codes, max_retries, retry_interval)
1142
+ opts = {
1143
+ :desired_exit_codes => desired_exit_codes,
1144
+ :max_retries => max_retries,
1145
+ :retry_interval => retry_interval
1146
+ }
1147
+ retry_on(host, "curl -m 1 #{url}", opts)
1120
1148
  end
1121
1149
 
1122
- def retry_command(desc, host, command, desired_exit_codes = 0,
1123
- max_retries = 60, retry_interval = 1, verbose = false)
1150
+ # This command will execute repeatedly until success or it runs out with an error
1151
+ #
1152
+ # @param [Host, Array<Host>, String, Symbol] host One or more hosts to act upon,
1153
+ # or a role (String or Symbol) that identifies one or more hosts.
1154
+ # @param [String, Command] command The command to execute on *host*.
1155
+ # @param [Hash{Symbol=>String}] opts Options to alter execution.
1156
+ # @param [Proc] block Additional actions or assertions.
1157
+ #
1158
+ # @option opts [Array<Fixnum>, Fixnum] :desired_exit_codes (0) An array
1159
+ # or integer exit code(s) that should be considered
1160
+ # acceptable. An error will be thrown if the exit code never
1161
+ # matches one of the values in this list.
1162
+ # @option opts [Fixnum] :max_retries (60) number of times the
1163
+ # command will be tried before failing
1164
+ # @option opts [Float] :retry_interval (1) number of seconds
1165
+ # that we'll wait between tries
1166
+ # @option opts [Boolean] :verbose (false)
1167
+ def retry_on(host, command, opts = {}, &block)
1168
+ option_exit_codes = opts[:desired_exit_codes]
1169
+ option_max_retries = opts[:max_retries].to_i
1170
+ option_retry_interval = opts[:retry_interval].to_f
1171
+ desired_exit_codes = option_exit_codes ? [option_exit_codes].flatten : [0]
1172
+ desired_exit_codes = [0] if desired_exit_codes.empty?
1173
+ max_retries = option_max_retries == 0 ? 60 : option_max_retries # nil & "" both return 0
1174
+ retry_interval = option_retry_interval == 0 ? 1 : option_retry_interval
1175
+ verbose = true.to_s == opts[:verbose]
1176
+
1124
1177
  log_prefix = host.log_prefix
1125
1178
  logger.debug "\n#{log_prefix} #{Time.new.strftime('%H:%M:%S')}$ #{command}"
1126
1179
  logger.debug " Trying command #{max_retries} times."
1127
1180
  logger.debug ".", add_newline=false
1128
- desired_exit_codes = [desired_exit_codes].flatten
1129
- result = on host, command, {:acceptable_exit_codes => (0...127), :silent => !verbose}
1181
+
1182
+ result = on host, command, {:acceptable_exit_codes => (0...127), :silent => !verbose}, &block
1130
1183
  num_retries = 0
1131
1184
  until desired_exit_codes.include?(result.exit_code)
1132
1185
  sleep retry_interval
1133
- result = on host, command, {:acceptable_exit_codes => (0...127), :silent => !verbose}
1186
+ result = on host, command, {:acceptable_exit_codes => (0...127), :silent => !verbose}, &block
1134
1187
  num_retries += 1
1135
1188
  logger.debug ".", add_newline=false
1136
1189
  if (num_retries > max_retries)
@@ -1139,6 +1192,7 @@ module Beaker
1139
1192
  end
1140
1193
  end
1141
1194
  logger.debug "\n#{log_prefix} #{Time.new.strftime('%H:%M:%S')}$ #{command} ostensibly successful."
1195
+ result
1142
1196
  end
1143
1197
 
1144
1198
  #Is semver-ish version a less than semver-ish version b
@@ -1219,7 +1273,7 @@ module Beaker
1219
1273
  #wait for a given host to appear in the dashboard
1220
1274
  def wait_for_host_in_dashboard(host)
1221
1275
  hostname = host.node_name
1222
- retry_command("Wait for #{hostname} to be in the console", dashboard, "! curl --tlsv1 -k -I https://#{dashboard}/nodes/#{hostname} | grep '404 Not Found'")
1276
+ retry_on(dashboard, "! curl --tlsv1 -k -I https://#{dashboard}/nodes/#{hostname} | grep '404 Not Found'")
1223
1277
  end
1224
1278
 
1225
1279
  # Ensure the host has requested a cert, then sign it
@@ -1245,7 +1299,7 @@ module Beaker
1245
1299
  (0..10).each do |i|
1246
1300
  fail_test("Failed to sign cert for #{hostname}") if i == 10
1247
1301
 
1248
- on master, puppet("cert --sign --all"), :acceptable_exit_codes => [0,24]
1302
+ on master, puppet("cert --sign --all --allow-dns-alt-names"), :acceptable_exit_codes => [0,24]
1249
1303
  break if on(master, puppet("cert --list --all")).stdout =~ /\+ "?#{hostname}"?/
1250
1304
  sleep next_sleep
1251
1305
  (last_sleep, next_sleep) = next_sleep, last_sleep+next_sleep