vagrant-libvirt 0.0.45 → 0.4.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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +542 -167
  3. data/lib/vagrant-libvirt/action.rb +2 -2
  4. data/lib/vagrant-libvirt/action/create_domain.rb +112 -42
  5. data/lib/vagrant-libvirt/action/create_domain_volume.rb +14 -10
  6. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +8 -5
  7. data/lib/vagrant-libvirt/action/create_networks.rb +2 -2
  8. data/lib/vagrant-libvirt/action/destroy_domain.rb +1 -1
  9. data/lib/vagrant-libvirt/action/forward_ports.rb +10 -8
  10. data/lib/vagrant-libvirt/action/halt_domain.rb +1 -1
  11. data/lib/vagrant-libvirt/action/handle_box_image.rb +28 -60
  12. data/lib/vagrant-libvirt/action/handle_storage_pool.rb +4 -4
  13. data/lib/vagrant-libvirt/action/package_domain.rb +64 -12
  14. data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +3 -9
  15. data/lib/vagrant-libvirt/action/prune_nfs_exports.rb +19 -9
  16. data/lib/vagrant-libvirt/action/remove_libvirt_image.rb +2 -2
  17. data/lib/vagrant-libvirt/action/remove_stale_volume.rb +17 -11
  18. data/lib/vagrant-libvirt/action/set_boot_order.rb +2 -2
  19. data/lib/vagrant-libvirt/action/set_name_of_domain.rb +6 -9
  20. data/lib/vagrant-libvirt/action/start_domain.rb +87 -30
  21. data/lib/vagrant-libvirt/action/wait_till_up.rb +10 -32
  22. data/lib/vagrant-libvirt/cap/public_address.rb +16 -0
  23. data/lib/vagrant-libvirt/cap/synced_folder.rb +3 -3
  24. data/lib/vagrant-libvirt/config.rb +294 -42
  25. data/lib/vagrant-libvirt/driver.rb +49 -34
  26. data/lib/vagrant-libvirt/errors.rb +5 -5
  27. data/lib/vagrant-libvirt/plugin.rb +7 -2
  28. data/lib/vagrant-libvirt/provider.rb +2 -9
  29. data/lib/vagrant-libvirt/templates/domain.xml.erb +52 -10
  30. data/lib/vagrant-libvirt/templates/public_interface.xml.erb +5 -1
  31. data/lib/vagrant-libvirt/util.rb +1 -0
  32. data/lib/vagrant-libvirt/util/erb_template.rb +6 -7
  33. data/lib/vagrant-libvirt/util/network_util.rb +6 -1
  34. data/lib/vagrant-libvirt/util/nfs.rb +17 -0
  35. data/lib/vagrant-libvirt/util/ui.rb +23 -0
  36. data/lib/vagrant-libvirt/version +1 -0
  37. data/lib/vagrant-libvirt/version.rb +72 -1
  38. data/locales/en.yml +6 -6
  39. data/spec/spec_helper.rb +28 -2
  40. data/spec/support/libvirt_context.rb +3 -1
  41. data/spec/support/sharedcontext.rb +7 -3
  42. data/spec/unit/action/create_domain_spec.rb +160 -0
  43. data/spec/unit/action/create_domain_spec/default_system_storage_pool.xml +17 -0
  44. data/spec/unit/action/create_domain_spec/default_user_storage_pool.xml +17 -0
  45. data/spec/unit/action/destroy_domain_spec.rb +2 -2
  46. data/spec/unit/action/set_name_of_domain_spec.rb +3 -3
  47. data/spec/unit/action/start_domain_spec.rb +231 -0
  48. data/spec/unit/action/start_domain_spec/clock_timer_rtc.xml +50 -0
  49. data/spec/unit/action/start_domain_spec/default.xml +48 -0
  50. data/spec/unit/action/start_domain_spec/default_added_tpm_path.xml +48 -0
  51. data/spec/unit/action/start_domain_spec/default_added_tpm_version.xml +48 -0
  52. data/spec/unit/action/wait_till_up_spec.rb +14 -9
  53. data/spec/unit/config_spec.rb +438 -0
  54. data/spec/unit/provider_spec.rb +11 -0
  55. data/spec/unit/templates/domain_all_settings.xml +20 -5
  56. data/spec/unit/templates/domain_custom_cpu_model.xml +4 -1
  57. data/spec/unit/templates/domain_defaults.xml +4 -1
  58. data/spec/unit/templates/domain_spec.rb +92 -4
  59. data/spec/unit/templates/tpm/version_1.2.xml +54 -0
  60. data/spec/unit/templates/tpm/version_2.0.xml +53 -0
  61. metadata +91 -36
  62. data/.coveralls.yml +0 -1
  63. data/.github/issue_template.md +0 -37
  64. data/.gitignore +0 -21
  65. data/.travis.yml +0 -24
  66. data/Gemfile +0 -26
  67. data/Rakefile +0 -8
  68. data/example_box/README.md +0 -29
  69. data/example_box/Vagrantfile +0 -60
  70. data/example_box/metadata.json +0 -5
  71. data/lib/vagrant-libvirt/templates/default_storage_volume.xml.erb +0 -14
  72. data/tools/create_box.sh +0 -130
  73. data/tools/prepare_redhat_for_box.sh +0 -119
  74. data/vagrant-libvirt.gemspec +0 -51
@@ -12,18 +12,19 @@ describe VagrantPlugins::ProviderLibvirt::Action::WaitTillUp do
12
12
  include_context 'libvirt'
13
13
  include_context 'unit'
14
14
 
15
+ let (:driver) { double('driver') }
16
+
15
17
  describe '#call' do
16
18
  before do
17
- allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver)
18
- .to receive(:get_domain).and_return(domain)
19
- allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).to receive(:state)
20
- .and_return(:running)
19
+ allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Provider).to receive(:driver)
20
+ .and_return(driver)
21
+ allow(driver).to receive(:get_domain).and_return(domain)
22
+ allow(driver).to receive(:state).and_return(:running)
21
23
  end
22
24
 
23
25
  context 'when machine does not exist' do
24
26
  before do
25
- allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver)
26
- .to receive(:get_domain).and_return(nil)
27
+ allow(driver).to receive(:get_domain).and_return(nil)
27
28
  end
28
29
 
29
30
  it 'raises exception' do
@@ -41,6 +42,7 @@ describe VagrantPlugins::ProviderLibvirt::Action::WaitTillUp do
41
42
  it 'should exit' do
42
43
  expect(app).to_not receive(:call)
43
44
  expect(ui).to receive(:info).with('Waiting for domain to get an IP address...')
45
+ expect(logger).to receive(:debug).with(/Searching for IP for MAC address: .*/)
44
46
  expect(subject.call(env)).to be_nil
45
47
  end
46
48
  end
@@ -50,13 +52,12 @@ describe VagrantPlugins::ProviderLibvirt::Action::WaitTillUp do
50
52
  allow(domain).to receive(:wait_for).and_return(true)
51
53
  allow(env).to receive(:[]).and_call_original
52
54
  allow(env).to receive(:[]).with(:interrupted).and_return(false, true, true)
53
- allow(env).to receive(:[]).with(:ip_address).and_return('192.168.121.2')
55
+ allow(driver).to receive(:get_domain_ipaddress).and_return('192.168.121.2')
54
56
  end
55
57
  it 'should exit after getting IP' do
56
58
  expect(app).to_not receive(:call)
57
59
  expect(ui).to receive(:info).with('Waiting for domain to get an IP address...')
58
60
  expect(ui).to receive(:info).with('Waiting for SSH to become available...')
59
- logger = subject.instance_variable_get(:@logger)
60
61
  expect(logger).to receive(:debug).with(/Searching for IP for MAC address: .*/)
61
62
  expect(logger).to receive(:info).with('Got IP address 192.168.121.2')
62
63
  expect(logger).to receive(:info).with(/Time for getting IP: .*/)
@@ -71,12 +72,16 @@ describe VagrantPlugins::ProviderLibvirt::Action::WaitTillUp do
71
72
  allow(domain).to receive(:wait_for).and_return(true)
72
73
  allow(env).to receive(:[]).and_call_original
73
74
  allow(env).to receive(:[]).with(:interrupted).and_return(false)
74
- allow(env).to receive(:[]).with(:ip_address).and_return('192.168.121.2')
75
+ allow(driver).to receive(:get_domain_ipaddress).and_return('192.168.121.2')
75
76
  end
76
77
  it 'should call the next hook' do
77
78
  expect(app).to receive(:call)
78
79
  expect(ui).to receive(:info).with('Waiting for domain to get an IP address...')
79
80
  expect(ui).to receive(:info).with('Waiting for SSH to become available...')
81
+ expect(logger).to receive(:debug).with(/Searching for IP for MAC address: .*/)
82
+ expect(logger).to receive(:info).with('Got IP address 192.168.121.2')
83
+ expect(logger).to receive(:info).with(/Time for getting IP: .*/)
84
+ expect(logger).to receive(:info).with(/Time for SSH ready: .*/)
80
85
  expect(env[:machine].communicate).to receive(:ready?).and_return(true)
81
86
  expect(subject.call(env)).to be_nil
82
87
  end
@@ -1,3 +1,5 @@
1
+ require 'contextual_proc'
2
+
1
3
  require 'spec_helper'
2
4
  require 'support/sharedcontext'
3
5
 
@@ -6,12 +8,438 @@ require 'vagrant-libvirt/config'
6
8
  describe VagrantPlugins::ProviderLibvirt::Config do
7
9
  include_context 'unit'
8
10
 
11
+ let(:fake_env) { Hash.new }
12
+
13
+ describe '#clock_timer' do
14
+ it 'should handle all options' do
15
+ expect(
16
+ subject.clock_timer(
17
+ :name => 'rtc',
18
+ :track => 'wall',
19
+ :tickpolicy => 'delay',
20
+ :present => 'yes',
21
+ ).length
22
+ ).to be(1)
23
+ expect(
24
+ subject.clock_timer(
25
+ :name => 'tsc',
26
+ :tickpolicy => 'delay',
27
+ :frequency => '100',
28
+ :mode => 'auto',
29
+ :present => 'yes',
30
+ ).length
31
+ ).to be(2)
32
+ end
33
+
34
+ it 'should correctly save the options' do
35
+ opts = {:name => 'rtc', :track => 'wall'}
36
+ expect(subject.clock_timer(opts).length).to be(1)
37
+
38
+ expect(subject.clock_timers[0]).to eq(opts)
39
+
40
+ opts[:name] = 'tsc'
41
+ expect(subject.clock_timers[0]).to_not eq(opts)
42
+ end
43
+
44
+ it 'should error name option is missing' do
45
+ expect{ subject.clock_timer(:track => "wall") }.to raise_error("Clock timer name must be specified")
46
+ end
47
+
48
+ it 'should error if nil value for option supplied' do
49
+ expect{ subject.clock_timer(:name => "rtc", :track => nil) }.to raise_error("Value of timer option track is nil")
50
+ end
51
+
52
+ it 'should error if unrecognized option specified' do
53
+ expect{ subject.clock_timer(:name => "tsc", :badopt => "value") }.to raise_error("Unknown clock timer option: badopt")
54
+ end
55
+ end
56
+
57
+ describe '#finalize!' do
58
+ it 'is valid with defaults' do
59
+ subject.finalize!
60
+ end
61
+
62
+ context '@uri' do
63
+ before(:example) do
64
+ stub_const("ENV", fake_env)
65
+ fake_env['HOME'] = "/home/tests"
66
+ end
67
+
68
+ # table describing expected behaviour of inputs that affect the resulting uri as
69
+ # well as any subsequent settings that might be inferred if the uri was
70
+ # explicitly set.
71
+ [
72
+ # settings
73
+ [ # all default
74
+ {},
75
+ {:uri => "qemu:///system"},
76
+ ],
77
+
78
+ # explicit uri settings
79
+ [ # transport and hostname
80
+ {:uri => "qemu+ssh://localhost/system"},
81
+ {:uri => "qemu+ssh://localhost/system", :connect_via_ssh => true, :host => "localhost", :username => nil},
82
+ ],
83
+ [ # tcp transport with port
84
+ {:uri => "qemu+tcp://localhost:5000/system"},
85
+ {:uri => "qemu+tcp://localhost:5000/system", :connect_via_ssh => false, :host => "localhost", :username => nil},
86
+ ],
87
+ [ # connect explicit to unix socket
88
+ {:uri => "qemu+unix:///system"},
89
+ {:uri => "qemu+unix:///system", :connect_via_ssh => false, :host => nil, :username => nil},
90
+ ],
91
+ [ # via libssh2 should enable ssh as well
92
+ {:uri => "qemu+libssh2://user@remote/system?known_hosts=/home/user/.ssh/known_hosts"},
93
+ {
94
+ :uri => "qemu+libssh2://user@remote/system?known_hosts=/home/user/.ssh/known_hosts",
95
+ :connect_via_ssh => true, :host => "remote", :username => "user",
96
+ },
97
+ ],
98
+ [ # xen
99
+ {:uri => "xen://remote/system?no_verify=1"},
100
+ {
101
+ :uri => "xen://remote/system?no_verify=1",
102
+ :connect_via_ssh => false, :host => "remote", :username => nil,
103
+ :id_ssh_key_file => nil,
104
+ },
105
+ {
106
+ :setup => ContextualProc.new {
107
+ expect(File).to_not receive(:file?)
108
+ }
109
+ }
110
+ ],
111
+ [ # xen
112
+ {:uri => "xen+ssh://remote/system?no_verify=1"},
113
+ {
114
+ :uri => "xen+ssh://remote/system?no_verify=1",
115
+ :connect_via_ssh => true, :host => "remote", :username => nil,
116
+ :id_ssh_key_file => "/home/tests/.ssh/id_rsa",
117
+ },
118
+ {
119
+ :setup => ContextualProc.new {
120
+ expect(File).to receive(:file?).with("/home/tests/.ssh/id_rsa").and_return(true)
121
+ }
122
+ }
123
+ ],
124
+
125
+ # with LIBVIRT_DEFAULT_URI
126
+ [ # all other set to default
127
+ {},
128
+ {:uri => "custom:///custom_path", :qemu_use_session => false},
129
+ {
130
+ :env => {'LIBVIRT_DEFAULT_URI' => "custom:///custom_path"},
131
+ }
132
+ ],
133
+ [ # with session
134
+ {},
135
+ {:uri => "qemu:///session", :qemu_use_session => true},
136
+ {
137
+ :env => {'LIBVIRT_DEFAULT_URI' => "qemu:///session"},
138
+ }
139
+ ],
140
+ [ # with session and using ssh infer connect by ssh and ignore host as not provided
141
+ {},
142
+ {:uri => "qemu+ssh:///session", :qemu_use_session => true, :connect_via_ssh => true, :host => nil},
143
+ {
144
+ :env => {'LIBVIRT_DEFAULT_URI' => "qemu+ssh:///session"},
145
+ }
146
+ ],
147
+ [ # with session and using ssh to specific host with additional query options provided, infer host and ssh
148
+ {},
149
+ {:uri => "qemu+ssh://remote/session?keyfile=my_id_rsa", :qemu_use_session => true, :connect_via_ssh => true, :host => 'remote'},
150
+ {
151
+ :env => {'LIBVIRT_DEFAULT_URI' => "qemu+ssh://remote/session?keyfile=my_id_rsa"},
152
+ }
153
+ ],
154
+ [ # when session not set
155
+ {},
156
+ {:uri => "qemu:///system", :qemu_use_session => false},
157
+ {
158
+ :env => {'LIBVIRT_DEFAULT_URI' => "qemu:///system"},
159
+ }
160
+ ],
161
+ [ # when session appearing elsewhere
162
+ {},
163
+ {:uri => "qemu://remote/system?keyfile=my_session_id", :qemu_use_session => false},
164
+ {
165
+ :env => {'LIBVIRT_DEFAULT_URI' => "qemu://remote/system?keyfile=my_session_id"},
166
+ }
167
+ ],
168
+
169
+ # ignore LIBVIRT_DEFAULT_URI due to explicit settings
170
+ [ # when uri explicitly set
171
+ {:uri => 'qemu:///system'},
172
+ {:uri => 'qemu:///system'},
173
+ {
174
+ :env => {'LIBVIRT_DEFAULT_URI' => 'qemu://session'},
175
+ }
176
+ ],
177
+ [ # when host explicitly set
178
+ {:host => 'remote'},
179
+ {:uri => 'qemu://remote/system'},
180
+ {
181
+ :env => {'LIBVIRT_DEFAULT_URI' => 'qemu://session'},
182
+ }
183
+ ],
184
+ [ # when connect_via_ssh explicitly set
185
+ {:connect_via_ssh => true},
186
+ {:uri => 'qemu+ssh://localhost/system?no_verify=1'},
187
+ {
188
+ :env => {'LIBVIRT_DEFAULT_URI' => 'qemu://session'},
189
+ }
190
+ ],
191
+ [ # when username explicitly set without ssh
192
+ {:username => 'my_user' },
193
+ {:uri => 'qemu:///system'},
194
+ {
195
+ :env => {'LIBVIRT_DEFAULT_URI' => 'qemu://session'},
196
+ }
197
+ ],
198
+ [ # when username explicitly set with host but without ssh
199
+ {:username => 'my_user', :host => 'remote'},
200
+ {:uri => 'qemu://remote/system'},
201
+ {
202
+ :env => {'LIBVIRT_DEFAULT_URI' => 'qemu://session'},
203
+ }
204
+ ],
205
+ [ # when password explicitly set
206
+ {:password => 'some_password'},
207
+ {:uri => 'qemu:///system', :password => 'some_password'},
208
+ {
209
+ :env => {'LIBVIRT_DEFAULT_URI' => 'qemu://session'},
210
+ }
211
+ ],
212
+
213
+ # driver settings
214
+ [ # set to kvm only
215
+ {:driver => 'kvm'},
216
+ {:uri => "qemu:///system"},
217
+ ],
218
+ [ # set to qemu only
219
+ {:driver => 'qemu'},
220
+ {:uri => "qemu:///system"},
221
+ ],
222
+ [ # set to qemu with session enabled
223
+ {:driver => 'qemu', :qemu_use_session => true},
224
+ {:uri => "qemu:///session"},
225
+ ],
226
+ [ # set to openvz only
227
+ {:driver => 'openvz'},
228
+ {:uri => "openvz:///system"},
229
+ ],
230
+ [ # set to esx
231
+ {:driver => 'esx'},
232
+ {:uri => "esx:///"},
233
+ ],
234
+ [ # set to vbox only
235
+ {:driver => 'vbox'},
236
+ {:uri => "vbox:///session"},
237
+ ],
238
+
239
+ # connect_via_ssh settings
240
+ [ # enabled
241
+ {:connect_via_ssh => true},
242
+ {:uri => "qemu+ssh://localhost/system?no_verify=1"},
243
+ ],
244
+ [ # enabled with user
245
+ {:connect_via_ssh => true, :username => 'my_user'},
246
+ {:uri => "qemu+ssh://my_user@localhost/system?no_verify=1"},
247
+ ],
248
+ [ # enabled with host
249
+ {:connect_via_ssh => true, :host => 'remote_server'},
250
+ {:uri => "qemu+ssh://remote_server/system?no_verify=1"},
251
+ ],
252
+
253
+ # id_ssh_key_file behaviour
254
+ [ # set should take given value
255
+ {:connect_via_ssh => true, :id_ssh_key_file => '/path/to/keyfile'},
256
+ {:uri => 'qemu+ssh://localhost/system?no_verify=1&keyfile=/path/to/keyfile', :connect_via_ssh => true},
257
+ ],
258
+ [ # set should infer use of ssh
259
+ {:id_ssh_key_file => '/path/to/keyfile'},
260
+ {:uri => 'qemu+ssh://localhost/system?no_verify=1&keyfile=/path/to/keyfile', :connect_via_ssh => true},
261
+ ],
262
+ [ # connect_via_ssh should enable default but ignore due to not existing
263
+ {:connect_via_ssh => true},
264
+ {:uri => 'qemu+ssh://localhost/system?no_verify=1', :id_ssh_key_file => nil},
265
+ {
266
+ :setup => ContextualProc.new {
267
+ expect(File).to receive(:file?).with("/home/tests/.ssh/id_rsa").and_return(false)
268
+ }
269
+ }
270
+ ],
271
+ [ # connect_via_ssh should enable default and include due to existing
272
+ {:connect_via_ssh => true},
273
+ {:uri => 'qemu+ssh://localhost/system?no_verify=1&keyfile=/home/tests/.ssh/id_rsa', :id_ssh_key_file => '/home/tests/.ssh/id_rsa'},
274
+ {
275
+ :setup => ContextualProc.new {
276
+ expect(File).to receive(:file?).with("/home/tests/.ssh/id_rsa").and_return(true)
277
+ }
278
+ }
279
+ ],
280
+
281
+ # socket behaviour
282
+ [ # set
283
+ {:socket => '/var/run/libvirt/libvirt-sock'},
284
+ {:uri => "qemu:///system?socket=/var/run/libvirt/libvirt-sock"},
285
+ ],
286
+ ].each do |inputs, outputs, options|
287
+ opts = {}
288
+ opts.merge!(options) if options
289
+
290
+ it "should handle inputs #{inputs} with env (#{opts[:env]})" do
291
+ # allow some of these to fail for now if marked as such
292
+ if !opts[:allow_failure].nil?
293
+ pending(opts[:allow_failure])
294
+ end
295
+
296
+ if !opts[:setup].nil?
297
+ opts[:setup].apply(binding)
298
+ end
299
+
300
+ inputs.each do |k, v|
301
+ subject.instance_variable_set("@#{k}", v)
302
+ end
303
+
304
+ if !opts[:env].nil?
305
+ opts[:env].each do |k, v|
306
+ fake_env[k] = v
307
+ end
308
+ end
309
+
310
+ subject.finalize!
311
+
312
+ # ensure failed output indicates which settings are incorrect in the failed test
313
+ got = subject.instance_variables.each_with_object({}) do |name, hash|
314
+ if outputs.key?(name.to_s[1..-1].to_sym)
315
+ hash["#{name.to_s[1..-1]}".to_sym] =subject.instance_variable_get(name)
316
+ end
317
+ end
318
+ expect(got).to eq(outputs)
319
+ end
320
+ end
321
+
322
+ context 'when invalid @driver is defined' do
323
+ it "should raise exception for unrecognized" do
324
+ subject.driver = "bad-driver"
325
+
326
+ expect { subject.finalize! }.to raise_error("Require specify driver bad-driver")
327
+ end
328
+ end
329
+
330
+ context 'when invalid @uri is defined' do
331
+ it "should raise exception for unrecognized" do
332
+ subject.uri = "://bad-uri"
333
+
334
+ expect { subject.finalize! }.to raise_error("@uri set to invalid uri '://bad-uri'")
335
+ end
336
+ end
337
+ end
338
+
339
+ context '@proxy_command' do
340
+ before(:example) do
341
+ stub_const("ENV", fake_env)
342
+ fake_env['HOME'] = "/home/tests"
343
+ end
344
+
345
+ [
346
+ # no connect_via_ssh
347
+ [
348
+ {:host => "remote"},
349
+ nil,
350
+ ],
351
+
352
+ # connect_via_ssh
353
+ [ # host
354
+ {:connect_via_ssh => true, :host => 'remote'},
355
+ "ssh 'remote' -W %h:%p",
356
+ ],
357
+ [ # include user
358
+ {:connect_via_ssh => true, :host => 'remote', :username => 'myuser'},
359
+ "ssh 'remote' -l 'myuser' -W %h:%p",
360
+ ],
361
+ [ # include user and default ssh key exists
362
+ {:connect_via_ssh => true, :host => 'remote', :username => 'myuser'},
363
+ "ssh 'remote' -l 'myuser' -i '/home/tests/.ssh/id_rsa' -W %h:%p",
364
+ {
365
+ :setup => ContextualProc.new {
366
+ expect(File).to receive(:file?).with("/home/tests/.ssh/id_rsa").and_return(true)
367
+ }
368
+ }
369
+ ],
370
+
371
+ # disable id_ssh_key_file
372
+ [
373
+ {:connect_via_ssh => true, :host => 'remote', :id_ssh_key_file => nil},
374
+ "ssh 'remote' -W %h:%p",
375
+ ],
376
+ [ # include user
377
+ {:connect_via_ssh => true, :host => 'remote', :id_ssh_key_file => nil},
378
+ "ssh 'remote' -W %h:%p",
379
+ ],
380
+
381
+ # use @uri
382
+ [
383
+ {:uri => 'qemu+ssh://remote/system'},
384
+ "ssh 'remote' -W %h:%p",
385
+ ],
386
+ [
387
+ {:uri => 'qemu+ssh://myuser@remote/system'},
388
+ "ssh 'remote' -l 'myuser' -W %h:%p",
389
+ ],
390
+ [
391
+ {:uri => 'qemu+ssh://remote/system?keyfile=/some/path/to/keyfile'},
392
+ "ssh 'remote' -i '/some/path/to/keyfile' -W %h:%p",
393
+ {:allow_failure => "keyfile not yet inferred from uri"},
394
+ ],
395
+
396
+ # provide custom template
397
+ [
398
+ {:connect_via_ssh => true, :host => 'remote', :proxy_command => "ssh {host} nc %h %p" },
399
+ "ssh remote nc %h %p",
400
+ ],
401
+ [
402
+ {:connect_via_ssh => true, :host => 'remote', :username => 'myuser', :proxy_command => "ssh {host} nc %h %p" },
403
+ "ssh remote nc %h %p",
404
+ ],
405
+ [
406
+ {:connect_via_ssh => true, :host => 'remote', :username => 'myuser', :proxy_command => "ssh {host} -l {username} nc %h %p" },
407
+ "ssh remote -l myuser nc %h %p",
408
+ ],
409
+ ].each do |inputs, proxy_command, options|
410
+ opts = {}
411
+ opts.merge!(options) if options
412
+
413
+ it "should handle inputs #{inputs}" do
414
+ # allow some of these to fail for now if marked as such
415
+ if !opts[:allow_failure].nil?
416
+ pending(opts[:allow_failure])
417
+ end
418
+
419
+ if !opts[:setup].nil?
420
+ opts[:setup].apply(binding)
421
+ end
422
+
423
+ inputs.each do |k, v|
424
+ subject.instance_variable_set("@#{k}", v)
425
+ end
426
+
427
+ subject.finalize!
428
+
429
+ expect(subject.proxy_command).to eq(proxy_command)
430
+ end
431
+ end
432
+ end
433
+ end
434
+
9
435
  def assert_invalid
436
+ subject.finalize!
10
437
  errors = subject.validate(machine)
11
438
  raise "No errors: #{errors.inspect}" if errors.values.all?(&:empty?)
12
439
  end
13
440
 
14
441
  def assert_valid
442
+ subject.finalize!
15
443
  errors = subject.validate(machine)
16
444
  raise "Errors: #{errors.inspect}" unless errors.values.all?(&:empty?)
17
445
  end
@@ -109,5 +537,15 @@ describe VagrantPlugins::ProviderLibvirt::Config do
109
537
  end
110
538
  end
111
539
  end
540
+
541
+ context 'clock_timers' do
542
+ it 'should merge clock_timers' do
543
+ one.clock_timer(:name => 'rtc', :tickpolicy => 'catchup')
544
+ two.clock_timer(:name => 'hpet', :present => 'no')
545
+
546
+ expect(subject.clock_timers).to include(include(name: 'rtc'),
547
+ include(name: 'hpet'))
548
+ end
549
+ end
112
550
  end
113
551
  end