beaker 3.20.0 → 3.21.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 (55) hide show
  1. checksums.yaml +8 -8
  2. data/beaker.gemspec +4 -5
  3. data/docs/how_to/hypervisors/README.md +7 -3
  4. data/docs/tutorials/quick_start_rake_tasks.md +1 -1
  5. data/lib/beaker/command.rb +1 -1
  6. data/lib/beaker/host.rb +6 -4
  7. data/lib/beaker/host/windows/exec.rb +10 -0
  8. data/lib/beaker/host/windows/pkg.rb +1 -29
  9. data/lib/beaker/host_prebuilt_steps.rb +1 -0
  10. data/lib/beaker/hypervisor.rb +26 -37
  11. data/lib/beaker/ssh_connection.rb +8 -15
  12. data/lib/beaker/version.rb +1 -1
  13. data/spec/beaker/dsl/install_utils/windows_utils_spec.rb +1 -1
  14. data/spec/beaker/host/windows/exec_spec.rb +18 -0
  15. data/spec/beaker/host/windows/pkg_spec.rb +0 -7
  16. data/spec/beaker/host_prebuilt_steps_spec.rb +1 -0
  17. data/spec/beaker/host_spec.rb +31 -40
  18. data/spec/beaker/hypervisor/hypervisor_spec.rb +20 -34
  19. data/spec/beaker/ssh_connection_spec.rb +18 -19
  20. data/spec/spec_helper.rb +0 -1
  21. metadata +23 -57
  22. data/docs/how_to/hypervisors/aws.md +0 -149
  23. data/docs/how_to/hypervisors/ec2.md +0 -81
  24. data/docs/how_to/hypervisors/google_compute_engine.md +0 -41
  25. data/docs/how_to/hypervisors/vagrant.md +0 -165
  26. data/docs/how_to/hypervisors/vagrant_hosts_file_examples.md +0 -60
  27. data/docs/how_to/hypervisors/vagrant_libvirt.md +0 -58
  28. data/docs/how_to/hypervisors/vmware_fusion.md +0 -36
  29. data/docs/how_to/hypervisors/vsphere.md +0 -54
  30. data/lib/beaker/hypervisor/aws_sdk.rb +0 -989
  31. data/lib/beaker/hypervisor/ec2_helper.rb +0 -41
  32. data/lib/beaker/hypervisor/fusion.rb +0 -65
  33. data/lib/beaker/hypervisor/google_compute.rb +0 -164
  34. data/lib/beaker/hypervisor/google_compute_helper.rb +0 -577
  35. data/lib/beaker/hypervisor/vagrant.rb +0 -286
  36. data/lib/beaker/hypervisor/vagrant_custom.rb +0 -11
  37. data/lib/beaker/hypervisor/vagrant_fusion.rb +0 -17
  38. data/lib/beaker/hypervisor/vagrant_libvirt.rb +0 -41
  39. data/lib/beaker/hypervisor/vagrant_parallels.rb +0 -18
  40. data/lib/beaker/hypervisor/vagrant_virtualbox.rb +0 -76
  41. data/lib/beaker/hypervisor/vagrant_workstation.rb +0 -13
  42. data/lib/beaker/hypervisor/vsphere.rb +0 -85
  43. data/lib/beaker/hypervisor/vsphere_helper.rb +0 -204
  44. data/spec/beaker/hypervisor/aws_sdk_spec.rb +0 -980
  45. data/spec/beaker/hypervisor/ec2_helper_spec.rb +0 -44
  46. data/spec/beaker/hypervisor/fusion_spec.rb +0 -41
  47. data/spec/beaker/hypervisor/vagrant_custom_spec.rb +0 -46
  48. data/spec/beaker/hypervisor/vagrant_fusion_spec.rb +0 -32
  49. data/spec/beaker/hypervisor/vagrant_libvirt_spec.rb +0 -61
  50. data/spec/beaker/hypervisor/vagrant_parallels_spec.rb +0 -44
  51. data/spec/beaker/hypervisor/vagrant_spec.rb +0 -479
  52. data/spec/beaker/hypervisor/vagrant_virtualbox_spec.rb +0 -44
  53. data/spec/beaker/hypervisor/vagrant_workstation_spec.rb +0 -32
  54. data/spec/beaker/hypervisor/vsphere_helper_spec.rb +0 -163
  55. data/spec/beaker/hypervisor/vsphere_spec.rb +0 -90
@@ -1,286 +0,0 @@
1
- require 'open3'
2
-
3
- module Beaker
4
- class Vagrant < Beaker::Hypervisor
5
-
6
- # Return a random mac address
7
- #
8
- # @return [String] a random mac address
9
- def randmac
10
- "080027" + (1..3).map{"%0.2X"%rand(256)}.join
11
- end
12
-
13
- def rand_chunk
14
- (2 + rand(252)).to_s #don't want a 0, 1, or a 255
15
- end
16
-
17
- def randip
18
- "10.255.#{rand_chunk}.#{rand_chunk}"
19
- end
20
-
21
- def private_network_generator(host)
22
- private_network_string = " v.vm.network :private_network, ip: \"#{host['ip'].to_s}\", :netmask => \"#{host['netmask'] ||= "255.255.0.0"}\""
23
- case host['network_mac']
24
- when 'false'
25
- private_network_string << "\n"
26
- when nil
27
- private_network_string << ", :mac => \"#{randmac}\"\n"
28
- else
29
- private_network_string << ", :mac => \"#{host['network_mac']}\"\n"
30
- end
31
- end
32
-
33
- def make_vfile hosts, options = {}
34
- #HACK HACK HACK - add checks here to ensure that we have box + box_url
35
- #generate the VagrantFile
36
- v_file = "Vagrant.configure(\"2\") do |c|\n"
37
- v_file << " c.ssh.forward_agent = true\n" if options[:forward_ssh_agent] == true
38
- v_file << " c.ssh.insert_key = false\n"
39
- hosts.each do |host|
40
- host['ip'] ||= randip #use the existing ip, otherwise default to a random ip
41
- v_file << " c.vm.define '#{host.name}' do |v|\n"
42
- v_file << " v.vm.hostname = '#{host.name}'\n"
43
- v_file << " v.vm.box = '#{host['box']}'\n"
44
- v_file << " v.vm.box_url = '#{host['box_url']}'\n" unless host['box_url'].nil?
45
- v_file << " v.vm.box_version = '#{host['box_version']}'\n" unless host['box_version'].nil?
46
- v_file << " v.vm.box_check_update = '#{host['box_check_update'] ||= 'true'}'\n"
47
- v_file << " v.vm.synced_folder '.', '/vagrant', disabled: true\n" if host['synced_folder'] == 'disabled'
48
- v_file << private_network_generator(host)
49
-
50
- unless host['mount_folders'].nil?
51
- host['mount_folders'].each do |name, folder|
52
- v_file << " v.vm.synced_folder '#{folder[:from]}', '#{folder[:to]}', create: true\n"
53
- end
54
- end
55
-
56
- unless host['forwarded_ports'].nil?
57
- host['forwarded_ports'].each do |_name, port|
58
- fwd = " v.vm.network :forwarded_port,"
59
- fwd << " protocol: '#{port[:protocol]}'," unless port[:protocol].nil?
60
- fwd << " guest_ip: '#{port[:to_ip]}'," unless port[:to_ip].nil?
61
- fwd << " guest: #{port[:to]},"
62
- fwd << " host_ip: '#{port[:from_ip]}'," unless port[:from_ip].nil?
63
- fwd << " host: #{port[:from]}"
64
- fwd << "\n"
65
-
66
- v_file << fwd
67
- end
68
- end
69
-
70
- if /windows/i.match(host['platform'])
71
- #due to a regression bug in versions of vagrant 1.6.2, 1.6.3, 1.6.4, >= 1.7.3 ssh fails to forward
72
- #automatically (note <=1.6.1, 1.6.5, 1.7.0 - 1.7.2 are uneffected)
73
- #Explicitly setting SSH port forwarding due to this bug
74
- v_file << " v.vm.network :forwarded_port, guest: 22, host: 2222, id: 'ssh', auto_correct: true\n"
75
- v_file << " v.vm.network :forwarded_port, guest: 3389, host: 3389, id: 'rdp', auto_correct: true\n"
76
- v_file << " v.vm.network :forwarded_port, guest: 5985, host: 5985, id: 'winrm', auto_correct: true\n"
77
- v_file << " v.vm.guest = :windows\n"
78
- end
79
-
80
- if /osx/i.match(host['platform'])
81
- v_file << " v.vm.network 'private_network', ip: '10.0.1.10'\n"
82
- v_file << " v.vm.synced_folder '.', '/vagrant', :nfs => true\n"
83
- end
84
-
85
- if /freebsd/i.match(host['platform'])
86
- v_file << " v.ssh.shell = 'sh'\n"
87
- v_file << " v.vm.guest = :freebsd\n"
88
-
89
- # FreeBSD NFS has a character restriction of 88 characters
90
- # So you can enable it but if your module has a long name it probably won't work...
91
- # So to keep things simple let's rsync by default!
92
- #
93
- # Further reading if interested:
94
- # http://www.secnetix.de/olli/FreeBSD/mnamelen.hawk
95
- # https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=167105
96
- #
97
- if host['vagrant_freebsd_nfs'].nil?
98
- v_file << " v.vm.synced_folder '.', '/vagrant', type: 'rsync'\n"
99
- else
100
- v_file << " v.vm.synced_folder '.', '/vagrant', :nfs => true\n"
101
- end
102
- end
103
-
104
- v_file << self.class.provider_vfile_section(host, options)
105
-
106
- v_file << " end\n"
107
- @logger.debug "created Vagrantfile for VagrantHost #{host.name}"
108
- end
109
- v_file << "end\n"
110
- File.open(@vagrant_file, 'w') do |f|
111
- f.write(v_file)
112
- end
113
- end
114
-
115
- def self.provider_vfile_section host, options
116
- # Backwards compatibility; default to virtualbox
117
- Beaker::VagrantVirtualbox.provider_vfile_section(host, options)
118
- end
119
-
120
- def set_ssh_config host, user
121
- f = Tempfile.new("#{host.name}")
122
- ssh_config = Dir.chdir(@vagrant_path) do
123
- stdin, stdout, stderr, wait_thr = Open3.popen3(@vagrant_env, 'vagrant', 'ssh-config', host.name)
124
- if not wait_thr.value.success?
125
- raise "Failed to 'vagrant ssh-config' for #{host.name}"
126
- end
127
- stdout.read
128
- end
129
- #replace hostname with ip
130
- ssh_config = ssh_config.gsub(/Host #{host.name}/, "Host #{host['ip']}") unless not host['ip']
131
-
132
- #set the user
133
- ssh_config = ssh_config.gsub(/User vagrant/, "User #{user}")
134
- f.write(ssh_config)
135
- f.rewind
136
- host['ssh'] = {:config => f.path()}
137
- host['user'] = user
138
- @temp_files << f
139
- end
140
-
141
- def get_ip_from_vagrant_file(hostname)
142
- ip = ''
143
- if File.file?(@vagrant_file) #we should have a vagrant file available to us for reading
144
- f = File.read(@vagrant_file)
145
- m = /'#{hostname}'.*?ip:\s*('|")\s*([^'"]+)('|")/m.match(f)
146
- if m
147
- ip = m[2]
148
- @logger.debug("Determined existing vagrant box #{hostname} ip to be: #{ip} ")
149
- else
150
- ip = nil
151
- @logger.debug("Unable to determine ip for vagrant box #{hostname}")
152
- end
153
- else
154
- raise("No vagrant file found (should be located at #{@vagrant_file})")
155
- end
156
- ip
157
- end
158
-
159
- def initialize(vagrant_hosts, options)
160
- require 'tempfile'
161
- @options = options
162
- @logger = options[:logger]
163
- @temp_files = []
164
- @hosts = vagrant_hosts
165
- @vagrant_path = File.expand_path(File.join(File.basename(__FILE__), '..', '.vagrant', 'beaker_vagrant_files', File.basename(options[:hosts_file])))
166
- FileUtils.mkdir_p(@vagrant_path)
167
- @vagrant_file = File.expand_path(File.join(@vagrant_path, "Vagrantfile"))
168
- @vagrant_env = { "RUBYLIB" => "" }
169
- end
170
-
171
- def provision(provider = nil)
172
- if !@options[:provision] and !File.file?(@vagrant_file)
173
- raise "Beaker is configured with provision = false but no vagrant file was found at #{@vagrant_file}. You need to enable provision"
174
- end
175
- if @options[:provision]
176
- #setting up new vagrant hosts
177
- #make sure that any old boxes are dead dead dead
178
- begin
179
- vagrant_cmd("destroy --force") if File.file?(@vagrant_file)
180
- rescue RuntimeError => e
181
- # LATER: use <<~MESSAGE once we're on Ruby 2.3
182
- @logger.debug(%Q{
183
- Beaker failed to destroy the existing VM's. If you think this is
184
- an error or you upgraded from an older version of beaker try
185
- verifying the VM exists and deleting the existing Vagrantfile if
186
- you believe it is safe to do so. WARNING: If a VM still exists
187
- please run 'vagrant destroy'.
188
-
189
- cd #{@vagrant_path}
190
- vagrant status
191
- vagrant destroy # only need to run this is a VM is not created
192
- rm #{@vagrant_file} # only do this if all VM's are actually destroyed
193
- }.each_line.map(&:strip).join("\n"))
194
- raise e
195
- end
196
-
197
- make_vfile @hosts, @options
198
-
199
- vagrant_cmd("up#{" --provider #{provider}" if provider}")
200
- else #set host ip of already up boxes
201
- @hosts.each do |host|
202
- host[:ip] = get_ip_from_vagrant_file(host.name)
203
- end
204
- end
205
-
206
- @logger.debug "configure vagrant boxes (set ssh-config, switch to root user, hack etc/hosts)"
207
- @hosts.each do |host|
208
- if host[:platform] =~ /windows/
209
- @logger.debug "skip ssh hacks on windows box #{host[:name]}"
210
- set_ssh_config host, host['user']
211
- next
212
- end
213
-
214
- default_user = host['user']
215
-
216
- set_ssh_config host, 'vagrant'
217
-
218
- #copy vagrant's keys to roots home dir, to allow for login as root
219
- copy_ssh_to_root host, @options
220
- #ensure that root login is enabled for this host
221
- enable_root_login host, @options
222
- #shut down connection, will reconnect on next exec
223
- host.close
224
-
225
- set_ssh_config host, default_user
226
- end
227
-
228
- hack_etc_hosts @hosts, @options
229
-
230
- end
231
-
232
- def cleanup
233
- @logger.debug "removing temporary ssh-config files per-vagrant box"
234
- @temp_files.each do |f|
235
- f.close()
236
- end
237
- @logger.notify "Destroying vagrant boxes"
238
- vagrant_cmd("destroy --force")
239
- FileUtils.rm_rf(@vagrant_path)
240
- end
241
-
242
- def vagrant_cmd(args)
243
- Dir.chdir(@vagrant_path) do
244
- exit_status = 1
245
- Open3.popen3(@vagrant_env, "vagrant #{args}") {|stdin, stdout, stderr, wait_thr|
246
- while line = stdout.gets
247
- @logger.info(line)
248
- end
249
- if not wait_thr.value.success?
250
- raise "Failed to exec 'vagrant #{args}'. Error was #{stderr.read}"
251
- end
252
- exit_status = wait_thr.value
253
- }
254
- if exit_status != 0
255
- raise "Failed to execute vagrant_cmd ( #{args} ). Error was #{stderr.read}"
256
- end
257
- end
258
- end
259
-
260
- def self.cpus(host, options)
261
- case
262
- when host['vagrant_cpus']
263
- host['vagrant_cpus']
264
- when options['vagrant_cpus']
265
- options['vagrant_cpus']
266
- else
267
- '1'
268
- end
269
- end
270
-
271
- def self.memsize(host, options)
272
- case
273
- when host['vagrant_memsize']
274
- host['vagrant_memsize']
275
- when options['vagrant_memsize']
276
- options['vagrant_memsize']
277
- else
278
- if host['platform'] =~ /windows/
279
- '2048'
280
- else
281
- '1024'
282
- end
283
- end
284
- end
285
- end
286
- end
@@ -1,11 +0,0 @@
1
- require 'beaker/hypervisor/vagrant'
2
-
3
- class Beaker::VagrantCustom < Beaker::Vagrant
4
- def provision(provider = nil)
5
- super
6
- end
7
-
8
- def make_vfile hosts, options = {}
9
- FileUtils.cp(@options[:vagrantfile_path], @vagrant_file)
10
- end
11
- end
@@ -1,17 +0,0 @@
1
- require 'beaker/hypervisor/vagrant'
2
-
3
- class Beaker::VagrantFusion < Beaker::Vagrant
4
- def provision(provider = 'vmware_fusion')
5
- # By default vmware_fusion creates a .vagrant directory relative to the
6
- # Vagrantfile path. That means beaker tries to scp the VM to itself unless
7
- # we move the VM files elsewhere.
8
- ENV['VAGRANT_VMWARE_CLONE_DIRECTORY'] = '~/.vagrant/vmware_fusion'
9
- super
10
- end
11
-
12
- def self.provider_vfile_section(host, options)
13
- " v.vm.provider :vmware_fusion do |v|\n" +
14
- " v.vmx['memsize'] = '#{memsize(host, options)}'\n" +
15
- " end\n"
16
- end
17
- end
@@ -1,41 +0,0 @@
1
- require 'beaker/hypervisor/vagrant'
2
-
3
- class Beaker::VagrantLibvirt < Beaker::Vagrant
4
- @memory = nil
5
- @cpu = nil
6
-
7
- class << self
8
- attr_reader :memory
9
- end
10
-
11
- # Return a random mac address with colons
12
- #
13
- # @return [String] a random mac address
14
- def randmac
15
- "08:00:27:" + (1..3).map{"%0.2X"%rand(256)}.join(':')
16
- end
17
-
18
- def provision(provider = 'libvirt')
19
- super
20
- end
21
-
22
- def self.provider_vfile_section(host, options)
23
- " v.vm.provider :libvirt do |node|\n" +
24
- " node.cpus = #{cpus(host, options)}\n" +
25
- " node.memory = #{memsize(host, options)}\n" +
26
- build_options_str(options) +
27
- " end\n"
28
- end
29
-
30
- def self.build_options_str(options)
31
- other_options_str = ''
32
- if options['libvirt']
33
- other_options = []
34
- options['libvirt'].each do |k, v|
35
- other_options << " node.#{k} = '#{v}'"
36
- end
37
- other_options_str = other_options.join("\n")
38
- end
39
- "#{other_options_str}\n"
40
- end
41
- end
@@ -1,18 +0,0 @@
1
- require 'beaker/hypervisor/vagrant'
2
-
3
- class Beaker::VagrantParallels < Beaker::Vagrant
4
- def provision(provider = 'parallels')
5
- super
6
- end
7
-
8
- def self.provider_vfile_section(host, options)
9
- provider_section = ""
10
- provider_section << " v.vm.provider :parallels do |prl|\n"
11
- provider_section << " prl.optimize_power_consumption = false\n"
12
- provider_section << " prl.memory = '#{memsize(host,options)}'\n"
13
- provider_section << " prl.update_guest_tools = false\n" if options[:prl_update_guest_tools] == 'disable'
14
- provider_section << " end\n"
15
-
16
- provider_section
17
- end
18
- end
@@ -1,76 +0,0 @@
1
- require 'beaker/hypervisor/vagrant'
2
-
3
- class Beaker::VagrantVirtualbox < Beaker::Vagrant
4
- def provision(provider = 'virtualbox')
5
- super
6
- end
7
-
8
- # Generate a VM customization string
9
- def self.vb_customize(command, args)
10
- " vb.customize ['#{command}', #{args.map{|a| "'#{a.to_s}'"}.join(", ")}]\n"
11
- end
12
-
13
- # Generate a VM customization string for the current VM
14
- def self.vb_customize_vm(command, args)
15
- " vb.customize ['#{command}', :id, #{args.map{|a| "'#{a.to_s}'"}.join(", ")}]\n"
16
- end
17
-
18
- def self.provider_vfile_section(host, options)
19
- # Allow memory and CPUs to be set at a per node level or overall, and take the most specific setting
20
- provider_section = ""
21
- provider_section << " v.vm.provider :virtualbox do |vb|\n"
22
- provider_section << " vb.customize ['modifyvm', :id, '--memory', '#{memsize(host,options)}', '--cpus', '#{cpus(host,options)}']\n"
23
- provider_section << " vb.vbguest.auto_update = false" if options[:vbguest_plugin] == 'disable'
24
-
25
- # Guest volume support
26
- # - Creates a new AHCI controller with the requisite number of ports,
27
- # the default controller is limited in its number of supported ports (2).
28
- # The AHCI emulation is generic enough for acceptance testing, and
29
- # presents the devices as SCSI devices in /sys/class/scsi_disk.
30
- # - Creates the defined volumes in beaker's temporary folder and attaches
31
- # them to the controller in order starting at port 0. This presents disks
32
- # as 2:0:0:0, 3:0:0:0 ... much like you'd see on commercial storage boxes
33
- if host['volumes']
34
- provider_section << self.vb_customize_vm('storagectl', [
35
- '--name', 'SATA Controller',
36
- '--add', 'sata',
37
- '--controller', 'IntelAHCI',
38
- '--portcount', host['volumes'].length
39
- ])
40
- host['volumes'].keys.each_with_index do |volume, index|
41
- volume_path = "#{host.name}-#{volume}.vdi"
42
- provider_section << self.vb_customize('createhd', [
43
- '--filename', volume_path,
44
- '--size', host['volumes'][volume]['size'],
45
- ])
46
- provider_section << self.vb_customize_vm('storageattach', [
47
- '--storagectl', 'SATA Controller',
48
- '--port', index,
49
- '--device', 0,
50
- '--type', 'hdd',
51
- '--medium', volume_path,
52
- ])
53
- end
54
- end
55
-
56
- provider_section << " vb.customize [\"modifyvm\", :id, \"--natdnshostresolver1\", \"#{host['natdns']}\"]\n" unless host['natdns'].nil?
57
-
58
- provider_section << " vb.customize [\"modifyvm\", :id, \"--natdnsproxy1\", \"#{host['natdns']}\"]\n" unless host['natdns'].nil?
59
-
60
- provider_section << " vb.gui = true\n" unless host['vb_gui'].nil?
61
-
62
- provider_section << " [\"modifyvm\", :id, \"--cpuidset\", \"1\",\"000206a7\",\"02100800\",\"1fbae3bf\",\"bfebfbff\"\]" if /osx/i.match(host['platform'])
63
-
64
- if host['disk_path']
65
- unless File.exist?(host['disk_path'])
66
- host['disk_path'] = File.join(host['disk_path'], "#{host.name}.vmdk")
67
- provider_section << " vb.customize ['createhd', '--filename', '#{host['disk_path']}', '--size', #{host['disk_size'] ||= 5 * 1024}, '--format', 'vmdk']\n"
68
- end
69
- provider_section << " vb.customize ['storageattach', :id, '--storagectl', 'SATA Controller', '--port', 1, '--device', 0, '--type', 'hdd', '--medium','#{host['disk_path']}']\n"
70
- end
71
-
72
- provider_section << " end\n"
73
-
74
- provider_section
75
- end
76
- end