beaker 2.33.0 → 2.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +8 -8
  2. data/HISTORY.md +173 -2
  3. data/README.md +5 -0
  4. data/acceptance/tests/base/dsl/helpers/host_helpers/check_for_package_test.rb +0 -5
  5. data/acceptance/tests/base/dsl/helpers/host_helpers/install_package_test.rb +0 -4
  6. data/acceptance/tests/base/dsl/helpers/host_helpers/upgrade_package_test.rb +0 -4
  7. data/docs/Beaker-Libraries.md +8 -0
  8. data/docs/Beaker-Recipes.md +13 -0
  9. data/docs/Docker-Support.md +19 -0
  10. data/docs/README.md +2 -0
  11. data/docs/hosts/cisco.md +60 -0
  12. data/docs/hosts/eos.md +2 -2
  13. data/lib/beaker/command.rb +4 -45
  14. data/lib/beaker/dsl/helpers/host_helpers.rb +14 -9
  15. data/lib/beaker/dsl/install_utils/foss_utils.rb +32 -32
  16. data/lib/beaker/host.rb +7 -3
  17. data/lib/beaker/host/cisco.rb +124 -0
  18. data/lib/beaker/host/pswindows/exec.rb +11 -0
  19. data/lib/beaker/host/pswindows/user.rb +1 -1
  20. data/lib/beaker/host/unix.rb +9 -2
  21. data/lib/beaker/host/unix/exec.rb +43 -0
  22. data/lib/beaker/host/unix/file.rb +19 -4
  23. data/lib/beaker/host/windows/exec.rb +13 -0
  24. data/lib/beaker/host/windows/user.rb +1 -1
  25. data/lib/beaker/hypervisor/docker.rb +9 -0
  26. data/lib/beaker/network_manager.rb +3 -1
  27. data/lib/beaker/test_case.rb +2 -0
  28. data/lib/beaker/version.rb +1 -1
  29. data/spec/beaker/command_spec.rb +17 -27
  30. data/spec/beaker/dsl/helpers/host_helpers_spec.rb +13 -1
  31. data/spec/beaker/dsl/install_utils/foss_utils_spec.rb +24 -15
  32. data/spec/beaker/dsl/install_utils/module_utils_spec.rb +2 -1
  33. data/spec/beaker/host/cisco_spec.rb +182 -0
  34. data/spec/beaker/host/pswindows/exec_spec.rb +54 -0
  35. data/spec/beaker/host/pswindows/user_spec.rb +70 -0
  36. data/spec/beaker/host/unix/exec_spec.rb +30 -0
  37. data/spec/beaker/host/unix/file_spec.rb +11 -4
  38. data/spec/beaker/host/unix/pkg_spec.rb +0 -1
  39. data/spec/beaker/host/unix_spec.rb +9 -0
  40. data/spec/beaker/host/windows/exec_spec.rb +17 -24
  41. data/spec/beaker/host/windows/user_spec.rb +70 -0
  42. data/spec/beaker/host_spec.rb +21 -0
  43. data/spec/beaker/hypervisor/docker_spec.rb +35 -0
  44. metadata +10 -2
@@ -61,16 +61,21 @@ module Beaker
61
61
  # @raise [FailTest] Raises an exception if *command* obviously fails.
62
62
  def on(host, command, opts = {}, &block)
63
63
  block_on host do | host |
64
- cur_command = command
65
- if command.is_a? Command
66
- cur_command = command.cmd_line(host)
67
- end
68
- cmd_opts = {}
69
- #add any additional environment variables to the command
70
- if opts[:environment]
71
- cmd_opts['ENV'] = opts[:environment]
64
+ if command.is_a? String
65
+ cmd_opts = {}
66
+ #add any additional environment variables to the command
67
+ if opts[:environment]
68
+ cmd_opts['ENV'] = opts[:environment]
69
+ end
70
+ command_object = Command.new(command.to_s, [], cmd_opts)
71
+ elsif command.is_a? Command
72
+ command_object = command
73
+ else
74
+ msg = "DSL method `on` can only be called with a String or Beaker::Command"
75
+ msg << " object as the command parameter, not #{command.class}."
76
+ raise ArgumentError, msg
72
77
  end
73
- @result = host.exec(Command.new(cur_command.to_s, [], cmd_opts), opts)
78
+ @result = host.exec(command_object, opts)
74
79
 
75
80
  # Also, let additional checking be performed by the caller.
76
81
  if block_given?
@@ -333,7 +333,7 @@ module Beaker
333
333
  add_role(host, 'aio') #we are installing agent, so we want aio role
334
334
  package_name = nil
335
335
  case host['platform']
336
- when /el-|fedora|sles|centos/
336
+ when /el-|fedora|sles|centos|cisco-/
337
337
  package_name = 'puppet-agent'
338
338
  package_name << "-#{opts[:puppet_agent_version]}" if opts[:puppet_agent_version]
339
339
  when /debian|ubuntu|cumulus/
@@ -393,30 +393,18 @@ module Beaker
393
393
  #
394
394
  # @return nil
395
395
  def configure_puppet_on(hosts, opts = {})
396
- block_on hosts do |host|
397
- if host['platform'] =~ /windows/
398
- puppet_conf = host.puppet['config']
399
- conf_data = ''
400
- opts.each do |section,options|
401
- conf_data << "[#{section}]`n"
402
- options.each do |option,value|
403
- conf_data << "#{option}=#{value}`n"
404
- end
405
- conf_data << "`n"
406
- end
407
- on host, powershell("\$text = \\\"#{conf_data}\\\"; Set-Content -path '#{puppet_conf}' -value \$text")
408
- else
409
- puppet_conf = host.puppet['config']
410
- conf_data = ''
411
- opts.each do |section,options|
412
- conf_data << "[#{section}]\n"
413
- options.each do |option,value|
414
- conf_data << "#{option}=#{value}\n"
415
- end
416
- conf_data << "\n"
417
- end
418
- on host, "echo \"#{conf_data}\" > #{puppet_conf}"
396
+ puppet_conf_text = ''
397
+ opts.each do |section,options|
398
+ puppet_conf_text << "[#{section}]\n"
399
+ options.each do |option,value|
400
+ puppet_conf_text << "#{option}=#{value}\n"
419
401
  end
402
+ puppet_conf_text << "\n"
403
+ end
404
+ logger.debug( "setting config '#{puppet_conf_text}' on hosts #{hosts}" )
405
+ block_on hosts do |host|
406
+ puppet_conf_path = host.puppet['config']
407
+ create_remote_file(host, puppet_conf_path, puppet_conf_text)
420
408
  end
421
409
  end
422
410
 
@@ -854,13 +842,19 @@ module Beaker
854
842
  opts = FOSS_DEFAULT_DOWNLOAD_URLS.merge(opts)
855
843
 
856
844
  case variant
857
- when /^(fedora|el|centos|sles)$/
858
- variant = (($1 == 'centos') ? 'el' : $1)
845
+ when /^(fedora|el|centos|sles|cisco)$/
846
+ variant_url_value = (($1 == 'centos') ? 'el' : $1)
847
+ variant_url_value = 'cisco-wrlinux' if variant == 'cisco'
859
848
  remote = "%s/puppetlabs-release%s-%s-%s.noarch.rpm" %
860
- [opts[:release_yum_repo_url], repo_name, variant, version]
849
+ [opts[:release_yum_repo_url], repo_name, variant_url_value, version]
861
850
 
862
- host.install_package_with_rpm(remote, '--replacepkgs',
863
- {:package_proxy => opts[:package_proxy]})
851
+ if variant == 'cisco'
852
+ # cisco requires using yum to install the repo
853
+ host.install_package( remote )
854
+ else
855
+ host.install_package_with_rpm( remote, '--replacepkgs',
856
+ { :package_proxy => opts[:package_proxy] } )
857
+ end
864
858
 
865
859
  when /^(debian|ubuntu|cumulus)$/
866
860
  deb = "puppetlabs-release%s-%s.deb" % [repo_name, codename]
@@ -895,7 +889,13 @@ module Beaker
895
889
  repo = fetch_http_file( repo_config_folder_url,
896
890
  repo_filename,
897
891
  copy_dir )
898
- scp_to( host, repo, host.package_config_dir )
892
+
893
+ if host[:platform] =~ /cisco-5/
894
+ to_path = "#{host.package_config_dir}/#{File.basename(repo)}"
895
+ else
896
+ to_path = host.package_config_dir
897
+ end
898
+ scp_to( host, repo, to_path )
899
899
 
900
900
  on( host, 'apt-get update' ) if host['platform'] =~ /ubuntu-|debian-|cumulus-/
901
901
  nil
@@ -932,7 +932,7 @@ module Beaker
932
932
  repo_configs_dir = nil,
933
933
  opts = options )
934
934
  variant, version, arch, codename = host['platform'].to_array
935
- if variant !~ /^(fedora|el|centos|debian|ubuntu|cumulus)$/
935
+ if variant !~ /^(fedora|el|centos|debian|ubuntu|cumulus|cisco)$/
936
936
  raise "No repository installation step for #{variant} yet..."
937
937
  end
938
938
  repo_configs_dir ||= 'tmp/repo_configs'
@@ -1029,7 +1029,7 @@ module Beaker
1029
1029
  onhost_copy_base = opts[:copy_dir_external]
1030
1030
 
1031
1031
  case variant
1032
- when /^(fedora|el|centos|debian|ubuntu|cumulus)$/
1032
+ when /^(fedora|el|centos|debian|ubuntu|cumulus|cisco)$/
1033
1033
  sha = opts[:puppet_agent_sha] || opts[:puppet_agent_version]
1034
1034
  opts[:dev_builds_repos] ||= [ opts[:puppet_collection] ]
1035
1035
  install_puppetlabs_dev_repo( host, 'puppet-agent', sha, nil, opts )
@@ -57,6 +57,8 @@ module Beaker
57
57
  FreeBSD::Host.new name, host_hash, options
58
58
  when /eos/
59
59
  Eos::Host.new name, host_hash, options
60
+ when /cisco/
61
+ Cisco::Host.new name, host_hash, options
60
62
  else
61
63
  Unix::Host.new name, host_hash, options
62
64
  end
@@ -331,7 +333,7 @@ module Beaker
331
333
  # to that source dir.
332
334
  #
333
335
  # @param source [String] The path to the file/dir to upload
334
- # @param target [String] The destination path on the host
336
+ # @param target_path [String] The destination path on the host
335
337
  # @param options [Hash{Symbol=>String}] Options to alter execution
336
338
  # @option options [Array<String>] :ignore An array of file/dir paths that will not be copied to the host
337
339
  # @example
@@ -340,8 +342,8 @@ module Beaker
340
342
  #
341
343
  # do_scp_to('source/file.rb', 'target', { :ignore => 'file.rb' }
342
344
  # -> will result in not files copyed to the host, all are ignored
343
- def do_scp_to source, target, options
344
- target = self.scp_path(target)
345
+ def do_scp_to source, target_path, options
346
+ target = self.scp_path( target_path )
345
347
  @logger.notify "localhost $ scp #{source} #{@name}:#{target} {:ignore => #{options[:ignore]}}"
346
348
 
347
349
  result = Result.new(@name, [source, target])
@@ -409,6 +411,7 @@ module Beaker
409
411
  end
410
412
  end
411
413
 
414
+ self.scp_post_operations( target, target_path )
412
415
  return result
413
416
  end
414
417
 
@@ -510,6 +513,7 @@ module Beaker
510
513
  'windows',
511
514
  'pswindows',
512
515
  'eos',
516
+ 'cisco',
513
517
  ].each do |lib|
514
518
  require "beaker/host/#{lib}"
515
519
  end
@@ -0,0 +1,124 @@
1
+ [ 'host', 'command_factory' ].each do |lib|
2
+ require "beaker/#{lib}"
3
+ end
4
+
5
+ module Cisco
6
+ class Host < Unix::Host
7
+
8
+ # Tells you whether a host platform supports beaker's
9
+ # {Beaker::HostPrebuiltSteps#set_env} method
10
+ #
11
+ # @return [String,nil] Reason message if set_env should be skipped,
12
+ # nil if it should run.
13
+ def skip_set_env?
14
+ 'Cisco does not allow SSH control through the BASH shell'
15
+ end
16
+
17
+ # Handles host operations needed after an SCP takes place
18
+ #
19
+ # @param [String] scp_file_actual File path to actual SCP'd file on host
20
+ # @param [String] scp_file_target File path to target SCP location on host
21
+ #
22
+ # @return nil
23
+ def scp_post_operations(scp_file_actual, scp_file_target)
24
+ if self[:platform] =~ /cisco-5/
25
+ execute( "mv #{scp_file_actual} #{scp_file_target}" )
26
+ end
27
+ nil
28
+ end
29
+
30
+ # Handles any changes needed in a path for SCP
31
+ #
32
+ # @param [String] path File path to SCP to
33
+ #
34
+ # @return [String] path, changed if needed due to host
35
+ # constraints
36
+ def scp_path(path)
37
+ if self[:platform] =~ /cisco-5/
38
+ @home_dir ||= execute( 'pwd' )
39
+ answer = "#{@home_dir}/#{File.basename( path )}"
40
+ answer << '/' if path =~ /\/$/
41
+ return answer
42
+ end
43
+ path
44
+ end
45
+
46
+ # Gets the repo type for the given platform
47
+ #
48
+ # @raise [ArgumentError] For an unknown platform
49
+ #
50
+ # @return [String] Type of repo (rpm|deb)
51
+ def repo_type
52
+ 'rpm'
53
+ end
54
+
55
+ # Gets the config dir location for package information
56
+ #
57
+ # @raise [ArgumentError] For an unknown platform
58
+ #
59
+ # @return [String] Path to package config dir
60
+ def package_config_dir
61
+ '/etc/yum/repos.d/'
62
+ end
63
+
64
+ # Gets the specific prepend commands as needed for this host
65
+ #
66
+ # @param [String] command Command to be executed
67
+ # @param [String] user_pc List of user-specified commands to prepend
68
+ # @param [Hash] opts optional parameters
69
+ #
70
+ # @return [String] Command string as needed for this host
71
+ def prepend_commands(command = '', user_pc = '', opts = {})
72
+ return user_pc unless command.index('vsh').nil?
73
+
74
+ prepend_cmds = 'source /etc/profile;'
75
+ if self[:platform] =~ /cisco-5/
76
+ prepend_cmds << ' sudo ip netns exec '
77
+ prepend_cmds << ( self[:vrf] ? self[:vrf] : '' )
78
+ end
79
+ return prepend_cmds
80
+ end
81
+
82
+ # Construct the environment string for this command
83
+ #
84
+ # @param [Hash{String=>String}] env An optional Hash containing
85
+ # key-value pairs to be treated
86
+ # as environment variables that
87
+ # should be set for the duration
88
+ # of the puppet command.
89
+ #
90
+ # @return [String] Returns a string containing command line arguments that
91
+ # will ensure the environment is correctly set for the
92
+ # given host.
93
+ def environment_string env
94
+ return '' if env.empty?
95
+ env_array = self.environment_variable_string_pair_array( env )
96
+ environment_string = env_array.join(' ')
97
+
98
+ command = self[:platform] =~ /cisco-5/ ? 'export' : 'env'
99
+ "#{command} #{environment_string};"
100
+ end
101
+
102
+ # Validates that the host was setup correctly
103
+ #
104
+ # @return nil
105
+ # @raise [ArgumentError] If the host is setup incorrectly,
106
+ # this will be raised with the appropriate message
107
+ def validate_setup
108
+ msg = nil
109
+ msg = 'Cisco hosts must be provided with a :vrf value.' unless self[:vrf]
110
+
111
+ if !msg && self[:platform] =~ /cisco-5/ && self[:user] == 'root'
112
+ msg = 'Cisco-5 hosts must be provided with a :user value, as they can not SSH in as root.'
113
+ end
114
+
115
+ if msg
116
+ msg << <<-EOF
117
+ Check https://github.com/puppetlabs/beaker/blob/master/docs/hosts/cisco.md for more info.'
118
+ EOF
119
+ raise ArgumentError, msg
120
+ end
121
+ end
122
+
123
+ end
124
+ end
@@ -148,6 +148,17 @@ module PSWindows::Exec
148
148
  self.close #refresh the state
149
149
  end
150
150
 
151
+ def environment_string env
152
+ return '' if env.empty?
153
+ env_array = self.environment_variable_string_pair_array( env )
154
+
155
+ environment_string = ''
156
+ env_array.each_with_index do |env|
157
+ environment_string += "set #{env} && "
158
+ end
159
+ environment_string
160
+ end
161
+
151
162
  # Overrides the {Windows::Exec#ssh_permit_user_environment} method,
152
163
  # since no steps are needed in this setup to allow user ssh environments
153
164
  # to work.
@@ -5,7 +5,7 @@ module PSWindows::User
5
5
  execute('cmd /c echo "" | wmic useraccount where localaccount="true" get name /format:value') do |result|
6
6
  users = []
7
7
  result.stdout.each_line do |line|
8
- users << (line.match(/^Name=([\w ]+)/) or next)[1]
8
+ users << (line.match(/^Name=(.+)/) or next)[1]
9
9
  end
10
10
 
11
11
  yield result if block_given?
@@ -146,8 +146,6 @@ module Unix
146
146
  def skip_set_env?
147
147
  variant, version, arch, codename = self['platform'].to_array
148
148
  case variant
149
- when /^cisco$/
150
- 'Cisco does not allow SSH control through the BASH shell'
151
149
  when /^(f5|netscaler)$/
152
150
  "no puppet-agent package for network device platform '#{variant}'"
153
151
  else
@@ -155,6 +153,15 @@ module Unix
155
153
  end
156
154
  end
157
155
 
156
+ # Validates that the host was setup correctly
157
+ #
158
+ # @return nil
159
+ # @raise [ArgumentError] If the host is setup incorrectly,
160
+ # this will be raised with the appropriate message
161
+ def validate_setup
162
+ nil
163
+ end
164
+
158
165
  def initialize name, host_hash, options
159
166
  super
160
167
 
@@ -219,6 +219,49 @@ module Unix::Exec
219
219
  ssh_service_restart()
220
220
  end
221
221
 
222
+ # Construct the environment string for this command
223
+ #
224
+ # @param [Hash{String=>String}] env An optional Hash containing
225
+ # key-value pairs to be treated
226
+ # as environment variables that
227
+ # should be set for the duration
228
+ # of the puppet command.
229
+ #
230
+ # @return [String] Returns a string containing command line arguments that
231
+ # will ensure the environment is correctly set for the
232
+ # given host.
233
+ def environment_string env
234
+ return '' if env.empty?
235
+ env_array = self.environment_variable_string_pair_array( env )
236
+ environment_string = env_array.join(' ')
237
+ "env #{environment_string}"
238
+ end
239
+
240
+ def environment_variable_string_pair_array env
241
+ env_array = []
242
+ env.each_key do |key|
243
+ val = env[key]
244
+ if val.is_a?(Array)
245
+ val = val.join(':')
246
+ else
247
+ val = val.to_s
248
+ end
249
+ env_array << "#{key.to_s.upcase}=\"#{val}\""
250
+ end
251
+ env_array
252
+ end
253
+
254
+ # Gets the specific prepend commands as needed for this host
255
+ #
256
+ # @param [String] command Command to be executed
257
+ # @param [String] user_pc List of user-specified commands to prepend
258
+ # @param [Hash] opts optional parameters
259
+ #
260
+ # @return [String] Command string as needed for this host
261
+ def prepend_commands(command = '', user_pc = '', opts = {})
262
+ user_pc
263
+ end
264
+
222
265
  # Fills the user SSH environment file.
223
266
  #
224
267
  # @param [Hash{String=>String}] env Environment variables to set on the system,
@@ -15,9 +15,11 @@ module Unix::File
15
15
 
16
16
  # Handles any changes needed in a path for SCP
17
17
  #
18
- # @note This is really only needed in Windows at this point. Refer to
19
- # {Windows::File#scp_path} for more info
20
- def scp_path path
18
+ # @param [String] path File path to SCP to
19
+ #
20
+ # @return [String] path, changed if needed due to host
21
+ # constraints
22
+ def scp_path(path)
21
23
  path
22
24
  end
23
25
 
@@ -60,8 +62,9 @@ module Unix::File
60
62
  repo_filename = "pl-%s-%s-" % [ package_name, build_version ]
61
63
 
62
64
  case variant
63
- when /fedora|el|centos/
65
+ when /fedora|el|centos|cisco/
64
66
  variant = 'el' if variant == 'centos'
67
+ variant = 'cisco-wrlinux' if variant == 'cisco'
65
68
  fedora_prefix = ((variant == 'fedora') ? 'f' : '')
66
69
  pattern = "%s-%s%s-%s.repo"
67
70
  pattern = "repos-pe-#{pattern}" if self.is_pe?
@@ -144,4 +147,16 @@ NOASK
144
147
  end
145
148
  noask
146
149
  end
150
+
151
+ protected
152
+
153
+ # Handles host operations needed after an SCP takes place
154
+ #
155
+ # @param [String] scp_file_actual File path to actual SCP'd file on host
156
+ # @param [String] scp_file_target File path to target SCP location on host
157
+ #
158
+ # @return nil
159
+ def scp_post_operations(scp_file_actual, scp_file_target)
160
+ nil
161
+ end
147
162
  end