beaker-vagrant 0.6.3 → 0.7.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.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +8 -0
- data/.github/workflows/release.yml +24 -0
- data/.github/workflows/test.yml +32 -0
- data/.rspec +1 -0
- data/Rakefile +2 -2
- data/beaker-vagrant.gemspec +2 -6
- data/docs/vagrant.md +39 -1
- data/lib/beaker-vagrant/version.rb +1 -1
- data/lib/beaker/hypervisor/vagrant.rb +46 -68
- data/lib/beaker/hypervisor/vagrant_custom.rb +1 -0
- data/lib/beaker/hypervisor/vagrant_libvirt.rb +18 -22
- data/lib/beaker/hypervisor/vagrant_virtualbox.rb +4 -4
- data/spec/beaker/hypervisor/vagrant_custom_spec.rb +3 -2
- data/spec/beaker/hypervisor/vagrant_desktop_spec.rb +33 -47
- data/spec/beaker/hypervisor/vagrant_fusion_spec.rb +14 -14
- data/spec/beaker/hypervisor/vagrant_libvirt_spec.rb +23 -26
- data/spec/beaker/hypervisor/vagrant_parallels_spec.rb +20 -23
- data/spec/beaker/hypervisor/vagrant_spec.rb +43 -118
- data/spec/beaker/hypervisor/vagrant_virtualbox_spec.rb +47 -56
- data/spec/beaker/hypervisor/vagrant_workstation_spec.rb +33 -47
- metadata +16 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4ee5ce13c977a0b3bd07ff792f1f722d986e1e50a332bb4762d1d15c8c8dfe48
|
4
|
+
data.tar.gz: 9e17a0f6f245ba61142e42883f0d2b5ac456e40b92b26d6b8c22d08dffc0c7b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b2c6c0ed39876e4f630d9dac376f782a00277011c8b5321567ed09635e55f04b7656df59f0658b1565a3fd474bf632017ea9a9ca99bdd5ba083ebc2791aea7e
|
7
|
+
data.tar.gz: 4f429aeccdbb05b4a9eeccf817e44327a463315a16c7a517914469a4a09f9b046d3ea8fc4342208ae2071f1a907324c20c23e1006feff3fe9e96979f6739a6a4
|
@@ -0,0 +1,24 @@
|
|
1
|
+
name: Release
|
2
|
+
|
3
|
+
on:
|
4
|
+
create:
|
5
|
+
ref_type: tag
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
release:
|
9
|
+
runs-on: ubuntu-latest
|
10
|
+
if: github.repository == 'voxpupuli/beaker-vagrant'
|
11
|
+
env:
|
12
|
+
BUNDLE_WITHOUT: release
|
13
|
+
steps:
|
14
|
+
- uses: actions/checkout@v2
|
15
|
+
- name: Install Ruby 2.7
|
16
|
+
uses: ruby/setup-ruby@v1
|
17
|
+
with:
|
18
|
+
ruby-version: '2.7'
|
19
|
+
- name: Build gem
|
20
|
+
run: gem build *.gemspec
|
21
|
+
- name: Publish gem
|
22
|
+
run: gem push *.gem
|
23
|
+
env:
|
24
|
+
GEM_HOST_API_KEY: '${{ secrets.RUBYGEMS_AUTH_TOKEN }}'
|
@@ -0,0 +1,32 @@
|
|
1
|
+
name: Test
|
2
|
+
|
3
|
+
on:
|
4
|
+
- pull_request
|
5
|
+
|
6
|
+
jobs:
|
7
|
+
test:
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
strategy:
|
10
|
+
fail-fast: false
|
11
|
+
matrix:
|
12
|
+
ruby:
|
13
|
+
- "2.4"
|
14
|
+
- "2.5"
|
15
|
+
- "2.6"
|
16
|
+
- "2.7"
|
17
|
+
env:
|
18
|
+
BUNDLE_WITHOUT: release
|
19
|
+
name: Ruby ${{ matrix.ruby }}
|
20
|
+
steps:
|
21
|
+
- uses: actions/checkout@v2
|
22
|
+
- name: Install Ruby ${{ matrix.ruby }}
|
23
|
+
uses: ruby/setup-ruby@v1
|
24
|
+
with:
|
25
|
+
ruby-version: ${{ matrix.ruby }}
|
26
|
+
bundler-cache: true
|
27
|
+
- name: Run spec tests
|
28
|
+
run: bundle exec rake test:spec
|
29
|
+
# It seems some additonal setup of Docker may be needed for
|
30
|
+
# the acceptance tests to work.
|
31
|
+
# - name: Run acceptance tests
|
32
|
+
# run: bundle exec rake test:acceptance
|
data/.rspec
CHANGED
data/Rakefile
CHANGED
@@ -6,14 +6,14 @@ namespace :test do
|
|
6
6
|
|
7
7
|
desc "Run spec tests"
|
8
8
|
RSpec::Core::RakeTask.new(:run) do |t|
|
9
|
-
t.rspec_opts = ['--color']
|
9
|
+
t.rspec_opts = ['--color', '--format documentation']
|
10
10
|
t.pattern = 'spec/'
|
11
11
|
end
|
12
12
|
|
13
13
|
desc "Run spec tests with coverage"
|
14
14
|
RSpec::Core::RakeTask.new(:coverage) do |t|
|
15
15
|
ENV['BEAKER_TEMPLATE_COVERAGE'] = 'y'
|
16
|
-
t.rspec_opts = ['--color']
|
16
|
+
t.rspec_opts = ['--color', '--format documentation']
|
17
17
|
t.pattern = 'spec/'
|
18
18
|
end
|
19
19
|
|
data/beaker-vagrant.gemspec
CHANGED
@@ -24,18 +24,14 @@ Gem::Specification.new do |s|
|
|
24
24
|
if RUBY_VERSION < "2.3"
|
25
25
|
s.add_development_dependency 'fakefs', '~> 0.6', '< 0.14'
|
26
26
|
else
|
27
|
-
s.add_development_dependency 'fakefs', '
|
27
|
+
s.add_development_dependency 'fakefs', '>= 0.6', '< 2.0'
|
28
28
|
end
|
29
|
-
s.add_development_dependency 'rake', '~>
|
29
|
+
s.add_development_dependency 'rake', '~> 13.0'
|
30
30
|
s.add_development_dependency 'simplecov'
|
31
31
|
s.add_development_dependency 'pry', '~> 0.10'
|
32
32
|
|
33
33
|
# Documentation dependencies
|
34
34
|
s.add_development_dependency 'yard'
|
35
35
|
s.add_development_dependency 'thin'
|
36
|
-
|
37
|
-
# Run time dependencies
|
38
|
-
s.add_runtime_dependency 'stringify-hash', '~> 0.0.0'
|
39
|
-
|
40
36
|
end
|
41
37
|
|
data/docs/vagrant.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
# Vagrant
|
2
2
|
|
3
|
+
<!-- vim-markdown-toc GFM -->
|
4
|
+
|
5
|
+
* [Getting Started](#getting-started)
|
6
|
+
* [Requirements](#requirements)
|
7
|
+
* [Setup a Vagrant Hosts File](#setup-a-vagrant-hosts-file)
|
8
|
+
* [Vagrant-Specific Hosts File Settings](#vagrant-specific-hosts-file-settings)
|
9
|
+
* [Running With a GUI](#running-with-a-gui)
|
10
|
+
* [Mounting Local Folders](#mounting-local-folders)
|
11
|
+
* [Forwarding Ports to Guest](#forwarding-ports-to-guest)
|
12
|
+
* [Volumes Support](#volumes-support)
|
13
|
+
* [Adding vagrant shell provisioner](#adding-vagrant-shell-provisioner)
|
14
|
+
* [Using the host's resolver as a DNS proxy in NAT mode (virtualbox only)](#using-the-hosts-resolver-as-a-dns-proxy-in-nat-mode-virtualbox-only)
|
15
|
+
* [vagrant plugins](#vagrant-plugins)
|
16
|
+
|
17
|
+
<!-- vim-markdown-toc -->
|
18
|
+
|
3
19
|
Vagrant's slogan is "development environments made easy". Vagrant provides an
|
4
20
|
abstraction on top of a VM or cloud provider that allows you to manage
|
5
21
|
hosts and their provisioning. <https://www.vagrantup.com/>.
|
@@ -211,8 +227,30 @@ When using the Vagrant Hypervisor, beaker can create the Vagrantfile with a shel
|
|
211
227
|
|
212
228
|
In the above, beaker will create a Vagrantfile which runs the above shell script on the Agent guest.
|
213
229
|
|
230
|
+
### Using the host's resolver as a DNS proxy in NAT mode (virtualbox only)
|
231
|
+
|
232
|
+
When using the Vagrant hypervisor with the virtualbox provider, beaker can
|
233
|
+
configure the VirtualBox NAT engine's DHCP sever to proxy DNS queries through
|
234
|
+
to the host's resolver using the `natdns` setting in the nodeset file.
|
235
|
+
|
236
|
+
**Example hosts file**
|
237
|
+
|
238
|
+
HOSTS:
|
239
|
+
el7-server:
|
240
|
+
roles:
|
241
|
+
- default
|
242
|
+
platform: el-7-x86_64
|
243
|
+
box: centos/7
|
244
|
+
hypervisor: vagrant
|
245
|
+
natdns: on
|
246
|
+
yum_repos:
|
247
|
+
epel:
|
248
|
+
mirrorlist: 'https://mirrors.fedoraproject.org/mirrorlist?repo=epel-7&arch=$basearch&country=us'
|
249
|
+
gpgkeys:
|
250
|
+
- https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-$releasever
|
251
|
+
|
214
252
|
# vagrant plugins #
|
215
253
|
|
216
|
-
You can check more information for some
|
254
|
+
You can check more information for some supported vagrant plugins:
|
217
255
|
|
218
256
|
- [vagrant-libvirt](vagrant_libvirt.md)
|
@@ -5,36 +5,33 @@ module Beaker
|
|
5
5
|
|
6
6
|
require 'beaker/hypervisor/vagrant/mount_folder'
|
7
7
|
require 'beaker/hypervisor/vagrant_virtualbox'
|
8
|
-
# Return a random mac address
|
9
|
-
#
|
10
|
-
# @return [String] a random mac address
|
11
|
-
def randmac
|
12
|
-
"080027" + (1..3).map{"%0.2X"%rand(256)}.join
|
13
|
-
end
|
14
8
|
|
15
9
|
def rand_chunk
|
16
10
|
(2 + rand(252)).to_s #don't want a 0, 1, or a 255
|
17
11
|
end
|
18
12
|
|
19
|
-
def randip
|
20
|
-
|
13
|
+
def randip(hypervisor=nil)
|
14
|
+
case hypervisor
|
15
|
+
when /libvirt/
|
16
|
+
"10.254.#{rand_chunk}.#{rand_chunk}"
|
17
|
+
else
|
18
|
+
"10.255.#{rand_chunk}.#{rand_chunk}"
|
19
|
+
end
|
21
20
|
end
|
22
21
|
|
23
22
|
def private_network_generator(host)
|
24
23
|
private_network_string = " v.vm.network :private_network, ip: \"#{host['ip'].to_s}\", :netmask => \"#{host['netmask'] ||= "255.255.0.0"}\""
|
25
|
-
|
26
|
-
|
27
|
-
@mac = randmac
|
28
|
-
private_network_string << "\n"
|
29
|
-
when nil
|
30
|
-
@mac = randmac
|
31
|
-
private_network_string << ", :mac => \"#{@mac}\"\n"
|
24
|
+
if host['network_mac']
|
25
|
+
private_network_string << ", :mac => \"#{host['network_mac']}\"\n"
|
32
26
|
else
|
33
|
-
|
34
|
-
private_network_string << ", :mac => \"#{@mac}\"\n"
|
27
|
+
private_network_string << "\n"
|
35
28
|
end
|
36
29
|
end
|
37
30
|
|
31
|
+
def connection_preference(host)
|
32
|
+
[:hostname]
|
33
|
+
end
|
34
|
+
|
38
35
|
def shell_provisioner_generator(provisioner_config)
|
39
36
|
unless provisioner_config['path'].nil? || provisioner_config['path'].empty?
|
40
37
|
unless provisioner_config['args'].nil?
|
@@ -57,7 +54,7 @@ module Beaker
|
|
57
54
|
|
58
55
|
hosts.each do |host|
|
59
56
|
host.name.tr!('_','-') # Rewrite Hostname with hyphens instead of underscores to get legal hostname
|
60
|
-
host
|
57
|
+
set_host_default_ip(host)
|
61
58
|
v_file << " c.vm.define '#{host.name}' do |v|\n"
|
62
59
|
v_file << " v.vm.hostname = '#{host.name}'\n"
|
63
60
|
v_file << " v.vm.box = '#{host['box']}'\n"
|
@@ -67,7 +64,7 @@ module Beaker
|
|
67
64
|
v_file << " v.vm.box_check_update = '#{host['box_check_update'] ||= 'true'}'\n"
|
68
65
|
v_file << " v.vm.synced_folder '.', '/vagrant', disabled: true\n" if host['synced_folder'] == 'disabled'
|
69
66
|
v_file << shell_provisioner_generator(host['shell_provisioner']) if host['shell_provisioner']
|
70
|
-
v_file << private_network_generator(host)
|
67
|
+
v_file << private_network_generator(host) if host['ip']
|
71
68
|
|
72
69
|
unless host['mount_folders'].nil?
|
73
70
|
host['mount_folders'].each do |name, folder|
|
@@ -127,7 +124,6 @@ module Beaker
|
|
127
124
|
else
|
128
125
|
v_file << " v.vm.synced_folder '.', '/vagrant', :nfs => true\n"
|
129
126
|
end
|
130
|
-
v_file << " v.vm.base_mac = '#{@mac}'\n"
|
131
127
|
end
|
132
128
|
|
133
129
|
v_file << self.class.provider_vfile_section(host, options)
|
@@ -136,6 +132,9 @@ module Beaker
|
|
136
132
|
@logger.debug "created Vagrantfile for VagrantHost #{host.name}"
|
137
133
|
end
|
138
134
|
v_file << "end\n"
|
135
|
+
|
136
|
+
# In case this is called directly
|
137
|
+
FileUtils.mkdir_p(@vagrant_path)
|
139
138
|
File.open(@vagrant_file, 'w') do |f|
|
140
139
|
f.write(v_file)
|
141
140
|
end
|
@@ -181,77 +180,53 @@ module Beaker
|
|
181
180
|
end
|
182
181
|
|
183
182
|
def set_ssh_config host, user
|
184
|
-
|
185
|
-
ssh_config = Dir.chdir(@vagrant_path) do
|
186
|
-
stdin, stdout, stderr, wait_thr = Open3.popen3(@vagrant_env, 'vagrant', 'ssh-config', host.name)
|
187
|
-
if not wait_thr.value.success?
|
188
|
-
raise "Failed to 'vagrant ssh-config' for #{host.name}"
|
189
|
-
end
|
190
|
-
stdout.read
|
191
|
-
end
|
192
|
-
#replace hostname with ip
|
193
|
-
ssh_config = ssh_config.gsub(/Host #{host.name}/, "Host #{host['ip']}") unless not host['ip']
|
194
|
-
|
195
|
-
#set the user
|
196
|
-
ssh_config = ssh_config.gsub(/User vagrant/, "User #{user}")
|
183
|
+
return unless Dir.exist?(@vagrant_path)
|
197
184
|
|
198
|
-
|
199
|
-
|
185
|
+
ssh_config = Dir.chdir(@vagrant_path) do
|
186
|
+
stdout, _, status = Open3.capture3(@vagrant_env, 'vagrant', 'ssh-config', host.name)
|
187
|
+
unless status.success?
|
188
|
+
raise "Failed to 'vagrant ssh-config' for #{host.name}"
|
200
189
|
end
|
201
190
|
|
202
|
-
f
|
203
|
-
|
204
|
-
|
205
|
-
host['user'] = user
|
206
|
-
@temp_files << f
|
207
|
-
end
|
191
|
+
Tempfile.create do |f|
|
192
|
+
f.write(stdout)
|
193
|
+
f.flush
|
208
194
|
|
209
|
-
|
210
|
-
ip = ''
|
211
|
-
if File.file?(@vagrant_file) #we should have a vagrant file available to us for reading
|
212
|
-
f = File.read(@vagrant_file)
|
213
|
-
m = /'#{hostname}'.*?ip:\s*('|")\s*([^'"]+)('|")/m.match(f)
|
214
|
-
if m
|
215
|
-
ip = m[2]
|
216
|
-
@logger.debug("Determined existing vagrant box #{hostname} ip to be: #{ip} ")
|
217
|
-
else
|
218
|
-
ip = nil
|
219
|
-
@logger.debug("Unable to determine ip for vagrant box #{hostname}")
|
195
|
+
Net::SSH::Config.for(host.name, [f.path])
|
220
196
|
end
|
221
|
-
else
|
222
|
-
raise("No vagrant file found (should be located at #{@vagrant_file})")
|
223
197
|
end
|
224
|
-
|
198
|
+
|
199
|
+
ssh_config[:user] = user
|
200
|
+
ssh_config[:keys_only] = false if @options[:forward_ssh_agent] == true
|
201
|
+
|
202
|
+
host['ssh'] = host['ssh'].merge(ssh_config)
|
203
|
+
host['user'] = user
|
225
204
|
end
|
226
205
|
|
227
206
|
def initialize(vagrant_hosts, options)
|
228
207
|
require 'tempfile'
|
229
208
|
@options = options
|
230
209
|
@logger = options[:logger]
|
231
|
-
@temp_files = []
|
232
210
|
@hosts = vagrant_hosts
|
233
|
-
@vagrant_path = File.expand_path(File.join(
|
234
|
-
FileUtils.mkdir_p(@vagrant_path)
|
211
|
+
@vagrant_path = File.expand_path(File.join('.vagrant', 'beaker_vagrant_files', 'beaker_' + File.basename(options[:hosts_file])))
|
235
212
|
@vagrant_file = File.expand_path(File.join(@vagrant_path, "Vagrantfile"))
|
236
213
|
@vagrant_env = { "RUBYLIB" => "", "RUBYOPT" => "" }
|
237
214
|
end
|
238
215
|
|
239
216
|
def configure(opts = {})
|
240
|
-
|
241
|
-
|
217
|
+
unless @options[:provision]
|
218
|
+
unless File.file?(@vagrant_file)
|
242
219
|
raise "Beaker is configured with provision = false but no vagrant file was found at #{@vagrant_file}. You need to enable provision"
|
243
220
|
end
|
244
221
|
|
245
|
-
@hosts.each do |host|
|
246
|
-
host[:ip] = get_ip_from_vagrant_file(host.name)
|
247
|
-
end
|
248
|
-
|
249
222
|
set_all_ssh_config
|
250
223
|
end
|
251
224
|
super
|
252
225
|
end
|
253
226
|
|
254
227
|
def provision(provider = nil)
|
228
|
+
FileUtils.mkdir_p(@vagrant_path)
|
229
|
+
|
255
230
|
#setting up new vagrant hosts
|
256
231
|
#make sure that any old boxes are dead dead dead
|
257
232
|
begin
|
@@ -281,9 +256,6 @@ module Beaker
|
|
281
256
|
|
282
257
|
def cleanup
|
283
258
|
@logger.debug "removing temporary ssh-config files per-vagrant box"
|
284
|
-
@temp_files.each do |f|
|
285
|
-
f.close()
|
286
|
-
end
|
287
259
|
@logger.notify "Destroying vagrant boxes"
|
288
260
|
vagrant_cmd("destroy --force")
|
289
261
|
FileUtils.rm_rf(@vagrant_path)
|
@@ -303,7 +275,7 @@ module Beaker
|
|
303
275
|
end
|
304
276
|
}
|
305
277
|
rescue => e
|
306
|
-
if e =~ /WinRM/m
|
278
|
+
if e.to_s =~ /WinRM/m
|
307
279
|
sleep(10)
|
308
280
|
|
309
281
|
retry if (retries += 1) < 6
|
@@ -339,5 +311,11 @@ module Beaker
|
|
339
311
|
end
|
340
312
|
end
|
341
313
|
end
|
314
|
+
|
315
|
+
private
|
316
|
+
|
317
|
+
def set_host_default_ip(host)
|
318
|
+
host['ip'] ||= randip(host.host_hash[:hypervisor]) # use the existing ip, otherwise default to a random ip
|
319
|
+
end
|
342
320
|
end
|
343
321
|
end
|
@@ -1,18 +1,14 @@
|
|
1
1
|
require 'beaker/hypervisor/vagrant'
|
2
2
|
|
3
3
|
class Beaker::VagrantLibvirt < Beaker::Vagrant
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
class << self
|
8
|
-
attr_reader :memory
|
9
|
-
end
|
4
|
+
def initialize(*)
|
5
|
+
super
|
10
6
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
# This needs to be unique for every system with the same hostname but does
|
8
|
+
# not affect VirtualBox
|
9
|
+
vagrant_path_digest = Digest::SHA256.hexdigest(@vagrant_path)
|
10
|
+
@vagrant_path += '_' + vagrant_path_digest[0..2] + vagrant_path_digest[-3..-1]
|
11
|
+
@vagrant_file = File.expand_path(File.join(@vagrant_path, "Vagrantfile"))
|
16
12
|
end
|
17
13
|
|
18
14
|
def provision(provider = 'libvirt')
|
@@ -24,19 +20,19 @@ class Beaker::VagrantLibvirt < Beaker::Vagrant
|
|
24
20
|
" node.cpus = #{cpus(host, options)}\n" +
|
25
21
|
" node.memory = #{memsize(host, options)}\n" +
|
26
22
|
" node.qemu_use_session = false\n" +
|
27
|
-
|
23
|
+
build_options(options).join("\n") + "\n" +
|
28
24
|
" end\n"
|
29
25
|
end
|
30
26
|
|
31
|
-
def self.
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
27
|
+
def self.build_options(options)
|
28
|
+
return [] unless options['libvirt']
|
29
|
+
|
30
|
+
options['libvirt'].map { |k, v| " node.#{k} = '#{v}'" }
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def set_host_default_ip(host)
|
36
|
+
# In vagrant-libvirt hosts get a management IP, no need for a default
|
41
37
|
end
|
42
38
|
end
|