vagrant-libvirt 0.9.0 → 0.10.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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +51 -2079
  3. data/lib/vagrant-libvirt/action/create_domain.rb +39 -4
  4. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +1 -1
  5. data/lib/vagrant-libvirt/action/create_networks.rb +3 -3
  6. data/lib/vagrant-libvirt/action/destroy_domain.rb +1 -1
  7. data/lib/vagrant-libvirt/action/destroy_networks.rb +1 -1
  8. data/lib/vagrant-libvirt/action/handle_box_image.rb +1 -1
  9. data/lib/vagrant-libvirt/action/package_domain.rb +1 -5
  10. data/lib/vagrant-libvirt/action/remove_libvirt_image.rb +3 -1
  11. data/lib/vagrant-libvirt/action/resolve_disk_settings.rb +15 -8
  12. data/lib/vagrant-libvirt/action/snapshot_delete.rb +26 -0
  13. data/lib/vagrant-libvirt/action/snapshot_restore.rb +22 -0
  14. data/lib/vagrant-libvirt/action/snapshot_save.rb +27 -0
  15. data/lib/vagrant-libvirt/action/start_domain.rb +43 -14
  16. data/lib/vagrant-libvirt/action.rb +49 -1
  17. data/lib/vagrant-libvirt/cap/snapshots.rb +12 -0
  18. data/lib/vagrant-libvirt/cap/synced_folder_9p.rb +4 -4
  19. data/lib/vagrant-libvirt/cap/synced_folder_virtiofs.rb +4 -4
  20. data/lib/vagrant-libvirt/config.rb +101 -6
  21. data/lib/vagrant-libvirt/driver.rb +108 -46
  22. data/lib/vagrant-libvirt/errors.rb +23 -3
  23. data/lib/vagrant-libvirt/plugin.rb +7 -3
  24. data/lib/vagrant-libvirt/provider.rb +1 -1
  25. data/lib/vagrant-libvirt/templates/domain.xml.erb +30 -4
  26. data/lib/vagrant-libvirt/util/byte_number.rb +0 -1
  27. data/lib/vagrant-libvirt/util/compat.rb +23 -0
  28. data/lib/vagrant-libvirt/util/unindent.rb +7 -0
  29. data/lib/vagrant-libvirt/version +1 -1
  30. data/locales/en.yml +24 -2
  31. data/spec/acceptance/additional_storage_spec.rb +32 -0
  32. data/spec/acceptance/package_domain_spec.rb +90 -0
  33. data/spec/acceptance/provider_settings_spec.rb +54 -0
  34. data/spec/acceptance/simple_vm_provision_via_shell_spec.rb +31 -0
  35. data/spec/acceptance/snapshots_spec.rb +41 -0
  36. data/spec/acceptance/support-skeletons/package_complex/Vagrantfile.testbox +14 -0
  37. data/spec/acceptance/support-skeletons/package_complex/scripts/sysprep.sh +32 -0
  38. data/spec/acceptance/support-skeletons/package_simple/Vagrantfile.testbox +10 -0
  39. data/spec/acceptance/two_disks_spec.rb +29 -0
  40. data/spec/acceptance/use_qemu_agent_for_connectivity_spec.rb +35 -0
  41. data/spec/spec_helper.rb +3 -0
  42. data/spec/support/acceptance/configuration.rb +21 -0
  43. data/spec/support/acceptance/context.rb +70 -0
  44. data/spec/support/acceptance/isolated_environment.rb +41 -0
  45. data/spec/support/libvirt_acceptance_context.rb +64 -0
  46. data/spec/support/sharedcontext.rb +1 -0
  47. data/spec/unit/action/create_domain_spec/sysinfo.xml +66 -0
  48. data/spec/unit/action/create_domain_spec/sysinfo_only_required.xml +49 -0
  49. data/spec/unit/action/create_domain_spec.rb +82 -0
  50. data/spec/unit/action/forward_ports_spec.rb +0 -1
  51. data/spec/unit/action/handle_box_image_spec.rb +18 -1
  52. data/spec/unit/action/remove_libvirt_image_spec.rb +43 -0
  53. data/spec/unit/action/resolve_disk_settings_spec.rb +24 -0
  54. data/spec/unit/action/start_domain_spec/clock_timer_removed.xml +38 -0
  55. data/spec/unit/action/start_domain_spec/clock_timer_rtc_tsc.xml +39 -0
  56. data/spec/unit/action/start_domain_spec/nvram_domain_other_setting.xml +2 -2
  57. data/spec/unit/action/start_domain_spec.rb +72 -30
  58. data/spec/unit/action_spec.rb +88 -0
  59. data/spec/unit/cap/synced_folder_9p_spec.rb +120 -0
  60. data/spec/unit/cap/synced_folder_virtiofs_spec.rb +120 -0
  61. data/spec/unit/config_spec.rb +133 -6
  62. data/spec/unit/driver_spec.rb +1 -1
  63. data/spec/unit/plugin_spec.rb +42 -0
  64. data/spec/unit/templates/domain_all_settings.xml +13 -4
  65. data/spec/unit/templates/domain_scsi_bus_storage.xml +44 -0
  66. data/spec/unit/templates/domain_scsi_device_storage.xml +44 -0
  67. data/spec/unit/templates/domain_scsi_multiple_controllers_storage.xml +130 -0
  68. data/spec/unit/templates/domain_spec.rb +105 -21
  69. data/spec/unit/util/byte_number_spec.rb +1 -1
  70. metadata +155 -87
  71. data/spec/unit/provider_spec.rb +0 -11
data/locales/en.yml CHANGED
@@ -16,7 +16,7 @@ en:
16
16
  Created volume larger than box defaults, will require manual resizing of
17
17
  filesystems to utilize.
18
18
  box_version_missing: |-
19
- No verison detected for %{name}, using timestamp to watch for modifications. Consider
19
+ No version detected for %{name}, using timestamp to watch for modifications. Consider
20
20
  generating a local metadata for the box with a version to allow better handling.
21
21
  See https://www.vagrantup.com/docs/boxes/format#box-metadata for further details.
22
22
  uploading_volume: |-
@@ -25,6 +25,8 @@ en:
25
25
  Creating image (snapshot of base box volume).
26
26
  removing_domain_volume: |-
27
27
  Removing image (snapshot of base box volume).
28
+ updating_domain: |-
29
+ Updating domain definition due to configuration change
28
30
  starting_domain: |-
29
31
  Starting domain.
30
32
  terminating: |-
@@ -138,7 +140,7 @@ en:
138
140
  Error while creating a storage pool volume: %{error_message}
139
141
  fog_create_domain_volume_error: |-
140
142
  Error while creating volume for domain: %{error_message}
141
- fog_create_server_error: |-
143
+ create_server_error: |-
142
144
  Error while creating domain: %{error_message}
143
145
  domain_name_exists: |-
144
146
  Name `%{domain_name}` of domain about to create is already taken. Please try to run
@@ -183,6 +185,16 @@ en:
183
185
  management_network_required: |-
184
186
  Management network can't be disabled when VM use box.
185
187
  Please fix your configuration and run vagrant again.
188
+ snapshot_deletion_error: |-
189
+ Error while deleting snapshot: %{error_message}.
190
+ snapshot_missing: |-
191
+ Snapshot not found: %{error_message}.
192
+ snapshot_list_error: |-
193
+ Cannot list snapshots: %{error_message}.
194
+ snapshot_creation_error: |-
195
+ Cannot create snapshot(s): %{error_message}.
196
+ snapshot_reversion_error: |-
197
+ Cannot revert snapshot(s): %{error_message}.
186
198
  serial_cannot_create_path_error: |-
187
199
  Error creating path for serial port output log: %{path}
188
200
 
@@ -202,3 +214,13 @@ en:
202
214
  preparing: |-
203
215
  The vagrant machine is being prepared for creation, please wait for
204
216
  it to reach a steady state before issuing commands on it.
217
+
218
+ cap:
219
+ virtiofs:
220
+ preparing: Configuring virtiofs devices for shared folders...
221
+ mounting: Mounting virtiofs shared folders...
222
+ cleanup: Removing virtiofs devices for shared folders...
223
+ 9p:
224
+ preparing: Configuring 9p devices for shared folders...
225
+ mounting: Mounting 9p shared folders...
226
+ cleanup: Removing 9p devices for shared folders...
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'additional storage configured', acceptance: true do
6
+ include_context 'libvirt_acceptance'
7
+
8
+ before do
9
+ environment.skeleton('additional_storage')
10
+ end
11
+
12
+ after do
13
+ assert_execute('vagrant', 'destroy', '--force')
14
+ end
15
+
16
+ it 'should succeed' do
17
+ status('Test: machine is created successfully')
18
+ result = environment.execute('vagrant', 'up')
19
+ expect(result).to exit_with(0)
20
+
21
+ status('Test: additional storage configured')
22
+ expect(result.stdout).to match(/\(vda\).*work_default.img/)
23
+ expect(result.stdout).to match(/\(vdb\).*work_default-vdb\.qcow2/)
24
+
25
+ status('Test: reload handles additional storage correctly')
26
+ result = environment.execute('vagrant', 'reload')
27
+ expect(result).to exit_with(0)
28
+
29
+ status('Test: additional storage reported correctly')
30
+ expect(result.stdout).to match(/\(vdb\).*work_default-vdb\.qcow2/)
31
+ end
32
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'package domain', acceptance: true do
6
+ include_context 'libvirt_acceptance'
7
+
8
+ before(:all) do
9
+ expect(Vagrant::Util::Which.which('virt-sysprep')).to be_truthy,
10
+ 'packaging tests require virt-sysprep, please install'
11
+ expect(Vagrant::Util::Which.which('virt-sparsify')).to be_truthy,
12
+ 'packaging tests require virt-sparsify, please install'
13
+
14
+ result = (File.exist?('C:\\') ? `dir /-C #{Dir.tmpdir}` : `df #{Dir.tmpdir}`).split("\n").last
15
+ expect(result.split[3].to_i).to be > 6 * 1024 * 1024,
16
+ "packaging tests require more than 6GiB of space under #{Dir.tmpdir}"
17
+ end
18
+
19
+ after(:each) do
20
+ assert_execute('vagrant', 'destroy', '--force')
21
+ end
22
+
23
+ let(:testbox_envvars) { { VAGRANT_VAGRANTFILE: 'Vagrantfile.testbox' } }
24
+
25
+ context 'simple' do
26
+ before do
27
+ environment.skeleton('package_simple')
28
+ end
29
+
30
+ after do
31
+ result = environment.execute('vagrant', 'destroy', '--force', extra_env: testbox_envvars)
32
+ expect(result).to exit_with(0)
33
+
34
+ assert_execute('vagrant', 'box', 'remove', '--force', 'test-package-simple-domain')
35
+ end
36
+
37
+ it 'should succeed' do
38
+ status('Test: machine is created successfully')
39
+ expect(environment.execute('vagrant', 'up')).to exit_with(0)
40
+
41
+ status('Test: package machine successfully')
42
+ expect(environment.execute('vagrant', 'package')).to exit_with(0)
43
+
44
+ status('Test: add packaged box')
45
+ expect(environment.execute(
46
+ 'vagrant', 'box', 'add', '--force', '--name', 'test-package-simple-domain', 'package.box'
47
+ )).to exit_with(0)
48
+
49
+ status('Test: machine from packaged box is created successfully')
50
+ result = environment.execute('vagrant', 'up', extra_env: testbox_envvars)
51
+ expect(result).to exit_with(0)
52
+ expect(result.stdout).to match(/test-package-complex-domain/)
53
+ end
54
+ end
55
+
56
+ context 'complex' do
57
+ before do
58
+ environment.skeleton('package_complex')
59
+ extra_env.merge!(
60
+ {
61
+ VAGRANT_LIBVIRT_VIRT_SYSPREP_OPERATIONS: 'defaults,-ssh-userdir,customize',
62
+ VAGRANT_LIBVIRT_VIRT_SYSPREP_OPTIONS: '--run $(pwd)/scripts/sysprep.sh',
63
+ }
64
+ )
65
+ end
66
+
67
+ after do
68
+ expect(environment.execute('vagrant', 'destroy', '--force', extra_env: testbox_envvars)).to exit_with(0)
69
+ assert_execute('vagrant', 'box', 'remove', '--force', 'test-package-complex-domain')
70
+ end
71
+
72
+ it 'should succeed' do
73
+ status('Test: machine is created successfully')
74
+ expect(environment.execute('vagrant', 'up')).to exit_with(0)
75
+
76
+ status('Test: package machine successfully')
77
+ expect(environment.execute('vagrant', 'package')).to exit_with(0)
78
+
79
+ status('Test: add packaged box')
80
+ expect(environment.execute(
81
+ 'vagrant', 'box', 'add', '--force', '--name', 'test-package-complex-domain', 'package.box'
82
+ )).to exit_with(0)
83
+
84
+ status('Test: machine from packaged box is created successfully')
85
+ result = environment.execute('vagrant', 'up', extra_env: testbox_envvars)
86
+ expect(result).to exit_with(0)
87
+ expect(result.stdout).to match(/test-package-complex-domain/)
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'provider settings', acceptance: true do
6
+ include_context 'libvirt_acceptance'
7
+
8
+ after do
9
+ assert_execute('vagrant', 'destroy', '--force')
10
+ end
11
+
12
+ context 'with defaults' do
13
+ before do
14
+ environment.skeleton('default_settings')
15
+ end
16
+
17
+ it 'should succeed' do
18
+ status('Test: machine is created successfully')
19
+ result = environment.execute('vagrant', 'up')
20
+ expect(result).to exit_with(0)
21
+
22
+ status('Test: CPU matches default')
23
+ expect(result.stdout).to match(/Cpus:\s+1$/)
24
+
25
+ status('Test: memory matches default')
26
+ expect(result.stdout).to match(/Memory:\s+512M/)
27
+
28
+ status('Test: default prefix is used')
29
+ expect(result.stdout).to match(/Name:\s+work_default$/)
30
+ end
31
+ end
32
+
33
+ context 'with modified config' do
34
+ before do
35
+ environment.skeleton('adjusted_settings')
36
+ end
37
+
38
+ it 'should succeed' do
39
+ status('Test: machine is created successfully')
40
+ result = environment.execute('vagrant', 'up')
41
+ expect(result).to exit_with(0)
42
+
43
+ status('Test: CPUs are changed')
44
+ expect(result.stdout).to match(/Cpus:\s+2$/)
45
+
46
+ status('Test: memory is changed')
47
+ expect(result.stdout).to match(/Memory:\s+1000M$/)
48
+
49
+ status('Test: default prefix is changed')
50
+ expect(result.stdout).to match(/Name:\s+changed_default_prefixdefault$/)
51
+ expect(result.stdout).to match(/\(vda\).*changed_default_prefixdefault\.img/)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'simple vm provision via shell', acceptance: true do
6
+ include_context 'libvirt_acceptance'
7
+
8
+ before do
9
+ environment.skeleton('simple_vm_provision')
10
+ end
11
+
12
+ after do
13
+ assert_execute('vagrant', 'destroy', '--force')
14
+ end
15
+
16
+ it 'should succeed' do
17
+ status('Test: machine is created successfully')
18
+ result = environment.execute('vagrant', 'up')
19
+ expect(result).to exit_with(0)
20
+
21
+ status('Test: provision script executed')
22
+ expect(result.stdout).to match(/Hello, World/)
23
+
24
+ status('Test: reload')
25
+ result = environment.execute('vagrant', 'reload')
26
+ expect(result).to exit_with(0)
27
+
28
+ status('Test: provision checked if already executed')
29
+ expect(result.stdout).to match(/Machine already provisioned/)
30
+ end
31
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'snapshots', acceptance: true do
6
+ include_context 'libvirt_acceptance'
7
+
8
+ after(:each) do
9
+ assert_execute('vagrant', 'destroy', '--force')
10
+ end
11
+
12
+ before do
13
+ environment.skeleton('snapshots')
14
+ end
15
+
16
+ it 'should succeed' do
17
+ status('Test: machine is created successfully')
18
+ expect(environment.execute('vagrant', 'up')).to exit_with(0)
19
+
20
+ status('Test: add test file')
21
+ expect(environment.execute('vagrant', 'ssh', '--', '-t', 'touch a.txt')).to exit_with(0)
22
+
23
+ status('Test: create snapshot')
24
+ expect(environment.execute('vagrant', 'snapshot', 'save', 'default', 'test')).to exit_with(0)
25
+
26
+ status('Test: modify files')
27
+ expect(environment.execute('vagrant', 'ssh', '--', '-t', 'rm a.txt')).to exit_with(0)
28
+ expect(environment.execute('vagrant', 'ssh', '--', '-t', 'ls a.txt')).to exit_with(1)
29
+ expect(environment.execute('vagrant', 'ssh', '--', '-t', 'touch b.txt')).to exit_with(0)
30
+
31
+ status('Test: restore snapshot')
32
+ expect(environment.execute('vagrant', 'snapshot', 'restore', 'test')).to exit_with(0)
33
+
34
+ status('Test: files are as expected')
35
+ expect(environment.execute('vagrant', 'ssh', '--', '-t', 'ls a.txt')).to exit_with(0)
36
+ expect(environment.execute('vagrant', 'ssh', '--', '-t', 'ls b.txt')).to exit_with(1)
37
+
38
+ status('Test: snapshot removal works')
39
+ expect(environment.execute('vagrant', 'snapshot', 'delete', 'test')).to exit_with(0)
40
+ end
41
+ end
@@ -0,0 +1,14 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant.configure("2") do |config|
5
+ config.vm.box = "test-package-complex-domain"
6
+ config.vm.define 'package-complex'
7
+ config.vm.synced_folder ".", "/vagrant", disabled: true
8
+
9
+ config.vm.provider :libvirt do |libvirt|
10
+ libvirt.driver = "qemu"
11
+ libvirt.cpus = 2
12
+ libvirt.memory = 2048
13
+ end
14
+ end
@@ -0,0 +1,32 @@
1
+ #!/bin/sh -eux
2
+
3
+ # consider purging any packages you don't need here
4
+
5
+ echo "autoremoving packages and cleaning apt data"
6
+ apt-get -y autoremove;
7
+ apt-get -y clean;
8
+
9
+ # repeat what machine-ids does in sysprep as this script needs to run via customize
10
+ # which has a bug resulting in the machine-ids being regenerated
11
+
12
+ if [ -f /etc/machine-id ]
13
+ then
14
+ truncate --size=0 /etc/machine-id
15
+ fi
16
+
17
+ if [ -f /var/lib/dbus/machine-id ]
18
+ then
19
+ truncate --size=0 /run/machine-id
20
+ fi
21
+
22
+ echo "remove /var/cache"
23
+ find /var/cache -type f -exec rm -rf {} \;
24
+
25
+ echo "force a new random seed to be generated"
26
+ rm -f /var/lib/systemd/random-seed
27
+
28
+ # for debian based systems ensure host keys regenerated on boot
29
+ if [ -e /usr/sbin/dpkg-reconfigure ]
30
+ then
31
+ printf "@reboot root command bash -c 'export PATH=$PATH:/usr/sbin ; export DEBIAN_FRONTEND=noninteractive ; export DEBCONF_NONINTERACTIVE_SEEN=true ; /usr/sbin/dpkg-reconfigure openssh-server &>/dev/null ; /bin/systemctl restart ssh.service ; rm --force /etc/cron.d/keys'\n" > /etc/cron.d/keys
32
+ fi
@@ -0,0 +1,10 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant.configure("2") do |config|
5
+ config.vm.box = "test-package-simple-domain"
6
+ config.vm.define 'package-simple'
7
+ config.ssh.shell = "/bin/sh"
8
+ config.ssh.insert_key = false
9
+ config.vm.synced_folder ".", "/vagrant", disabled: true
10
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'handle two disk machine', acceptance: true do
6
+ include_context 'libvirt_acceptance'
7
+
8
+ after do
9
+ assert_execute('vagrant', 'destroy', '--force')
10
+ end
11
+
12
+ before do
13
+ environment.skeleton('two_disks')
14
+ environment.execute(File.expand_path('../../tools/create_box_with_two_disks.sh', __dir__),
15
+ environment.homedir.to_s, 'vagrant')
16
+ end
17
+
18
+ it 'should succeed' do
19
+ status('Test: machine is created successfully')
20
+ result = environment.execute('vagrant', 'up')
21
+ expect(result).to exit_with(0)
22
+
23
+ status('Test: disk one referenced')
24
+ expect(result.stdout).to match(/Image\(vda\):.*work_default.img, virtio, 2G/)
25
+
26
+ status('Test: disk two referenced')
27
+ expect(result.stdout).to match(/Image\(vdb\):.*work_default_1.img, virtio, 10G/)
28
+ end
29
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'use qemu agent to determine machine private address', acceptance: true do
6
+ include_context 'libvirt_acceptance'
7
+
8
+ before do
9
+ environment.skeleton('qemu_agent')
10
+ end
11
+
12
+ after do
13
+ assert_execute('vagrant', 'destroy', '--force')
14
+ end
15
+
16
+ it 'should succeed' do
17
+ status('Test: machine is created successfully')
18
+ result = environment.execute('vagrant', 'up')
19
+ expect(result).to exit_with(0)
20
+
21
+ # extract SSH IP address emitted as it should be the private network since
22
+ # the mgmt network has not been attached
23
+ hostname = result.stdout.each_line.find { |line| line.include?('SSH address:') }
24
+ expect(hostname).to_not be_nil
25
+ ip_address = hostname.strip.split.last.split(':').first
26
+ # default private network for vagrant-libvirt unless explicitly configured
27
+ expect(IPAddr.new('172.28.128.0/255.255.255.0')).to include(IPAddr.new(ip_address))
28
+
29
+ # ssh'ing successfully means that the private network is accessible
30
+ status('Test: machine private network is accessible')
31
+ result = environment.execute('vagrant', 'ssh', '-c', 'echo "hello, world"')
32
+ expect(result).to exit_with(0)
33
+ expect(result.stdout).to match(/hello, world/)
34
+ end
35
+ end
data/spec/spec_helper.rb CHANGED
@@ -55,4 +55,7 @@ RSpec.configure do |config|
55
55
  config.mock_with :rspec do |mocks|
56
56
  mocks.verify_partial_doubles = true
57
57
  end
58
+
59
+ # don't run acceptance tests by default
60
+ config.filter_run_excluding :acceptance => true
58
61
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'vagrant-spec/acceptance/configuration'
4
+
5
+ module VagrantPlugins
6
+ module VagrantLibvirt
7
+ module Spec
8
+ module Acceptance
9
+ class Configuration < Vagrant::Spec::Acceptance::Configuration
10
+ attr_accessor :clean_on_fail
11
+
12
+ def initialize
13
+ super
14
+
15
+ @clean_on_fail = true
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'vagrant-spec/acceptance/configuration'
4
+ require "vagrant-spec/acceptance/rspec/matcher_exit_with"
5
+
6
+ require_relative 'isolated_environment'
7
+
8
+ shared_context "acceptance" do
9
+ # Setup the environment so that we have an isolated area
10
+ # to run Vagrant. We do some configuration here as well in order
11
+ # to replace "vagrant" with the proper path to Vagrant as well
12
+ # as tell the isolated environment about custom environmental
13
+ # variables to pass in.
14
+ let!(:environment) { new_environment }
15
+
16
+ let(:config) { Vagrant::Spec::Acceptance::Configuration.new }
17
+
18
+ let(:extra_env) { {} }
19
+
20
+ # The skeleton paths that will be used to configure environments.
21
+ let(:skeleton_paths) do
22
+ root = Vagrant::Spec.source_root.join("acceptance", "support-skeletons")
23
+ config.skeleton_paths.dup.unshift(root)
24
+ end
25
+
26
+ after(:each) do |example|
27
+ if example.exception.nil? || config.clean_on_fail
28
+ environment.close
29
+ else
30
+ example.reporter.message("Temporary work and home dirs (#{environment.workdir} and #{environment.homedir}) not removed to allow debug")
31
+ end
32
+ end
33
+
34
+ # Creates a new isolated environment instance each time it is called.
35
+ #
36
+ # @return [Acceptance::IsolatedEnvironment]
37
+ def new_environment(env=nil)
38
+ apps = { "vagrant" => config.vagrant_path }
39
+ env = config.env.merge(env || {})
40
+ env.merge!(extra_env)
41
+
42
+ VagrantPlugins::VagrantLibvirt::Spec::AcceptanceIsolatedEnvironment.new(
43
+ apps: apps,
44
+ env: env,
45
+ skeleton_paths: skeleton_paths,
46
+ )
47
+ end
48
+
49
+ # Executes the given command in the context of the isolated environment.
50
+ #
51
+ # @return [Object]
52
+ def execute(*args, env: nil, log: true, &block)
53
+ env ||= environment
54
+ status("Execute: #{args.join(" ")}") if log
55
+ env.execute(*args, &block)
56
+ end
57
+
58
+ # This method is an assertion helper for asserting that a process
59
+ # succeeds. It is a wrapper around `execute` that asserts that the
60
+ # exit status was successful.
61
+ def assert_execute(*args, env: nil, &block)
62
+ result = execute(*args, env: env, &block)
63
+ expect(result).to exit_with(0)
64
+ result
65
+ end
66
+
67
+ def status(message)
68
+ RSpec.world.reporter.message(message)
69
+ end
70
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'vagrant-spec/acceptance/isolated_environment'
4
+ require 'vagrant-spec/subprocess'
5
+ require 'vagrant-spec/which'
6
+
7
+ module VagrantPlugins
8
+ module VagrantLibvirt
9
+ module Spec
10
+ class AcceptanceIsolatedEnvironment < Vagrant::Spec::AcceptanceIsolatedEnvironment
11
+ # Executes a command in the context of this isolated environment.
12
+ # Any command executed will therefore see our temporary directory
13
+ # as the home directory.
14
+ #
15
+ # If the command has been defined with a special path, then the
16
+ # command will be replaced with the full path to that command.
17
+ def execute(command, *args, **options)
18
+ # Create the command
19
+ command = replace_command(command)
20
+ # Use provided command if it is a valid executable
21
+ if !File.executable?(command)
22
+ # If it's not a valid executable, search for vagrant
23
+ command = Vagrant::Spec::Which.which(command)
24
+ end
25
+
26
+ # Build up the options
27
+ options[:env] = @env.merge(options.delete(:extra_env) || {})
28
+ options[:notify] = [:stdin, :stderr, :stdout]
29
+ options[:workdir] = @workdir.to_s
30
+
31
+ # Execute, logging out the stdout/stderr as we get it
32
+ @logger.info("Executing: #{[command].concat(args).inspect}")
33
+ Vagrant::Spec::Subprocess.execute(command, *args, **options) do |type, data|
34
+ @logger.debug("#{type}: #{data}") if type == :stdout || type == :stderr
35
+ yield type, data if block_given?
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'acceptance/context'
4
+
5
+ FALSEY_VALUES = %w[f false no n 0].freeze
6
+
7
+ shared_context 'libvirt_acceptance' do
8
+ include_context 'acceptance'
9
+
10
+ # The skeleton paths that will be used to configure environments.
11
+ let(:skeleton_paths) do
12
+ root = File.expand_path('../acceptance/support-skeletons', __dir__)
13
+ config.skeleton_paths.dup.unshift(root)
14
+ end
15
+
16
+ let(:config) do
17
+ c = VagrantPlugins::VagrantLibvirt::Spec::Acceptance::Configuration.new
18
+ c.clean_on_fail = FALSEY_VALUES.include?(ENV.fetch('VAGRANT_SPEC_SKIP_CLEANUP', 'false').to_s.downcase)
19
+
20
+ c
21
+ end
22
+
23
+ before(:each) do
24
+ # allow execution environment to cache boxes used
25
+ symlink_boxes(ENV.fetch('VAGRANT_HOME', nil), environment)
26
+ end
27
+
28
+ after(:each) do
29
+ # ensure we remove the symlink
30
+ boxes_symlink = File.join(environment.homedir, 'boxes')
31
+ File.delete(boxes_symlink) if File.symlink?(boxes_symlink)
32
+ end
33
+
34
+ around do |example|
35
+ vagrant_cwd = ENV.delete('VAGRANT_CWD')
36
+ env_provider_before = ENV.fetch('VAGRANT_DEFAULT_PROVIDER', nil)
37
+ ENV['VAGRANT_DEFAULT_PROVIDER'] = 'libvirt'
38
+
39
+ begin
40
+ example.run
41
+ ensure
42
+ ENV['VAGRANT_CWD'] = vagrant_cwd if vagrant_cwd
43
+ if env_provider_before.nil?
44
+ ENV.delete('VAGRANT_DEFAULT_PROVIDER')
45
+ else
46
+ ENV['VAGRANT_DEFAULT_PROVIDER'] = env_provider_before
47
+ end
48
+ end
49
+ end
50
+
51
+ def duplicate_environment(env, *args)
52
+ dup_env = new_environment(*args)
53
+ symlink_boxes(env.homedir, dup_env)
54
+
55
+ dup_env
56
+ end
57
+
58
+ def symlink_boxes(vagrant_home, target_env)
59
+ return if vagrant_home.nil?
60
+
61
+ # allow use the same boxes location as source environment
62
+ File.symlink File.realpath(File.join(vagrant_home, 'boxes')), File.join(target_env.homedir, 'boxes')
63
+ end
64
+ end
@@ -37,5 +37,6 @@ shared_context 'unit' do
37
37
  before (:each) do
38
38
  allow(machine).to receive(:guest).and_return(guest)
39
39
  allow(machine).to receive(:communicate).and_return(communicator)
40
+ allow(machine).to receive(:ui).and_return(ui)
40
41
  end
41
42
  end