beaker 2.33.0 → 2.34.0

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