vagrant-libvirt 0.5.3 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +110 -18
  3. data/lib/vagrant-libvirt/action/clean_machine_folder.rb +2 -0
  4. data/lib/vagrant-libvirt/action/create_domain.rb +8 -1
  5. data/lib/vagrant-libvirt/action/create_domain_volume.rb +5 -0
  6. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +8 -2
  7. data/lib/vagrant-libvirt/action/create_networks.rb +12 -8
  8. data/lib/vagrant-libvirt/action/destroy_domain.rb +2 -0
  9. data/lib/vagrant-libvirt/action/destroy_networks.rb +2 -0
  10. data/lib/vagrant-libvirt/action/forward_ports.rb +7 -5
  11. data/lib/vagrant-libvirt/action/halt_domain.rb +4 -34
  12. data/lib/vagrant-libvirt/action/handle_box_image.rb +22 -13
  13. data/lib/vagrant-libvirt/action/handle_storage_pool.rb +7 -1
  14. data/lib/vagrant-libvirt/action/is_created.rb +2 -0
  15. data/lib/vagrant-libvirt/action/is_running.rb +2 -0
  16. data/lib/vagrant-libvirt/action/is_suspended.rb +2 -0
  17. data/lib/vagrant-libvirt/action/message_already_created.rb +2 -0
  18. data/lib/vagrant-libvirt/action/message_not_created.rb +2 -0
  19. data/lib/vagrant-libvirt/action/message_not_running.rb +2 -0
  20. data/lib/vagrant-libvirt/action/message_not_suspended.rb +2 -0
  21. data/lib/vagrant-libvirt/action/message_will_not_destroy.rb +2 -0
  22. data/lib/vagrant-libvirt/action/package_domain.rb +133 -68
  23. data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +2 -0
  24. data/lib/vagrant-libvirt/action/prepare_nfs_valid_ids.rb +2 -0
  25. data/lib/vagrant-libvirt/action/prune_nfs_exports.rb +2 -0
  26. data/lib/vagrant-libvirt/action/read_mac_addresses.rb +2 -0
  27. data/lib/vagrant-libvirt/action/remove_libvirt_image.rb +2 -0
  28. data/lib/vagrant-libvirt/action/remove_stale_volume.rb +2 -0
  29. data/lib/vagrant-libvirt/action/resume_domain.rb +2 -0
  30. data/lib/vagrant-libvirt/action/set_boot_order.rb +2 -0
  31. data/lib/vagrant-libvirt/action/set_name_of_domain.rb +3 -1
  32. data/lib/vagrant-libvirt/action/share_folders.rb +2 -0
  33. data/lib/vagrant-libvirt/action/shutdown_domain.rb +71 -0
  34. data/lib/vagrant-libvirt/action/start_domain.rb +26 -17
  35. data/lib/vagrant-libvirt/action/suspend_domain.rb +2 -0
  36. data/lib/vagrant-libvirt/action/wait_till_up.rb +2 -0
  37. data/lib/vagrant-libvirt/action.rb +37 -12
  38. data/lib/vagrant-libvirt/cap/mount_9p.rb +2 -0
  39. data/lib/vagrant-libvirt/cap/mount_virtiofs.rb +2 -0
  40. data/lib/vagrant-libvirt/cap/nic_mac_addresses.rb +2 -0
  41. data/lib/vagrant-libvirt/cap/public_address.rb +2 -0
  42. data/lib/vagrant-libvirt/cap/synced_folder_9p.rb +5 -2
  43. data/lib/vagrant-libvirt/cap/synced_folder_virtiofs.rb +5 -2
  44. data/lib/vagrant-libvirt/config.rb +49 -25
  45. data/lib/vagrant-libvirt/driver.rb +67 -12
  46. data/lib/vagrant-libvirt/errors.rb +6 -0
  47. data/lib/vagrant-libvirt/plugin.rb +2 -0
  48. data/lib/vagrant-libvirt/provider.rb +2 -0
  49. data/lib/vagrant-libvirt/templates/domain.xml.erb +4 -2
  50. data/lib/vagrant-libvirt/templates/public_interface.xml.erb +1 -0
  51. data/lib/vagrant-libvirt/util/collection.rb +2 -0
  52. data/lib/vagrant-libvirt/util/erb_template.rb +2 -0
  53. data/lib/vagrant-libvirt/util/error_codes.rb +2 -0
  54. data/lib/vagrant-libvirt/util/network_util.rb +3 -0
  55. data/lib/vagrant-libvirt/util/nfs.rb +2 -0
  56. data/lib/vagrant-libvirt/util/storage_util.rb +1 -0
  57. data/lib/vagrant-libvirt/util/timer.rb +2 -0
  58. data/lib/vagrant-libvirt/util/ui.rb +1 -0
  59. data/lib/vagrant-libvirt/util.rb +2 -0
  60. data/lib/vagrant-libvirt/version +1 -1
  61. data/lib/vagrant-libvirt/version.rb +2 -0
  62. data/lib/vagrant-libvirt.rb +2 -0
  63. data/locales/en.yml +7 -0
  64. data/spec/spec_helper.rb +2 -0
  65. data/spec/support/binding_proc.rb +2 -0
  66. data/spec/support/environment_helper.rb +2 -0
  67. data/spec/support/libvirt_context.rb +2 -0
  68. data/spec/support/matchers/have_file_content.rb +2 -0
  69. data/spec/support/sharedcontext.rb +3 -0
  70. data/spec/support/temporary_dir.rb +12 -0
  71. data/spec/unit/action/clean_machine_folder_spec.rb +2 -0
  72. data/spec/unit/action/create_domain_spec/additional_disks_domain.xml +7 -0
  73. data/spec/unit/action/create_domain_spec/default_domain.xml +6 -0
  74. data/spec/unit/action/create_domain_spec.rb +62 -30
  75. data/spec/unit/action/create_domain_volume_spec.rb +4 -0
  76. data/spec/unit/action/destroy_domain_spec.rb +8 -2
  77. data/spec/unit/action/forward_ports_spec.rb +2 -0
  78. data/spec/unit/action/halt_domain_spec.rb +30 -57
  79. data/spec/unit/action/handle_box_image_spec.rb +36 -4
  80. data/spec/unit/action/package_domain_spec.rb +304 -0
  81. data/spec/unit/action/set_name_of_domain_spec.rb +2 -0
  82. data/spec/unit/action/shutdown_domain_spec.rb +160 -0
  83. data/spec/unit/action/start_domain_spec/existing.xml +62 -0
  84. data/spec/unit/action/start_domain_spec.rb +18 -28
  85. data/spec/unit/action/wait_till_up_spec.rb +2 -0
  86. data/spec/unit/action_spec.rb +174 -0
  87. data/spec/unit/config_spec.rb +52 -2
  88. data/spec/unit/driver_spec.rb +155 -0
  89. data/spec/unit/templates/domain_all_settings.xml +4 -0
  90. data/spec/unit/templates/domain_spec.rb +2 -0
  91. data/spec/unit/util/byte_number_spec.rb +2 -0
  92. metadata +54 -42
@@ -0,0 +1,304 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'support/sharedcontext'
5
+
6
+ require 'vagrant-libvirt/action/clean_machine_folder'
7
+
8
+ describe VagrantPlugins::ProviderLibvirt::Action::PackageDomain do
9
+ subject { described_class.new(app, env) }
10
+
11
+ include_context 'unit'
12
+ include_context 'libvirt'
13
+ include_context 'temporary_dir'
14
+
15
+ let(:libvirt_client) { double('libvirt_client') }
16
+ let(:libvirt_domain) { double('libvirt_domain') }
17
+ let(:servers) { double('servers') }
18
+ let(:volumes) { double('volumes') }
19
+ let(:metadata_file) { double('file') }
20
+ let(:vagrantfile_file) { double('file') }
21
+
22
+ describe '#call' do
23
+ before do
24
+ allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver)
25
+ .to receive(:connection).and_return(connection)
26
+ allow(connection).to receive(:client).and_return(libvirt_client)
27
+ allow(libvirt_client).to receive(:lookup_domain_by_uuid).and_return(libvirt_domain)
28
+
29
+ allow(connection).to receive(:servers).and_return(servers)
30
+ allow(servers).to receive(:get).and_return(domain)
31
+
32
+ allow(connection).to receive(:volumes).and_return(volumes)
33
+
34
+ allow(logger).to receive(:info)
35
+
36
+ env["package.directory"] = temp_dir
37
+ end
38
+
39
+ context 'with defaults' do
40
+ let(:root_disk) { double('libvirt_domain_disk') }
41
+ before do
42
+ allow(root_disk).to receive(:name).and_return('default_domain.img')
43
+ allow(domain).to receive(:volumes).and_return([root_disk])
44
+ allow(libvirt_domain).to receive(:name).and_return('default_domain')
45
+ allow(subject).to receive(:download_image).and_return(true)
46
+ end
47
+
48
+ it 'should succeed' do
49
+ expect(ui).to receive(:info).with('Packaging domain...')
50
+ expect(ui).to receive(:info).with(/Downloading default_domain.img to .*\/box.img/)
51
+ expect(ui).to receive(:info).with('Image has backing image, copying image and rebasing ...')
52
+ expect(subject).to receive(:`).with(/qemu-img info .*\/box.img | grep 'backing file:' | cut -d ':' -f2/).and_return("some image")
53
+ expect(subject).to receive(:`).with(/qemu-img rebase -p -b "" .*\/box.img/)
54
+ expect(subject).to receive(:`).with(/virt-sysprep --no-logfile --operations .* -a .*\/box.img .*/)
55
+ expect(subject).to receive(:`).with(/virt-sparsify --in-place .*\/box.img/)
56
+ expect(subject).to receive(:`).with(/qemu-img info --output=json .*\/box.img/).and_return(
57
+ { 'virtual-size': 5*1024*1024*1024 }.to_json
58
+ )
59
+ expect(File).to receive(:write).with(
60
+ /.*\/metadata.json/,
61
+ <<-EOF.unindent
62
+ {
63
+ "provider": "libvirt",
64
+ "format": "qcow2",
65
+ "virtual_size": 5
66
+ }
67
+ EOF
68
+ )
69
+ expect(File).to receive(:write).with(/.*\/Vagrantfile/, /.*/)
70
+
71
+ expect(subject.call(env)).to be_nil
72
+ end
73
+ end
74
+
75
+ context 'with nil volume' do
76
+ let(:root_disk) { double('libvirt_domain_disk') }
77
+ before do
78
+ allow(root_disk).to receive(:name).and_return('default_domain.img')
79
+ allow(domain).to receive(:volumes).and_return([nil, root_disk])
80
+ allow(libvirt_domain).to receive(:name).and_return('default_domain')
81
+ allow(subject).to receive(:download_image).and_return(true)
82
+ end
83
+
84
+ it 'should succeed' do
85
+ expect(ui).to receive(:info).with('Packaging domain...')
86
+ expect(ui).to receive(:info).with(/Downloading default_domain.img to .*\/box.img/)
87
+ expect(ui).to receive(:info).with('Image has backing image, copying image and rebasing ...')
88
+ expect(subject).to receive(:`).with(/qemu-img info .*\/box.img | grep 'backing file:' | cut -d ':' -f2/).and_return("some image")
89
+ expect(subject).to receive(:`).with(/qemu-img rebase -p -b "" .*\/box.img/)
90
+ expect(subject).to receive(:`).with(/virt-sysprep --no-logfile --operations .* -a .*\/box.img .*/)
91
+ expect(subject).to receive(:`).with(/virt-sparsify --in-place .*\/box.img/)
92
+ expect(subject).to receive(:`).with(/qemu-img info --output=json .*\/box.img/).and_return(
93
+ { 'virtual-size': 5*1024*1024*1024 }.to_json
94
+ )
95
+
96
+ expect(subject.call(env)).to be_nil
97
+ end
98
+ end
99
+
100
+ context 'when detecting the format' do
101
+ let(:root_disk) { double('libvirt_domain_disk') }
102
+ let(:disk2) { double('libvirt_additional_disk') }
103
+ let(:fake_env) { Hash.new }
104
+
105
+ before do
106
+ allow(root_disk).to receive(:name).and_return('default_domain.img')
107
+ allow(disk2).to receive(:name).and_return('disk2.img')
108
+ allow(libvirt_domain).to receive(:name).and_return('default_domain')
109
+ end
110
+
111
+ context 'with two disks' do
112
+ before do
113
+ allow(domain).to receive(:volumes).and_return([root_disk, disk2])
114
+ end
115
+
116
+ it 'should emit a warning' do
117
+ expect(ui).to receive(:info).with('Packaging domain...')
118
+ expect(ui).to receive(:warn).with(/Detected more than one volume for machine.*\n.*/)
119
+ expect(subject).to receive(:package_v1)
120
+
121
+ expect(subject.call(env)).to be_nil
122
+ end
123
+ end
124
+
125
+ context 'with format set to v1' do
126
+ before do
127
+ allow(domain).to receive(:volumes).and_return([root_disk])
128
+ stub_const("ENV", fake_env)
129
+ fake_env['VAGRANT_LIBVIRT_BOX_FORMAT_VERSION'] = "v1"
130
+ end
131
+
132
+ it 'should call v1 packaging' do
133
+ expect(ui).to receive(:info).with('Packaging domain...')
134
+ expect(subject).to receive(:package_v1)
135
+
136
+ expect(subject.call(env)).to be_nil
137
+ end
138
+ end
139
+
140
+ context 'with format set to v2' do
141
+ before do
142
+ allow(domain).to receive(:volumes).and_return([root_disk])
143
+ stub_const("ENV", fake_env)
144
+ fake_env['VAGRANT_LIBVIRT_BOX_FORMAT_VERSION'] = "v2"
145
+ end
146
+
147
+ it 'should call v1 packaging' do
148
+ expect(ui).to receive(:info).with('Packaging domain...')
149
+ expect(subject).to receive(:package_v2)
150
+
151
+ expect(subject.call(env)).to be_nil
152
+ end
153
+ end
154
+
155
+ context 'with invalid format' do
156
+ before do
157
+ allow(domain).to receive(:volumes).and_return([root_disk])
158
+ stub_const("ENV", fake_env)
159
+ fake_env['VAGRANT_LIBVIRT_BOX_FORMAT_VERSION'] = "bad format"
160
+ end
161
+
162
+ it 'should emit a warning and default to v1' do
163
+ expect(ui).to receive(:info).with('Packaging domain...')
164
+ expect(ui).to receive(:warn).with(/Unrecognized value for.*defaulting to v1/)
165
+ expect(subject).to receive(:package_v1)
166
+
167
+ expect(subject.call(env)).to be_nil
168
+ end
169
+ end
170
+ end
171
+
172
+ context 'with v2 format' do
173
+ let(:disk1) { double('libvirt_domain_disk') }
174
+ let(:disk2) { double('libvirt_additional_disk') }
175
+ let(:fake_env) { Hash.new }
176
+
177
+ before do
178
+ allow(disk1).to receive(:name).and_return('default_domain.img')
179
+ allow(disk2).to receive(:name).and_return('disk2.img')
180
+ allow(libvirt_domain).to receive(:name).and_return('default_domain')
181
+ allow(subject).to receive(:download_image).and_return(true).twice()
182
+
183
+ stub_const("ENV", fake_env)
184
+ fake_env['VAGRANT_LIBVIRT_BOX_FORMAT_VERSION'] = "v2"
185
+ end
186
+
187
+ context 'with 2 disks' do
188
+ before do
189
+ allow(domain).to receive(:volumes).and_return([disk1, disk2])
190
+ end
191
+
192
+ it 'should succeed' do
193
+ expect(ui).to receive(:info).with('Packaging domain...')
194
+ expect(ui).to receive(:info).with(/Downloading default_domain.img to .*\/box_1.img/)
195
+ expect(ui).to receive(:info).with('Image has backing image, copying image and rebasing ...')
196
+ expect(subject).to receive(:`).with(/qemu-img info .*\/box_1.img | grep 'backing file:' | cut -d ':' -f2/).and_return("some image")
197
+ expect(subject).to receive(:`).with(/qemu-img rebase -p -b "" .*\/box_1.img/)
198
+ expect(subject).to receive(:`).with(/virt-sysprep --no-logfile --operations .* -a .*\/box_1.img .*/)
199
+ expect(subject).to receive(:`).with(/virt-sparsify --in-place .*\/box_1.img/)
200
+ expect(ui).to receive(:info).with(/Downloading disk2.img to .*\/box_2.img/)
201
+ expect(ui).to receive(:info).with('Image has backing image, copying image and rebasing ...')
202
+ expect(subject).to receive(:`).with(/qemu-img info .*\/box_2.img | grep 'backing file:' | cut -d ':' -f2/).and_return("some image")
203
+ expect(subject).to receive(:`).with(/qemu-img rebase -p -b "" .*\/box_2.img/)
204
+ expect(subject).to receive(:`).with(/virt-sparsify --in-place .*\/box_2.img/)
205
+
206
+ expect(File).to receive(:write).with(
207
+ /.*\/metadata.json/,
208
+ <<-EOF.unindent.rstrip()
209
+ {
210
+ "provider": "libvirt",
211
+ "format": "qcow2",
212
+ "disks": [
213
+ {
214
+ "path": "box_1.img"
215
+ },
216
+ {
217
+ "path": "box_2.img"
218
+ }
219
+ ]
220
+ }
221
+ EOF
222
+ )
223
+ expect(File).to receive(:write).with(/.*\/Vagrantfile/, /.*/)
224
+
225
+ expect(subject.call(env)).to be_nil
226
+ end
227
+ end
228
+
229
+ context 'with 1 disk' do
230
+ before do
231
+ allow(domain).to receive(:volumes).and_return([disk1])
232
+ end
233
+
234
+ it 'should succeed' do
235
+ expect(ui).to receive(:info).with('Packaging domain...')
236
+ expect(ui).to receive(:info).with(/Downloading default_domain.img to .*\/box_1.img/)
237
+ expect(ui).to receive(:info).with('Image has backing image, copying image and rebasing ...')
238
+ expect(subject).to receive(:`).with(/qemu-img info .*\/box_1.img | grep 'backing file:' | cut -d ':' -f2/).and_return("some image")
239
+ expect(subject).to receive(:`).with(/qemu-img rebase -p -b "" .*\/box_1.img/)
240
+ expect(subject).to receive(:`).with(/virt-sysprep --no-logfile --operations .* -a .*\/box_1.img .*/)
241
+ expect(subject).to receive(:`).with(/virt-sparsify --in-place .*\/box_1.img/)
242
+
243
+ expect(File).to receive(:write).with(
244
+ /.*\/metadata.json/,
245
+ <<-EOF.unindent.rstrip()
246
+ {
247
+ "provider": "libvirt",
248
+ "format": "qcow2",
249
+ "disks": [
250
+ {
251
+ "path": "box_1.img"
252
+ }
253
+ ]
254
+ }
255
+ EOF
256
+ )
257
+ expect(File).to receive(:write).with(/.*\/Vagrantfile/, /.*/)
258
+
259
+ expect(subject.call(env)).to be_nil
260
+ end
261
+ end
262
+ end
263
+ end
264
+
265
+ describe '#vagrantfile_content' do
266
+ context 'with defaults' do
267
+ it 'should output expected content' do
268
+ expect(subject.vagrantfile_content(env)).to eq(
269
+ <<-EOF.unindent
270
+ Vagrant.configure("2") do |config|
271
+ config.vm.provider :libvirt do |libvirt|
272
+ libvirt.driver = "kvm"
273
+ end
274
+
275
+ end
276
+ EOF
277
+ )
278
+ end
279
+ end
280
+
281
+ context 'with custom user vagrantfile' do
282
+ before do
283
+ env["package.vagrantfile"] = "_Vagrantfile"
284
+ end
285
+ it 'should output Vagrantfile containing reference' do
286
+ expect(subject.vagrantfile_content(env)).to eq(
287
+ <<-EOF.unindent
288
+ Vagrant.configure("2") do |config|
289
+ config.vm.provider :libvirt do |libvirt|
290
+ libvirt.driver = "kvm"
291
+ end
292
+
293
+ # Load include vagrant file if it exists after the auto-generated
294
+ # so it can override any of the settings
295
+ include_vagrantfile = File.expand_path("../include/_Vagrantfile", __FILE__)
296
+ load include_vagrantfile if File.exist?(include_vagrantfile)
297
+
298
+ end
299
+ EOF
300
+ )
301
+ end
302
+ end
303
+ end
304
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe VagrantPlugins::ProviderLibvirt::Action::SetNameOfDomain do
@@ -0,0 +1,160 @@
1
+ require 'spec_helper'
2
+ require 'support/sharedcontext'
3
+ require 'support/libvirt_context'
4
+ require 'vagrant-libvirt/action/shutdown_domain'
5
+
6
+ describe VagrantPlugins::ProviderLibvirt::Action::StartShutdownTimer do
7
+ subject { described_class.new(app, env) }
8
+
9
+ include_context 'unit'
10
+
11
+ describe '#call' do
12
+ it 'should set shutdown_start_time' do
13
+ expect(env[:shutdown_start_time]).to eq(nil)
14
+ expect(subject.call(env)).to eq(nil)
15
+ expect(env[:shutdown_start_time]).to_not eq(nil)
16
+ end
17
+ end
18
+ end
19
+
20
+ describe VagrantPlugins::ProviderLibvirt::Action::ShutdownDomain do
21
+ subject { described_class.new(app, env, target_state, current_state) }
22
+
23
+ include_context 'unit'
24
+ include_context 'libvirt'
25
+
26
+ let(:driver) { double('driver') }
27
+ let(:libvirt_domain) { double('libvirt_domain') }
28
+ let(:servers) { double('servers') }
29
+ let(:current_state) { :running }
30
+ let(:target_state) { :shutoff }
31
+
32
+ before do
33
+ allow(machine.provider).to receive('driver').and_return(driver)
34
+ allow(driver).to receive(:created?).and_return(true)
35
+ allow(driver).to receive(:connection).and_return(connection)
36
+ end
37
+
38
+ describe '#call' do
39
+ before do
40
+ allow(connection).to receive(:servers).and_return(servers)
41
+ allow(servers).to receive(:get).and_return(domain)
42
+ allow(ui).to receive(:info).with('Attempting direct shutdown of domain...')
43
+ allow(env).to receive(:[]).and_call_original
44
+ allow(env).to receive(:[]).with(:shutdown_start_time).and_return(Time.now)
45
+ end
46
+
47
+ context "when state is shutoff" do
48
+ before do
49
+ allow(driver).to receive(:state).and_return(:shutoff)
50
+ end
51
+
52
+ it "should not shutdown" do
53
+ expect(domain).not_to receive(:shutoff)
54
+ subject.call(env)
55
+ end
56
+
57
+ it "should not print shutdown message" do
58
+ expect(ui).not_to receive(:info)
59
+ subject.call(env)
60
+ end
61
+
62
+ it "should provide a true result" do
63
+ subject.call(env)
64
+ expect(env[:result]).to be_truthy
65
+ end
66
+ end
67
+
68
+ context "when state is running" do
69
+ before do
70
+ allow(driver).to receive(:state).and_return(:running)
71
+ end
72
+
73
+ it "should shutdown" do
74
+ expect(domain).to receive(:wait_for)
75
+ expect(domain).to receive(:shutdown)
76
+ subject.call(env)
77
+ end
78
+
79
+ it "should print shutdown message" do
80
+ expect(domain).to receive(:wait_for)
81
+ expect(domain).to receive(:shutdown)
82
+ expect(ui).to receive(:info).with('Attempting direct shutdown of domain...')
83
+ subject.call(env)
84
+ end
85
+
86
+ context "when final state is not shutoff" do
87
+ before do
88
+ expect(driver).to receive(:state).and_return(:running).exactly(3).times
89
+ expect(domain).to receive(:wait_for)
90
+ expect(domain).to receive(:shutdown)
91
+ end
92
+
93
+ it "should provide a false result" do
94
+ subject.call(env)
95
+ expect(env[:result]).to be_falsey
96
+ end
97
+ end
98
+
99
+ context "when final state is shutoff" do
100
+ before do
101
+ expect(driver).to receive(:state).and_return(:running).exactly(2).times
102
+ expect(driver).to receive(:state).and_return(:shutoff).exactly(1).times
103
+ expect(domain).to receive(:wait_for)
104
+ expect(domain).to receive(:shutdown)
105
+ end
106
+
107
+ it "should provide a true result" do
108
+ subject.call(env)
109
+ expect(env[:result]).to be_truthy
110
+ end
111
+ end
112
+
113
+ context "when timeout exceeded" do
114
+ before do
115
+ expect(machine).to receive_message_chain('config.vm.graceful_halt_timeout').and_return(1)
116
+ expect(Time).to receive(:now).and_return(env[:shutdown_start_time] + 2)
117
+ expect(driver).to receive(:state).and_return(:running).exactly(1).times
118
+ expect(domain).to_not receive(:wait_for)
119
+ expect(domain).to_not receive(:shutdown)
120
+ end
121
+
122
+ it "should provide a false result" do
123
+ subject.call(env)
124
+ expect(env[:result]).to be_falsey
125
+ end
126
+ end
127
+
128
+ context "when timeout not exceeded" do
129
+ before do
130
+ expect(machine).to receive_message_chain('config.vm.graceful_halt_timeout').and_return(2)
131
+ expect(Time).to receive(:now).and_return(env[:shutdown_start_time] + 1.5)
132
+ expect(driver).to receive(:state).and_return(:running).exactly(3).times
133
+ expect(domain).to receive(:wait_for) do |time|
134
+ expect(time).to be < 1
135
+ expect(time).to be > 0
136
+ end
137
+ expect(domain).to receive(:shutdown)
138
+ end
139
+
140
+ it "should wait for the reduced time" do
141
+ subject.call(env)
142
+ expect(env[:result]).to be_falsey
143
+ end
144
+ end
145
+ end
146
+
147
+ context "when required action not run" do
148
+ before do
149
+ expect(env).to receive(:[]).with(:shutdown_start_time).and_call_original
150
+ end
151
+
152
+ it "should raise an exception" do
153
+ expect { subject.call(env) }.to raise_error(
154
+ VagrantPlugins::ProviderLibvirt::Errors::CallChainError,
155
+ /Invalid action chain, must ensure that '.*ShutdownTimer' is called prior to calling '.*ShutdownDomain'/
156
+ )
157
+ end
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,62 @@
1
+ <domain type='qemu'>
2
+ <name>vagrant-libvirt_default</name>
3
+ <uuid>881a931b-0110-4d10-81aa-47a1a19f5726</uuid>
4
+ <description>Source: /home/test/vagrant-libvirt/Vagrantfile</description>
5
+ <memory unit='KiB'>2097152</memory>
6
+ <currentMemory unit='KiB'>2097152</currentMemory>
7
+ <vcpu placement='static'>2</vcpu>
8
+ <os>
9
+ <type arch='x86_64' machine='pc-i440fx-6.0'>hvm</type>
10
+ <boot dev='hd'/>
11
+ </os>
12
+ <features>
13
+ <acpi/>
14
+ <apic/>
15
+ <pae/>
16
+ </features>
17
+ <cpu mode='host-model' check='partial'/>
18
+ <clock offset='utc'/>
19
+ <on_poweroff>destroy</on_poweroff>
20
+ <on_reboot>restart</on_reboot>
21
+ <on_crash>destroy</on_crash>
22
+ <devices>
23
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
24
+ <disk type='file' device='disk'>
25
+ <driver name='qemu' type='qcow2'/>
26
+ <source file='/var/lib/libvirt/images/vagrant-libvirt_default.img'/>
27
+ <target dev='vda' bus='virtio'/>
28
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
29
+ </disk>
30
+ <controller type='usb' index='0' model='piix3-uhci'>
31
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
32
+ </controller>
33
+ <controller type='pci' index='0' model='pci-root'/>
34
+ <interface type='network'>
35
+ <mac address='52:54:00:7d:14:0e'/>
36
+ <source network='vagrant-libvirt'/>
37
+ <model type='virtio'/>
38
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
39
+ </interface>
40
+ <serial type='pty'>
41
+ <target type='isa-serial' port='0'>
42
+ <model name='isa-serial'/>
43
+ </target>
44
+ </serial>
45
+ <console type='pty'>
46
+ <target type='serial' port='0'/>
47
+ </console>
48
+ <input type='mouse' bus='ps2'/>
49
+ <input type='keyboard' bus='ps2'/>
50
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us'>
51
+ <listen type='address' address='127.0.0.1'/>
52
+ </graphics>
53
+ <audio id='1' type='none'/>
54
+ <video>
55
+ <model type='cirrus' vram='9216' heads='1' primary='yes'/>
56
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
57
+ </video>
58
+ <memballoon model='virtio'>
59
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
60
+ </memballoon>
61
+ </devices>
62
+ </domain>
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  require 'support/sharedcontext'
3
5
  require 'support/libvirt_context'
@@ -19,6 +21,8 @@ describe VagrantPlugins::ProviderLibvirt::Action::StartDomain do
19
21
  let(:updated_domain_xml) { File.read(File.join(File.dirname(__FILE__), File.basename(__FILE__, '.rb'), updated_test_file)) }
20
22
 
21
23
  describe '#call' do
24
+ let(:test_file) { 'default.xml' }
25
+
22
26
  before do
23
27
  allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver)
24
28
  .to receive(:connection).and_return(connection)
@@ -28,23 +32,29 @@ describe VagrantPlugins::ProviderLibvirt::Action::StartDomain do
28
32
  allow(connection).to receive(:servers).and_return(servers)
29
33
  allow(servers).to receive(:get).and_return(domain)
30
34
 
35
+ allow(logger).to receive(:debug)
31
36
  expect(logger).to receive(:info)
32
37
  expect(ui).to_not receive(:error)
38
+
39
+ allow(libvirt_domain).to receive(:xml_desc).and_return(domain_xml)
40
+
41
+ allow(libvirt_domain).to receive(:max_memory).and_return(512*1024)
42
+ allow(libvirt_domain).to receive(:num_vcpus).and_return(1)
33
43
  end
34
44
 
35
- context 'default config' do
36
- let(:test_file) { 'default.xml' }
45
+ it 'should execute without changing' do
46
+ allow(libvirt_domain).to receive(:undefine)
47
+ expect(libvirt_domain).to receive(:autostart=)
48
+ expect(domain).to receive(:start)
37
49
 
38
- before do
39
- allow(libvirt_domain).to receive(:xml_desc).and_return(domain_xml)
50
+ expect(subject.call(env)).to be_nil
51
+ end
40
52
 
41
- allow(libvirt_domain).to receive(:max_memory).and_return(512*1024)
42
- allow(libvirt_domain).to receive(:num_vcpus).and_return(1)
43
- end
53
+ context 'when previously running default config' do
54
+ let(:test_file) { 'existing.xml' }
44
55
 
45
56
  it 'should execute without changing' do
46
57
  allow(libvirt_domain).to receive(:undefine)
47
- expect(logger).to_not receive(:debug)
48
58
  expect(libvirt_domain).to receive(:autostart=)
49
59
  expect(domain).to receive(:start)
50
60
 
@@ -53,15 +63,6 @@ describe VagrantPlugins::ProviderLibvirt::Action::StartDomain do
53
63
  end
54
64
 
55
65
  context 'tpm' do
56
- let(:test_file) { 'default.xml' }
57
-
58
- before do
59
- allow(libvirt_domain).to receive(:xml_desc).and_return(domain_xml)
60
-
61
- allow(libvirt_domain).to receive(:max_memory).and_return(512*1024)
62
- allow(libvirt_domain).to receive(:num_vcpus).and_return(1)
63
- end
64
-
65
66
  context 'passthrough tpm added' do
66
67
  let(:updated_test_file) { 'default_added_tpm_path.xml' }
67
68
  let(:vagrantfile_providerconfig) do
@@ -116,7 +117,6 @@ describe VagrantPlugins::ProviderLibvirt::Action::StartDomain do
116
117
  end
117
118
 
118
119
  it 'should execute without changing' do
119
- expect(logger).to_not receive(:debug)
120
120
  expect(libvirt_domain).to receive(:autostart=)
121
121
  expect(domain).to receive(:start)
122
122
 
@@ -136,7 +136,6 @@ describe VagrantPlugins::ProviderLibvirt::Action::StartDomain do
136
136
  end
137
137
 
138
138
  it 'should execute without changing' do
139
- expect(logger).to_not receive(:debug)
140
139
  expect(libvirt_domain).to receive(:autostart=)
141
140
  expect(domain).to receive(:start)
142
141
 
@@ -170,13 +169,6 @@ describe VagrantPlugins::ProviderLibvirt::Action::StartDomain do
170
169
  context 'clock_timers' do
171
170
  let(:test_file) { 'clock_timer_rtc.xml' }
172
171
 
173
- before do
174
- allow(libvirt_domain).to receive(:xml_desc).and_return(domain_xml)
175
-
176
- allow(libvirt_domain).to receive(:max_memory).and_return(512*1024)
177
- allow(libvirt_domain).to receive(:num_vcpus).and_return(1)
178
- end
179
-
180
172
  context 'timers unchanged' do
181
173
  let(:vagrantfile_providerconfig) do
182
174
  <<-EOF
@@ -214,8 +206,6 @@ describe VagrantPlugins::ProviderLibvirt::Action::StartDomain do
214
206
  end
215
207
 
216
208
  context 'timers removed' do
217
- let(:updated_test_file) { 'default.xml' }
218
-
219
209
  it 'should modify the domain' do
220
210
  expect(libvirt_domain).to receive(:undefine)
221
211
  expect(logger).to receive(:debug).with('clock timers config changed')
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'vagrant-libvirt/action/wait_till_up'
2
4
  require 'vagrant-libvirt/errors'
3
5