vagrant-libvirt 0.6.3 → 0.8.1

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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +65 -13
  3. data/lib/vagrant-libvirt/action/cleanup_on_failure.rb +76 -0
  4. data/lib/vagrant-libvirt/action/create_domain.rb +56 -10
  5. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +5 -1
  6. data/lib/vagrant-libvirt/action/create_networks.rb +24 -0
  7. data/lib/vagrant-libvirt/action/destroy_domain.rb +106 -21
  8. data/lib/vagrant-libvirt/action/destroy_networks.rb +1 -1
  9. data/lib/vagrant-libvirt/action/forward_ports.rb +12 -11
  10. data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +1 -1
  11. data/lib/vagrant-libvirt/action/start_domain.rb +36 -0
  12. data/lib/vagrant-libvirt/action/wait_till_up.rb +6 -32
  13. data/lib/vagrant-libvirt/action.rb +72 -83
  14. data/lib/vagrant-libvirt/config.rb +85 -30
  15. data/lib/vagrant-libvirt/driver.rb +11 -9
  16. data/lib/vagrant-libvirt/errors.rb +12 -0
  17. data/lib/vagrant-libvirt/templates/domain.xml.erb +228 -218
  18. data/lib/vagrant-libvirt/templates/private_network.xml.erb +4 -1
  19. data/lib/vagrant-libvirt/util/network_util.rb +15 -3
  20. data/lib/vagrant-libvirt/util/nfs.rb +2 -0
  21. data/lib/vagrant-libvirt/util/resolvers.rb +80 -0
  22. data/lib/vagrant-libvirt/version +1 -1
  23. data/locales/en.yml +17 -0
  24. data/spec/spec_helper.rb +36 -23
  25. data/spec/support/libvirt_context.rb +7 -4
  26. data/spec/support/sharedcontext.rb +1 -1
  27. data/spec/unit/action/cleanup_on_failure_spec.rb +131 -0
  28. data/spec/unit/action/create_domain_spec/additional_disks_domain.xml +6 -18
  29. data/spec/unit/action/create_domain_spec/custom_disk_settings.xml +43 -0
  30. data/spec/unit/action/create_domain_spec/default_domain.xml +6 -18
  31. data/spec/unit/action/create_domain_spec/two_disk_settings.xml +49 -0
  32. data/spec/unit/action/create_domain_spec.rb +51 -7
  33. data/spec/unit/action/create_domain_volume_spec.rb +5 -3
  34. data/spec/unit/action/destroy_domain_spec/additional_disks_domain.xml +47 -0
  35. data/spec/unit/action/destroy_domain_spec/box_multiple_disks.xml +55 -0
  36. data/spec/unit/action/destroy_domain_spec/box_multiple_disks_and_additional_and_custom_disks.xml +72 -0
  37. data/spec/unit/action/destroy_domain_spec/box_multiple_disks_and_additional_and_custom_disks_no_aliases.xml +67 -0
  38. data/spec/unit/action/destroy_domain_spec/box_multiple_disks_and_additional_disks.xml +67 -0
  39. data/spec/unit/action/destroy_domain_spec/cdrom_domain.xml +48 -0
  40. data/spec/unit/action/destroy_domain_spec.rb +134 -30
  41. data/spec/unit/action/forward_ports_spec.rb +10 -2
  42. data/spec/unit/action/prepare_nfs_settings_spec.rb +59 -0
  43. data/spec/unit/action/shutdown_domain_spec.rb +1 -1
  44. data/spec/unit/action/start_domain_spec/clock_timer_rtc.xml +6 -18
  45. data/spec/unit/action/start_domain_spec/default.xml +6 -18
  46. data/spec/unit/action/start_domain_spec/default_added_tpm_path.xml +6 -18
  47. data/spec/unit/action/start_domain_spec/default_added_tpm_version.xml +6 -18
  48. data/spec/unit/action/start_domain_spec/existing.xml +1 -1
  49. data/spec/unit/action/wait_till_up_spec.rb +4 -43
  50. data/spec/unit/action_spec.rb +2 -0
  51. data/spec/unit/config_spec.rb +133 -26
  52. data/spec/unit/driver_spec.rb +154 -10
  53. data/spec/unit/templates/domain_all_settings.xml +56 -77
  54. data/spec/unit/templates/domain_cpu_mode_passthrough.xml +39 -0
  55. data/spec/unit/templates/domain_custom_cpu_model.xml +6 -18
  56. data/spec/unit/templates/domain_defaults.xml +6 -18
  57. data/spec/unit/templates/domain_spec.rb +39 -13
  58. data/spec/unit/templates/tpm/version_1.2.xml +6 -18
  59. data/spec/unit/templates/tpm/version_2.0.xml +6 -18
  60. data/spec/unit/util/resolvers_spec.rb +116 -0
  61. metadata +40 -41
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'support/sharedcontext'
5
+
6
+ require 'vagrant-libvirt/action/prepare_nfs_settings'
7
+
8
+
9
+ describe VagrantPlugins::ProviderLibvirt::Action::PrepareNFSSettings do
10
+ subject { described_class.new(app, env) }
11
+
12
+ include_context 'unit'
13
+
14
+ describe '#call' do
15
+ before do
16
+ # avoid requiring nfsd installed to run tests
17
+ allow(machine.env.host).to receive(:capability?).with(:nfs_installed).and_return(true)
18
+ allow(machine.env.host).to receive(:capability).with(:nfs_installed).and_return(true)
19
+ end
20
+
21
+ context 'when enabled' do
22
+ let(:vagrantfile) do
23
+ <<-EOF
24
+ Vagrant.configure('2') do |config|
25
+ config.vm.box = "vagrant-libvirt/test"
26
+ config.vm.define :test
27
+ config.vm.synced_folder ".", "/vagrant", type: "nfs"
28
+ config.vm.provider :libvirt do |libvirt|
29
+ #{vagrantfile_providerconfig}
30
+ end
31
+ end
32
+ EOF
33
+ end
34
+ let(:socket) { double('socket') }
35
+ let(:udp_socket) { double('udp_socket') }
36
+
37
+ before do
38
+ allow(::TCPSocket).to receive(:new).and_return(socket)
39
+ allow(socket).to receive(:close)
40
+
41
+ allow(::UDPSocket).to receive(:open).and_return(udp_socket)
42
+ allow(udp_socket).to receive(:connect)
43
+ end
44
+
45
+ it 'should retrieve the guest IP address' do
46
+ times_called = 0
47
+ expect(::TCPSocket).to receive(:new) do
48
+ # force reaching later code
49
+ times_called += 1
50
+ times_called < 2 ? raise("StandardError") : socket
51
+ end
52
+ expect(machine).to receive(:ssh_info).and_return({:host => '192.168.1.2'})
53
+ expect(communicator).to receive(:execute).and_yield(:stdout, "192.168.1.2\n192.168.2.2")
54
+
55
+ expect(subject.call(env)).to be_nil
56
+ end
57
+ end
58
+ end
59
+ end
@@ -50,7 +50,7 @@ describe VagrantPlugins::ProviderLibvirt::Action::ShutdownDomain do
50
50
  end
51
51
 
52
52
  it "should not shutdown" do
53
- expect(domain).not_to receive(:shutoff)
53
+ expect(domain).not_to receive(:poweroff)
54
54
  subject.call(env)
55
55
  end
56
56
 
@@ -5,15 +5,11 @@
5
5
  <uuid/>
6
6
  <memory/>
7
7
  <vcpu>1</vcpu>
8
-
9
-
10
8
  <cpu mode='host-model'>
11
- <model fallback='allow'/>
9
+ <model fallback='allow'/>
12
10
  </cpu>
13
-
14
-
15
11
  <os>
16
- <type>hvm</type>
12
+ <type>hvm</type>
17
13
  <kernel/>
18
14
  <initrd/>
19
15
  <cmdline/>
@@ -27,24 +23,16 @@
27
23
  <timer name='rtc'/>
28
24
  </clock>
29
25
  <devices>
30
-
31
-
32
26
  <serial type='pty'>
33
27
  <target port='0'/>
34
28
  </serial>
35
29
  <console type='pty'>
36
30
  <target port='0'/>
37
31
  </console>
38
-
39
-
40
32
  <input bus='ps2' type='mouse'/>
41
-
42
- <graphics autoport='yes' keymap='en-us' listen='127.0.0.1' port='-1' type='vnc'/>
43
- <video>
44
- <model heads='1' type='cirrus' vram='9216'/>
45
- </video>
46
-
47
-
33
+ <graphics autoport='yes' keymap='en-us' listen='127.0.0.1' port='-1' type='vnc'/>
34
+ <video>
35
+ <model heads='1' type='cirrus' vram='16384'/>
36
+ </video>
48
37
  </devices>
49
-
50
38
  </domain>
@@ -5,15 +5,11 @@
5
5
  <uuid/>
6
6
  <memory/>
7
7
  <vcpu>1</vcpu>
8
-
9
-
10
8
  <cpu mode='host-model'>
11
- <model fallback='allow'/>
9
+ <model fallback='allow'/>
12
10
  </cpu>
13
-
14
-
15
11
  <os>
16
- <type>hvm</type>
12
+ <type>hvm</type>
17
13
  <kernel/>
18
14
  <initrd/>
19
15
  <cmdline/>
@@ -25,24 +21,16 @@
25
21
  </features>
26
22
  <clock offset='utc'/>
27
23
  <devices>
28
-
29
-
30
24
  <serial type='pty'>
31
25
  <target port='0'/>
32
26
  </serial>
33
27
  <console type='pty'>
34
28
  <target port='0'/>
35
29
  </console>
36
-
37
-
38
30
  <input bus='ps2' type='mouse'/>
39
-
40
- <graphics autoport='yes' keymap='en-us' listen='127.0.0.1' port='-1' type='vnc'/>
41
- <video>
42
- <model heads='1' type='cirrus' vram='9216'/>
43
- </video>
44
-
45
-
31
+ <graphics autoport='yes' keymap='en-us' listen='127.0.0.1' port='-1' type='vnc'/>
32
+ <video>
33
+ <model heads='1' type='cirrus' vram='16384'/>
34
+ </video>
46
35
  </devices>
47
-
48
36
  </domain>
@@ -5,15 +5,11 @@
5
5
  <uuid/>
6
6
  <memory/>
7
7
  <vcpu>1</vcpu>
8
-
9
-
10
8
  <cpu mode='host-model'>
11
- <model fallback='allow'/>
9
+ <model fallback='allow'/>
12
10
  </cpu>
13
-
14
-
15
11
  <os>
16
- <type>hvm</type>
12
+ <type>hvm</type>
17
13
  <kernel/>
18
14
  <initrd/>
19
15
  <cmdline/>
@@ -25,24 +21,16 @@
25
21
  </features>
26
22
  <clock offset='utc'/>
27
23
  <devices>
28
-
29
-
30
24
  <serial type='pty'>
31
25
  <target port='0'/>
32
26
  </serial>
33
27
  <console type='pty'>
34
28
  <target port='0'/>
35
29
  </console>
36
-
37
-
38
30
  <input bus='ps2' type='mouse'/>
39
-
40
- <graphics autoport='yes' keymap='en-us' listen='127.0.0.1' port='-1' type='vnc'/>
41
- <video>
42
- <model heads='1' type='cirrus' vram='9216'/>
43
- </video>
44
-
45
-
31
+ <graphics autoport='yes' keymap='en-us' listen='127.0.0.1' port='-1' type='vnc'/>
32
+ <video>
33
+ <model heads='1' type='cirrus' vram='16384'/>
34
+ </video>
46
35
  <tpm model='tpm-tis'><backend type='passthrough'><device path='/dev/tpm0'/></backend></tpm></devices>
47
-
48
36
  </domain>
@@ -5,15 +5,11 @@
5
5
  <uuid/>
6
6
  <memory/>
7
7
  <vcpu>1</vcpu>
8
-
9
-
10
8
  <cpu mode='host-model'>
11
- <model fallback='allow'/>
9
+ <model fallback='allow'/>
12
10
  </cpu>
13
-
14
-
15
11
  <os>
16
- <type>hvm</type>
12
+ <type>hvm</type>
17
13
  <kernel/>
18
14
  <initrd/>
19
15
  <cmdline/>
@@ -25,24 +21,16 @@
25
21
  </features>
26
22
  <clock offset='utc'/>
27
23
  <devices>
28
-
29
-
30
24
  <serial type='pty'>
31
25
  <target port='0'/>
32
26
  </serial>
33
27
  <console type='pty'>
34
28
  <target port='0'/>
35
29
  </console>
36
-
37
-
38
30
  <input bus='ps2' type='mouse'/>
39
-
40
- <graphics autoport='yes' keymap='en-us' listen='127.0.0.1' port='-1' type='vnc'/>
41
- <video>
42
- <model heads='1' type='cirrus' vram='9216'/>
43
- </video>
44
-
45
-
31
+ <graphics autoport='yes' keymap='en-us' listen='127.0.0.1' port='-1' type='vnc'/>
32
+ <video>
33
+ <model heads='1' type='cirrus' vram='16384'/>
34
+ </video>
46
35
  <tpm model='tpm-crb'><backend type='emulator' version='2.0'/></tpm></devices>
47
-
48
36
  </domain>
@@ -52,7 +52,7 @@
52
52
  </graphics>
53
53
  <audio id='1' type='none'/>
54
54
  <video>
55
- <model type='cirrus' vram='9216' heads='1' primary='yes'/>
55
+ <model type='cirrus' vram='16384' heads='1' primary='yes'/>
56
56
  <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
57
57
  </video>
58
58
  <memballoon model='virtio'>
@@ -22,6 +22,10 @@ describe VagrantPlugins::ProviderLibvirt::Action::WaitTillUp do
22
22
  .and_return(driver)
23
23
  allow(driver).to receive(:get_domain).and_return(domain)
24
24
  allow(driver).to receive(:state).and_return(:running)
25
+ # return some information for domain when needed
26
+ allow(domain).to receive(:mac).and_return('9C:D5:53:F1:5A:E7')
27
+
28
+ allow(machine.provider_config).to receive(:qemu_use_session).and_return(false)
25
29
  end
26
30
 
27
31
  context 'when machine does not exist' do
@@ -62,7 +66,6 @@ describe VagrantPlugins::ProviderLibvirt::Action::WaitTillUp do
62
66
  expect(app).to_not receive(:call)
63
67
  expect(ui).to receive(:info).with('Waiting for domain to get an IP address...')
64
68
  expect(ui).to_not receive(:info).with('Waiting for SSH to become available...')
65
- expect(env[:machine].communicate).to_not receive(:ready?)
66
69
  expect {subject.call(env) }.to raise_error(::Fog::Errors::TimeoutError)
67
70
  end
68
71
  end
@@ -85,46 +88,4 @@ describe VagrantPlugins::ProviderLibvirt::Action::WaitTillUp do
85
88
  end
86
89
  end
87
90
  end
88
-
89
- describe '#recover' do
90
- before do
91
- allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).to receive(:get_domain).and_return(machine)
92
- allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).to receive(:state)
93
- .and_return(:not_created)
94
- allow(env).to receive(:[]).and_call_original
95
- end
96
-
97
- it 'should do nothing by default' do
98
- expect(env).to_not receive(:[]).with(:action_runner) # cleanup
99
- expect(subject.recover(env)).to be_nil
100
- end
101
-
102
- context 'with machine coming up' do
103
- before do
104
- allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).to receive(:state)
105
- .and_return(:running)
106
- env[:destroy_on_error] = true
107
- end
108
-
109
- context 'and user has disabled destroy on failure' do
110
- before do
111
- env[:destroy_on_error] = false
112
- end
113
-
114
- it 'skips terminate on failure' do
115
- expect(env).to_not receive(:[]).with(:action_runner) # cleanup
116
- expect(subject.recover(env)).to be_nil
117
- end
118
- end
119
-
120
- context 'and using default settings' do
121
- let(:runner) { double('runner') }
122
- it 'deletes VM on failure' do
123
- expect(env).to receive(:[]).with(:action_runner).and_return(runner) # cleanup
124
- expect(runner).to receive(:run)
125
- expect(subject.recover(env)).to be_nil
126
- end
127
- end
128
- end
129
- end
130
91
  end
@@ -27,6 +27,8 @@ describe VagrantPlugins::ProviderLibvirt::Action do
27
27
  allow(logger).to receive(:info)
28
28
  allow(logger).to receive(:debug)
29
29
  allow(logger).to receive(:error)
30
+
31
+ allow(connection.client).to receive(:libversion).and_return(6_002_000)
30
32
  end
31
33
 
32
34
  def allow_action_env_result(action, *responses)
@@ -171,55 +171,55 @@ describe VagrantPlugins::ProviderLibvirt::Config do
171
171
  # ignore LIBVIRT_DEFAULT_URI due to explicit settings
172
172
  [ # when uri explicitly set
173
173
  {:uri => 'qemu:///system'},
174
- {:uri => 'qemu:///system'},
174
+ {:uri => %r{qemu:///(system|session)}},
175
175
  {
176
- :env => {'LIBVIRT_DEFAULT_URI' => 'qemu://session'},
176
+ :env => {'LIBVIRT_DEFAULT_URI' => 'qemu:///custom'},
177
177
  }
178
178
  ],
179
179
  [ # when host explicitly set
180
180
  {:host => 'remote'},
181
- {:uri => 'qemu://remote/system'},
181
+ {:uri => %r{qemu://remote/(system|session)}},
182
182
  {
183
- :env => {'LIBVIRT_DEFAULT_URI' => 'qemu://session'},
183
+ :env => {'LIBVIRT_DEFAULT_URI' => 'qemu:///custom'},
184
184
  }
185
185
  ],
186
186
  [ # when connect_via_ssh explicitly set
187
187
  {:connect_via_ssh => true},
188
- {:uri => 'qemu+ssh://localhost/system?no_verify=1'},
188
+ {:uri => %r{qemu\+ssh://localhost/(system|session)\?no_verify=1}},
189
189
  {
190
- :env => {'LIBVIRT_DEFAULT_URI' => 'qemu://session'},
190
+ :env => {'LIBVIRT_DEFAULT_URI' => 'qemu:///custom'},
191
191
  }
192
192
  ],
193
193
  [ # when username explicitly set without ssh
194
194
  {:username => 'my_user' },
195
- {:uri => 'qemu:///system', :username => 'my_user'},
195
+ {:uri => %r{qemu:///(system|session)}, :username => 'my_user'},
196
196
  {
197
- :env => {'LIBVIRT_DEFAULT_URI' => 'qemu://session'},
197
+ :env => {'LIBVIRT_DEFAULT_URI' => 'qemu:///custom'},
198
198
  }
199
199
  ],
200
200
  [ # when username explicitly set with host but without ssh
201
201
  {:username => 'my_user', :host => 'remote'},
202
- {:uri => 'qemu://remote/system', :username => 'my_user'},
202
+ {:uri => %r{qemu://remote/(system|session)}, :username => 'my_user'},
203
203
  {
204
- :env => {'LIBVIRT_DEFAULT_URI' => 'qemu://session'},
204
+ :env => {'LIBVIRT_DEFAULT_URI' => 'qemu:///custom'},
205
205
  }
206
206
  ],
207
207
  [ # when password explicitly set
208
208
  {:password => 'some_password'},
209
- {:uri => 'qemu:///system', :password => 'some_password'},
209
+ {:uri => %r{qemu:///(system|session)}, :password => 'some_password'},
210
210
  {
211
- :env => {'LIBVIRT_DEFAULT_URI' => 'qemu://session'},
211
+ :env => {'LIBVIRT_DEFAULT_URI' => 'qemu:///custom'},
212
212
  }
213
213
  ],
214
214
 
215
215
  # driver settings
216
216
  [ # set to kvm only
217
217
  {:driver => 'kvm'},
218
- {:uri => "qemu:///system"},
218
+ {:uri => %r{qemu:///(system|session)}},
219
219
  ],
220
220
  [ # set to qemu only
221
221
  {:driver => 'qemu'},
222
- {:uri => "qemu:///system"},
222
+ {:uri => %r{qemu:///(system|session)}},
223
223
  ],
224
224
  [ # set to qemu with session enabled
225
225
  {:driver => 'qemu', :qemu_use_session => true},
@@ -241,29 +241,29 @@ describe VagrantPlugins::ProviderLibvirt::Config do
241
241
  # connect_via_ssh settings
242
242
  [ # enabled
243
243
  {:connect_via_ssh => true},
244
- {:uri => "qemu+ssh://localhost/system?no_verify=1"},
244
+ {:uri => %r{qemu\+ssh://localhost/(system|session)\?no_verify=1}},
245
245
  ],
246
246
  [ # enabled with user
247
247
  {:connect_via_ssh => true, :username => 'my_user'},
248
- {:uri => "qemu+ssh://my_user@localhost/system?no_verify=1"},
248
+ {:uri => %r{qemu\+ssh://my_user@localhost/(system|session)\?no_verify=1}},
249
249
  ],
250
250
  [ # enabled with host
251
251
  {:connect_via_ssh => true, :host => 'remote_server'},
252
- {:uri => "qemu+ssh://remote_server/system?no_verify=1"},
252
+ {:uri => %r{qemu\+ssh://remote_server/(system|session)\?no_verify=1}},
253
253
  ],
254
254
 
255
255
  # id_ssh_key_file behaviour
256
256
  [ # set should take given value
257
257
  {:connect_via_ssh => true, :id_ssh_key_file => '/path/to/keyfile'},
258
- {:uri => 'qemu+ssh://localhost/system?no_verify=1&keyfile=/path/to/keyfile', :connect_via_ssh => true},
258
+ {:uri => %r{qemu\+ssh://localhost/(system|session)\?no_verify=1&keyfile=/path/to/keyfile}, :connect_via_ssh => true},
259
259
  ],
260
260
  [ # set should infer use of ssh
261
261
  {:id_ssh_key_file => '/path/to/keyfile'},
262
- {:uri => 'qemu+ssh://localhost/system?no_verify=1&keyfile=/path/to/keyfile', :connect_via_ssh => true},
262
+ {:uri => %r{qemu\+ssh://localhost/(system|session)\?no_verify=1&keyfile=/path/to/keyfile}, :connect_via_ssh => true},
263
263
  ],
264
264
  [ # connect_via_ssh should enable default but ignore due to not existing
265
265
  {:connect_via_ssh => true},
266
- {:uri => 'qemu+ssh://localhost/system?no_verify=1', :id_ssh_key_file => nil},
266
+ {:uri => %r{qemu\+ssh://localhost/(system|session)\?no_verify=1}, :id_ssh_key_file => nil},
267
267
  {
268
268
  :setup => ProcWithBinding.new {
269
269
  expect(File).to receive(:file?).with("/home/tests/.ssh/id_rsa").and_return(false)
@@ -272,7 +272,7 @@ describe VagrantPlugins::ProviderLibvirt::Config do
272
272
  ],
273
273
  [ # connect_via_ssh should enable default and include due to existing
274
274
  {:connect_via_ssh => true},
275
- {:uri => 'qemu+ssh://localhost/system?no_verify=1&keyfile=/home/tests/.ssh/id_rsa', :id_ssh_key_file => '/home/tests/.ssh/id_rsa'},
275
+ {:uri => %r{qemu\+ssh://localhost/(system|session)\?no_verify=1&keyfile=/home/tests/\.ssh/id_rsa}, :id_ssh_key_file => '/home/tests/.ssh/id_rsa'},
276
276
  {
277
277
  :setup => ProcWithBinding.new {
278
278
  expect(File).to receive(:file?).with("/home/tests/.ssh/id_rsa").and_return(true)
@@ -283,7 +283,7 @@ describe VagrantPlugins::ProviderLibvirt::Config do
283
283
  # socket behaviour
284
284
  [ # set
285
285
  {:socket => '/var/run/libvirt/libvirt-sock'},
286
- {:uri => "qemu:///system?socket=/var/run/libvirt/libvirt-sock"},
286
+ {:uri => %r{qemu:///(system|session)\?socket=/var/run/libvirt/libvirt-sock}},
287
287
  ],
288
288
  ].each do |inputs, outputs, options|
289
289
  opts = {}
@@ -317,7 +317,8 @@ describe VagrantPlugins::ProviderLibvirt::Config do
317
317
  hash["#{name.to_s[1..-1]}".to_sym] =subject.instance_variable_get(name)
318
318
  end
319
319
  end
320
- expect(got).to eq(outputs)
320
+
321
+ expect(got).to match(outputs.inject({}) { |h, (k, v)| h[k] = v.is_a?(Regexp) ? a_string_matching(v) : v; h })
321
322
  end
322
323
  end
323
324
 
@@ -338,6 +339,54 @@ describe VagrantPlugins::ProviderLibvirt::Config do
338
339
  end
339
340
  end
340
341
 
342
+ context '@system_uri' do
343
+ [
344
+ # system uri
345
+ [ # transport and hostname
346
+ {:uri => "qemu+ssh://localhost/session"},
347
+ {:uri => "qemu+ssh://localhost/session", :system_uri => "qemu+ssh://localhost/system"},
348
+ ],
349
+ [ # explicitly set
350
+ {:qemu_use_session => true, :system_uri => "custom://remote/system"},
351
+ {:uri => "qemu:///session", :system_uri => "custom://remote/system"},
352
+ ],
353
+ ].each do |inputs, outputs, options|
354
+ opts = {}
355
+ opts.merge!(options) if options
356
+
357
+ it "should handle inputs #{inputs} with env (#{opts[:env]})" do
358
+ # allow some of these to fail for now if marked as such
359
+ if !opts[:allow_failure].nil?
360
+ pending(opts[:allow_failure])
361
+ end
362
+
363
+ if !opts[:setup].nil?
364
+ opts[:setup].apply_binding(binding)
365
+ end
366
+
367
+ inputs.each do |k, v|
368
+ subject.instance_variable_set("@#{k}", v)
369
+ end
370
+
371
+ if !opts[:env].nil?
372
+ opts[:env].each do |k, v|
373
+ fake_env[k] = v
374
+ end
375
+ end
376
+
377
+ subject.finalize!
378
+
379
+ # ensure failed output indicates which settings are incorrect in the failed test
380
+ got = subject.instance_variables.each_with_object({}) do |name, hash|
381
+ if outputs.key?(name.to_s[1..-1].to_sym)
382
+ hash["#{name.to_s[1..-1]}".to_sym] =subject.instance_variable_get(name)
383
+ end
384
+ end
385
+ expect(got).to eq(outputs)
386
+ end
387
+ end
388
+ end
389
+
341
390
  context '@proxy_command' do
342
391
  before(:example) do
343
392
  stub_const("ENV", fake_env)
@@ -483,6 +532,47 @@ describe VagrantPlugins::ProviderLibvirt::Config do
483
532
  end
484
533
  end
485
534
  end
535
+
536
+ context '@channels' do
537
+ it 'should be empty by default' do
538
+ subject.finalize!
539
+
540
+ expect(subject.channels).to be_empty
541
+ end
542
+
543
+ context 'when qemu_use_agent is set' do
544
+ before do
545
+ subject.qemu_use_agent = true
546
+ end
547
+
548
+ it 'should inject a qemu agent channel' do
549
+ subject.finalize!
550
+
551
+ expect(subject.channels).to_not be_empty
552
+ expect(subject.channels).to match([a_hash_including({:target_name => 'org.qemu.guest_agent.0'})])
553
+ end
554
+
555
+ context 'when agent channel already added' do
556
+ it 'should not modify the channels' do
557
+ subject.channel :type => 'unix', :target_name => 'org.qemu.guest_agent.0', :target_type => 'virtio'
558
+
559
+ subject.finalize!
560
+
561
+ expect(subject.channels.length).to eq(1)
562
+ end
563
+
564
+ context 'when agent channel explicitly disbaled' do
565
+ it 'should not include an agent channel' do
566
+ subject.channel :type => 'unix', :target_name => 'org.qemu.guest_agent.0', :disabled => true
567
+
568
+ subject.finalize!
569
+
570
+ expect(subject.channels).to be_empty
571
+ end
572
+ end
573
+ end
574
+ end
575
+ end
486
576
  end
487
577
 
488
578
  def assert_invalid
@@ -518,7 +608,9 @@ describe VagrantPlugins::ProviderLibvirt::Config do
518
608
 
519
609
  context 'with mac defined' do
520
610
  let (:vm) { double('vm') }
521
- before { expect(machine.config).to receive(:vm).and_return(vm) }
611
+ before do
612
+ machine.config.instance_variable_get("@keys")[:vm] = vm
613
+ end
522
614
 
523
615
  it 'is valid with valid mac' do
524
616
  expect(vm).to receive(:networks).and_return([[:public, { mac: 'aa:bb:cc:dd:ee:ff' }]])
@@ -537,6 +629,21 @@ describe VagrantPlugins::ProviderLibvirt::Config do
537
629
  assert_invalid
538
630
  end
539
631
  end
632
+
633
+ context 'with cpu_mode and cpu_model defined' do
634
+ it 'should discard model if mode is passthrough' do
635
+ subject.cpu_mode = 'host-passthrough'
636
+ subject.cpu_model = 'qemu64'
637
+ assert_valid
638
+ expect(subject.cpu_model).to be_empty
639
+ end
640
+
641
+ it 'should allow custom mode with model' do
642
+ subject.cpu_mode = 'custom'
643
+ subject.cpu_model = 'qemu64'
644
+ assert_valid
645
+ end
646
+ end
540
647
  end
541
648
 
542
649
  describe '#merge' do
@@ -558,11 +665,11 @@ describe VagrantPlugins::ProviderLibvirt::Config do
558
665
  end
559
666
 
560
667
  context 'without devices given' do
561
- it 'should merge disks with different devices assigned automatically' do
668
+ it 'should merge disks without assigning devices automatically' do
562
669
  one.storage(:file)
563
670
  two.storage(:file)
564
671
  subject.finalize!
565
- expect(subject.disks).to include(include(device: 'vdb'),
672
+ expect(subject.disks).to_not include(include(device: 'vdb'),
566
673
  include(device: 'vdc'))
567
674
  end
568
675
  end