vagrant-libvirt 0.0.43 → 0.3.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 (67) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +434 -150
  3. data/lib/vagrant-libvirt/action.rb +2 -2
  4. data/lib/vagrant-libvirt/action/create_domain.rb +103 -38
  5. data/lib/vagrant-libvirt/action/create_domain_volume.rb +19 -14
  6. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +10 -5
  7. data/lib/vagrant-libvirt/action/create_networks.rb +7 -2
  8. data/lib/vagrant-libvirt/action/destroy_domain.rb +1 -1
  9. data/lib/vagrant-libvirt/action/destroy_networks.rb +5 -0
  10. data/lib/vagrant-libvirt/action/forward_ports.rb +9 -7
  11. data/lib/vagrant-libvirt/action/halt_domain.rb +1 -1
  12. data/lib/vagrant-libvirt/action/handle_box_image.rb +32 -18
  13. data/lib/vagrant-libvirt/action/handle_storage_pool.rb +9 -4
  14. data/lib/vagrant-libvirt/action/package_domain.rb +63 -12
  15. data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +3 -9
  16. data/lib/vagrant-libvirt/action/prune_nfs_exports.rb +19 -9
  17. data/lib/vagrant-libvirt/action/remove_libvirt_image.rb +2 -2
  18. data/lib/vagrant-libvirt/action/remove_stale_volume.rb +17 -11
  19. data/lib/vagrant-libvirt/action/set_boot_order.rb +2 -2
  20. data/lib/vagrant-libvirt/action/set_name_of_domain.rb +6 -9
  21. data/lib/vagrant-libvirt/action/start_domain.rb +3 -3
  22. data/lib/vagrant-libvirt/action/wait_till_up.rb +31 -16
  23. data/lib/vagrant-libvirt/cap/public_address.rb +16 -0
  24. data/lib/vagrant-libvirt/cap/synced_folder.rb +3 -3
  25. data/lib/vagrant-libvirt/config.rb +178 -29
  26. data/lib/vagrant-libvirt/driver.rb +31 -2
  27. data/lib/vagrant-libvirt/errors.rb +5 -1
  28. data/lib/vagrant-libvirt/plugin.rb +7 -2
  29. data/lib/vagrant-libvirt/templates/default_storage_pool.xml.erb +3 -3
  30. data/lib/vagrant-libvirt/templates/domain.xml.erb +48 -8
  31. data/lib/vagrant-libvirt/templates/public_interface.xml.erb +5 -1
  32. data/lib/vagrant-libvirt/util.rb +2 -0
  33. data/lib/vagrant-libvirt/util/erb_template.rb +6 -7
  34. data/lib/vagrant-libvirt/util/network_util.rb +33 -13
  35. data/lib/vagrant-libvirt/util/nfs.rb +17 -0
  36. data/lib/vagrant-libvirt/util/storage_util.rb +27 -0
  37. data/lib/vagrant-libvirt/util/ui.rb +23 -0
  38. data/lib/vagrant-libvirt/version +1 -0
  39. data/lib/vagrant-libvirt/version.rb +24 -1
  40. data/locales/en.yml +8 -4
  41. data/spec/support/environment_helper.rb +1 -1
  42. data/spec/support/libvirt_context.rb +1 -1
  43. data/spec/support/sharedcontext.rb +3 -3
  44. data/spec/unit/action/create_domain_spec.rb +85 -0
  45. data/spec/unit/action/create_domain_spec/default_storage_pool.xml +17 -0
  46. data/spec/unit/action/destroy_domain_spec.rb +2 -2
  47. data/spec/unit/action/set_name_of_domain_spec.rb +3 -3
  48. data/spec/unit/action/start_domain_spec.rb +49 -0
  49. data/spec/unit/action/start_domain_spec/default.xml +48 -0
  50. data/spec/unit/config_spec.rb +173 -0
  51. data/spec/unit/templates/domain_all_settings.xml +20 -4
  52. data/spec/unit/templates/domain_custom_cpu_model.xml +48 -0
  53. data/spec/unit/templates/domain_defaults.xml +2 -0
  54. data/spec/unit/templates/domain_spec.rb +26 -2
  55. metadata +34 -32
  56. data/.coveralls.yml +0 -1
  57. data/.github/issue_template.md +0 -37
  58. data/.gitignore +0 -21
  59. data/.travis.yml +0 -24
  60. data/Gemfile +0 -26
  61. data/Rakefile +0 -8
  62. data/example_box/README.md +0 -29
  63. data/example_box/Vagrantfile +0 -60
  64. data/example_box/metadata.json +0 -5
  65. data/tools/create_box.sh +0 -130
  66. data/tools/prepare_redhat_for_box.sh +0 -119
  67. data/vagrant-libvirt.gemspec +0 -54
@@ -23,7 +23,7 @@ module VagrantPlugins
23
23
 
24
24
  libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(env[:machine].id)
25
25
 
26
- # libvirt API doesn't support modifying memory on NUMA enabled CPUs
26
+ # Libvirt API doesn't support modifying memory on NUMA enabled CPUs
27
27
  # http://libvirt.org/git/?p=libvirt.git;a=commit;h=d174394105cf00ed266bf729ddf461c21637c736
28
28
  if config.numa_nodes == nil
29
29
  if config.memory.to_i * 1024 != libvirt_domain.max_memory
@@ -68,7 +68,7 @@ module VagrantPlugins
68
68
  end
69
69
 
70
70
  # vCpu count
71
- if config.cpus.to_i != libvirt_domain.vcpus.length
71
+ if config.cpus.to_i != libvirt_domain.num_vcpus(0)
72
72
  descr_changed = true
73
73
  REXML::XPath.first(xml_descr, '/domain/vcpu').text = config.cpus
74
74
  end
@@ -94,7 +94,7 @@ module VagrantPlugins
94
94
  cpu_model.attributes['fallback'] = 'allow'
95
95
  cpu_model.text = config.cpu_model
96
96
  else
97
- if cpu_model.text != config.cpu_model
97
+ if cpu_model.text.strip != config.cpu_model.strip
98
98
  descr_changed = true
99
99
  cpu_model.text = config.cpu_model
100
100
  end
@@ -28,25 +28,42 @@ module VagrantPlugins
28
28
  end
29
29
 
30
30
  # Wait for domain to obtain an ip address. Ip address is searched
31
- # from arp table, either localy or remotely via ssh, if libvirt
31
+ # from arp table, either locally or remotely via ssh, if Libvirt
32
32
  # connection was done via ssh.
33
33
  env[:ip_address] = nil
34
- env[:metrics]['instance_ip_time'] = Util::Timer.time do
35
- @logger.debug("Searching for IP for MAC address: #{domain.mac}")
36
- env[:ui].info(I18n.t('vagrant_libvirt.waiting_for_ip'))
37
- retryable(on: Fog::Errors::TimeoutError, tries: 300) do
38
- # If we're interrupted don't worry about waiting
39
- return terminate(env) if env[:interrupted]
34
+ @logger.debug("Searching for IP for MAC address: #{domain.mac}")
35
+ env[:ui].info(I18n.t('vagrant_libvirt.waiting_for_ip'))
36
+
37
+ if env[:machine].provider_config.qemu_use_session
38
+ env[:metrics]['instance_ip_time'] = Util::Timer.time do
39
+ retryable(on: Fog::Errors::TimeoutError, tries: 300) do
40
+ # just return if interrupted and let the warden call recover
41
+ return if env[:interrupted]
42
+
43
+ # Wait for domain to obtain an ip address
44
+ domain.wait_for(2) do
45
+ env[:ip_address] = env[:machine].provider.driver.get_ipaddress_system(domain.mac)
46
+ !env[:ip_address].nil?
47
+ end
48
+ end
49
+ end
50
+ else
51
+ env[:metrics]['instance_ip_time'] = Util::Timer.time do
52
+ retryable(on: Fog::Errors::TimeoutError, tries: 300) do
53
+ # just return if interrupted and let the warden call recover
54
+ return if env[:interrupted]
40
55
 
41
- # Wait for domain to obtain an ip address
42
- domain.wait_for(2) do
43
- addresses.each_pair do |_type, ip|
44
- env[:ip_address] = ip[0] unless ip[0].nil?
56
+ # Wait for domain to obtain an ip address
57
+ domain.wait_for(2) do
58
+ addresses.each_pair do |_type, ip|
59
+ env[:ip_address] = ip[0] unless ip[0].nil?
60
+ end
61
+ !env[:ip_address].nil?
45
62
  end
46
- !env[:ip_address].nil?
47
63
  end
48
64
  end
49
65
  end
66
+
50
67
  @logger.info("Got IP address #{env[:ip_address]}")
51
68
  @logger.info("Time for getting IP: #{env[:metrics]['instance_ip_time']}")
52
69
 
@@ -67,8 +84,8 @@ module VagrantPlugins
67
84
  end
68
85
  end
69
86
  end
70
- # if interrupted above, just terminate immediately
71
- return terminate(env) if env[:interrupted]
87
+ # just return if interrupted and let the warden call recover
88
+ return if env[:interrupted]
72
89
  @logger.info("Time for SSH ready: #{env[:metrics]['instance_ssh_time']}")
73
90
 
74
91
  # Booted and ready for use.
@@ -78,8 +95,6 @@ module VagrantPlugins
78
95
  end
79
96
 
80
97
  def recover(env)
81
- return if env['vagrant.error'].is_a?(Vagrant::Errors::VagrantError)
82
-
83
98
  # Undo the import
84
99
  terminate(env)
85
100
  end
@@ -0,0 +1,16 @@
1
+ module VagrantPlugins
2
+ module ProviderLibvirt
3
+ module Cap
4
+ class PublicAddress
5
+ def self.public_address(machine)
6
+ # This does not need to be a globally routable address, it
7
+ # only needs to be accessible from the machine running
8
+ # Vagrant.
9
+ ssh_info = machine.ssh_info
10
+ return nil if !ssh_info
11
+ ssh_info[:host]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -20,7 +20,7 @@ module VagrantPlugins
20
20
  end
21
21
 
22
22
  def usable?(machine, _raise_error = false)
23
- # bail now if not using libvirt since checking version would throw error
23
+ # bail now if not using Libvirt since checking version would throw error
24
24
  return false unless machine.provider_name == :libvirt
25
25
 
26
26
  # <filesystem/> support in device attach/detach introduced in 1.2.2
@@ -30,7 +30,7 @@ module VagrantPlugins
30
30
  end
31
31
 
32
32
  def prepare(machine, folders, _opts)
33
- raise Vagrant::Errors::Error('No libvirt connection') if machine.provider.driver.connection.nil?
33
+ raise Vagrant::Errors::Error('No Libvirt connection') if machine.provider.driver.connection.nil?
34
34
  @conn = machine.provider.driver.connection.client
35
35
 
36
36
  begin
@@ -89,7 +89,7 @@ module VagrantPlugins
89
89
 
90
90
  def cleanup(machine, _opts)
91
91
  if machine.provider.driver.connection.nil?
92
- raise Vagrant::Errors::Error('No libvirt connection')
92
+ raise Vagrant::Errors::Error('No Libvirt connection')
93
93
  end
94
94
  @conn = machine.provider.driver.connection.client
95
95
  begin
@@ -20,12 +20,12 @@ module VagrantPlugins
20
20
  # A hypervisor name to access via Libvirt.
21
21
  attr_accessor :driver
22
22
 
23
- # The name of the server, where libvirtd is running.
23
+ # The name of the server, where Libvirtd is running.
24
24
  attr_accessor :host
25
25
 
26
26
  # If use ssh tunnel to connect to Libvirt.
27
27
  attr_accessor :connect_via_ssh
28
- # Path towards the libvirt socket
28
+ # Path towards the Libvirt socket
29
29
  attr_accessor :socket
30
30
 
31
31
  # The username to access Libvirt.
@@ -40,11 +40,16 @@ module VagrantPlugins
40
40
  # Libvirt storage pool name, where box image and instance snapshots will
41
41
  # be stored.
42
42
  attr_accessor :storage_pool_name
43
+ attr_accessor :storage_pool_path
44
+
45
+ # Libvirt storage pool where the base image snapshot shall be stored
46
+ attr_accessor :snapshot_pool_name
43
47
 
44
48
  # Turn on to prevent hostname conflicts
45
49
  attr_accessor :random_hostname
46
50
 
47
51
  # Libvirt default network
52
+ attr_accessor :management_network_device
48
53
  attr_accessor :management_network_name
49
54
  attr_accessor :management_network_address
50
55
  attr_accessor :management_network_mode
@@ -53,24 +58,35 @@ module VagrantPlugins
53
58
  attr_accessor :management_network_autostart
54
59
  attr_accessor :management_network_pci_bus
55
60
  attr_accessor :management_network_pci_slot
61
+ attr_accessor :management_network_domain
62
+
63
+ # System connection information
64
+ attr_accessor :system_uri
56
65
 
57
66
  # Default host prefix (alternative to use project folder name)
58
67
  attr_accessor :default_prefix
59
68
 
60
69
  # Domain specific settings used while creating new domain.
70
+ attr_accessor :title
71
+ attr_accessor :description
61
72
  attr_accessor :uuid
62
73
  attr_accessor :memory
74
+ attr_accessor :nodeset
63
75
  attr_accessor :memory_backing
64
76
  attr_accessor :channel
65
77
  attr_accessor :cpus
78
+ attr_accessor :cpuset
66
79
  attr_accessor :cpu_mode
67
80
  attr_accessor :cpu_model
68
81
  attr_accessor :cpu_fallback
69
82
  attr_accessor :cpu_features
70
83
  attr_accessor :cpu_topology
84
+ attr_accessor :shares
71
85
  attr_accessor :features
86
+ attr_accessor :features_hyperv
72
87
  attr_accessor :numa_nodes
73
88
  attr_accessor :loader
89
+ attr_accessor :nvram
74
90
  attr_accessor :boot_order
75
91
  attr_accessor :machine_type
76
92
  attr_accessor :machine_arch
@@ -126,6 +142,9 @@ module VagrantPlugins
126
142
  # Watchdog device
127
143
  attr_accessor :watchdog_dev
128
144
 
145
+ # USB controller
146
+ attr_accessor :usbctl_dev
147
+
129
148
  # USB device passthrough
130
149
  attr_accessor :usbs
131
150
 
@@ -148,6 +167,12 @@ module VagrantPlugins
148
167
  # Additional qemuargs arguments
149
168
  attr_accessor :qemu_args
150
169
 
170
+ # Additional qemuenv arguments
171
+ attr_accessor :qemu_env
172
+
173
+ # Use QEMU session instead of system
174
+ attr_accessor :qemu_use_session
175
+
151
176
  def initialize
152
177
  @uri = UNSET_VALUE
153
178
  @driver = UNSET_VALUE
@@ -157,7 +182,9 @@ module VagrantPlugins
157
182
  @password = UNSET_VALUE
158
183
  @id_ssh_key_file = UNSET_VALUE
159
184
  @storage_pool_name = UNSET_VALUE
185
+ @snapshot_pool_name = UNSET_VALUE
160
186
  @random_hostname = UNSET_VALUE
187
+ @management_network_device = UNSET_VALUE
161
188
  @management_network_name = UNSET_VALUE
162
189
  @management_network_address = UNSET_VALUE
163
190
  @management_network_mode = UNSET_VALUE
@@ -166,20 +193,31 @@ module VagrantPlugins
166
193
  @management_network_autostart = UNSET_VALUE
167
194
  @management_network_pci_slot = UNSET_VALUE
168
195
  @management_network_pci_bus = UNSET_VALUE
196
+ @management_network_domain = UNSET_VALUE
197
+
198
+ # System connection information
199
+ @system_uri = UNSET_VALUE
169
200
 
170
201
  # Domain specific settings.
202
+ @title = UNSET_VALUE
203
+ @description = UNSET_VALUE
171
204
  @uuid = UNSET_VALUE
172
205
  @memory = UNSET_VALUE
206
+ @nodeset = UNSET_VALUE
173
207
  @memory_backing = UNSET_VALUE
174
208
  @cpus = UNSET_VALUE
209
+ @cpuset = UNSET_VALUE
175
210
  @cpu_mode = UNSET_VALUE
176
211
  @cpu_model = UNSET_VALUE
177
212
  @cpu_fallback = UNSET_VALUE
178
213
  @cpu_features = UNSET_VALUE
179
214
  @cpu_topology = UNSET_VALUE
215
+ @shares = UNSET_VALUE
180
216
  @features = UNSET_VALUE
217
+ @features_hyperv = UNSET_VALUE
181
218
  @numa_nodes = UNSET_VALUE
182
219
  @loader = UNSET_VALUE
220
+ @nvram = UNSET_VALUE
183
221
  @machine_type = UNSET_VALUE
184
222
  @machine_arch = UNSET_VALUE
185
223
  @machine_virtual_size = UNSET_VALUE
@@ -231,6 +269,9 @@ module VagrantPlugins
231
269
  # Watchdog device
232
270
  @watchdog_dev = UNSET_VALUE
233
271
 
272
+ # USB controller
273
+ @usbctl_dev = UNSET_VALUE
274
+
234
275
  # USB device passthrough
235
276
  @usbs = UNSET_VALUE
236
277
 
@@ -250,7 +291,13 @@ module VagrantPlugins
250
291
  # Attach mgmt network
251
292
  @mgmt_attach = UNSET_VALUE
252
293
 
253
- @qemu_args = []
294
+ # Additional QEMU commandline arguments
295
+ @qemu_args = UNSET_VALUE
296
+
297
+ # Additional QEMU commandline environment variables
298
+ @qemu_env = UNSET_VALUE
299
+
300
+ @qemu_use_session = UNSET_VALUE
254
301
  end
255
302
 
256
303
  def boot(device)
@@ -282,7 +329,7 @@ module VagrantPlugins
282
329
  end
283
330
  end
284
331
 
285
- # is it better to raise our own error, or let libvirt cause the exception?
332
+ # is it better to raise our own error, or let Libvirt cause the exception?
286
333
  raise 'Only four cdroms may be attached at a time'
287
334
  end
288
335
 
@@ -321,6 +368,17 @@ module VagrantPlugins
321
368
  policy: options[:policy])
322
369
  end
323
370
 
371
+ def hyperv_feature(options = {})
372
+ if options[:name].nil? || options[:state].nil?
373
+ raise 'Feature name AND state must be specified'
374
+ end
375
+
376
+ @features_hyperv = [] if @features_hyperv == UNSET_VALUE
377
+
378
+ @features_hyperv.push(name: options[:name],
379
+ state: options[:state])
380
+ end
381
+
324
382
  def cputopology(options = {})
325
383
  if options[:sockets].nil? || options[:cores].nil? || options[:threads].nil?
326
384
  raise 'CPU topology must have all of sockets, cores and threads specified'
@@ -332,7 +390,7 @@ module VagrantPlugins
332
390
 
333
391
  @cpu_topology[:sockets] = options[:sockets]
334
392
  @cpu_topology[:cores] = options[:cores]
335
- @cpu_topology[:threads] = options[:threads]
393
+ @cpu_topology[:threads] = options[:threads]
336
394
  end
337
395
 
338
396
  def memorybacking(option, config = {})
@@ -400,7 +458,14 @@ module VagrantPlugins
400
458
 
401
459
  @pcis = [] if @pcis == UNSET_VALUE
402
460
 
403
- @pcis.push(bus: options[:bus],
461
+ if options[:domain].nil?
462
+ pci_domain = '0x0000'
463
+ else
464
+ pci_domain = options[:domain]
465
+ end
466
+
467
+ @pcis.push(domain: pci_domain,
468
+ bus: options[:bus],
404
469
  slot: options[:slot],
405
470
  function: options[:function])
406
471
  end
@@ -419,6 +484,19 @@ module VagrantPlugins
419
484
  end
420
485
 
421
486
 
487
+ def usb_controller(options = {})
488
+ if options[:model].nil?
489
+ raise 'USB controller model must be specified.'
490
+ end
491
+
492
+ if @usbctl_dev == UNSET_VALUE
493
+ @usbctl_dev = {}
494
+ end
495
+
496
+ @usbctl_dev[:model] = options[:model]
497
+ @usbctl_dev[:ports] = options[:ports]
498
+ end
499
+
422
500
  def usb(options = {})
423
501
  if (options[:bus].nil? || options[:device].nil?) && options[:vendor].nil? && options[:product].nil?
424
502
  raise 'Bus and device and/or vendor and/or product must be specified. Check `lsusb` for these.'
@@ -447,9 +525,9 @@ module VagrantPlugins
447
525
  @redirfilters = [] if @redirfilters == UNSET_VALUE
448
526
 
449
527
  @redirfilters.push(class: options[:class] || -1,
450
- vendor: options[:class] || -1,
451
- product: options[:class] || -1,
452
- version: options[:class] || -1,
528
+ vendor: options[:vendor] || -1,
529
+ product: options[:product] || -1,
530
+ version: options[:version] || -1,
453
531
  allow: options[:allow])
454
532
  end
455
533
 
@@ -526,23 +604,42 @@ module VagrantPlugins
526
604
  cache: options[:cache] || 'default',
527
605
  allow_existing: options[:allow_existing],
528
606
  shareable: options[:shareable],
529
- serial: options[:serial]
607
+ serial: options[:serial],
608
+ pool: options[:pool], # overrides storage_pool setting for additional disks
609
+ wwn: options[:wwn],
530
610
  }
531
611
 
532
612
  @disks << disk # append
533
613
  end
534
614
 
535
615
  def qemuargs(options = {})
616
+ @qemu_args = [] if @qemu_args == UNSET_VALUE
617
+
536
618
  @qemu_args << options if options[:value]
537
619
  end
538
620
 
539
- # code to generate URI from a config moved out of the connect action
540
- def _generate_uri
541
- # builds the libvirt connection URI from the given driver config
621
+ def qemuenv(options = {})
622
+ @qemu_env = {} if @qemu_env == UNSET_VALUE
623
+
624
+ @qemu_env.merge!(options)
625
+ end
626
+
627
+ # code to generate URI from from either the LIBVIRT_URI environment
628
+ # variable or a config moved out of the connect action
629
+ def _generate_uri(qemu_use_session)
630
+
631
+ # If the LIBVIRT_DEFAULT_URI var is set, we'll use that
632
+ if ENV.fetch('LIBVIRT_DEFAULT_URI', '') != ""
633
+ return ENV['LIBVIRT_DEFAULT_URI']
634
+ end
635
+
636
+ # builds the Libvirt connection URI from the given driver config
542
637
  # Setup connection uri.
543
638
  uri = @driver.dup
544
639
  virt_path = case uri
545
- when 'qemu', 'openvz', 'uml', 'phyp', 'parallels', 'kvm'
640
+ when 'qemu', 'kvm'
641
+ qemu_use_session ? '/session' : '/system'
642
+ when 'openvz', 'uml', 'phyp', 'parallels'
546
643
  '/system'
547
644
  when '@en', 'esx'
548
645
  '/'
@@ -552,38 +649,44 @@ module VagrantPlugins
552
649
  raise "Require specify driver #{uri}"
553
650
  end
554
651
  if uri == 'kvm'
555
- uri = 'qemu' # use qemu uri for kvm domain type
652
+ uri = 'qemu' # use QEMU uri for KVM domain type
556
653
  end
557
654
 
558
655
  if @connect_via_ssh
559
656
  uri << '+ssh://'
560
657
  uri << @username + '@' if @username
561
658
 
562
- uri << if @host
563
- @host
564
- else
565
- 'localhost'
566
- end
659
+ uri << ( @host ? @host : 'localhost' )
567
660
  else
568
661
  uri << '://'
569
662
  uri << @host if @host
570
663
  end
571
664
 
572
665
  uri << virt_path
573
- uri << '?no_verify=1'
666
+
667
+ params = {'no_verify' => '1'}
574
668
 
575
669
  if @id_ssh_key_file
576
- # set ssh key for access to libvirt host
577
- uri << "\&keyfile="
670
+ # set ssh key for access to Libvirt host
578
671
  # if no slash, prepend $HOME/.ssh/
579
- @id_ssh_key_file.prepend("#{`echo ${HOME}`.chomp}/.ssh/") if @id_ssh_key_file !~ /\A\//
580
- uri << @id_ssh_key_file
672
+ @id_ssh_key_file.prepend("#{ENV['HOME']}/.ssh/") if @id_ssh_key_file !~ /\A\//
673
+ params['keyfile'] = @id_ssh_key_file
581
674
  end
582
- # set path to libvirt socket
583
- uri << "\&socket=" + @socket if @socket
675
+ # set path to Libvirt socket
676
+ params['socket'] = @socket if @socket
677
+
678
+ uri << "?" + params.map{|pair| pair.join('=')}.join('&')
584
679
  uri
585
680
  end
586
681
 
682
+ def _parse_uri(uri)
683
+ begin
684
+ URI.parse(uri)
685
+ rescue
686
+ raise "@uri set to invalid uri '#{uri}'"
687
+ end
688
+ end
689
+
587
690
  def finalize!
588
691
  @driver = 'kvm' if @driver == UNSET_VALUE
589
692
  @host = nil if @host == UNSET_VALUE
@@ -592,7 +695,10 @@ module VagrantPlugins
592
695
  @password = nil if @password == UNSET_VALUE
593
696
  @id_ssh_key_file = 'id_rsa' if @id_ssh_key_file == UNSET_VALUE
594
697
  @storage_pool_name = 'default' if @storage_pool_name == UNSET_VALUE
698
+ @snapshot_pool_name = @storage_pool_name if @snapshot_pool_name == UNSET_VALUE
699
+ @storage_pool_path = nil if @storage_pool_path == UNSET_VALUE
595
700
  @random_hostname = false if @random_hostname == UNSET_VALUE
701
+ @management_network_device = 'virbr0' if @management_network_device == UNSET_VALUE
596
702
  @management_network_name = 'vagrant-libvirt' if @management_network_name == UNSET_VALUE
597
703
  @management_network_address = '192.168.121.0/24' if @management_network_address == UNSET_VALUE
598
704
  @management_network_mode = 'nat' if @management_network_mode == UNSET_VALUE
@@ -601,27 +707,51 @@ module VagrantPlugins
601
707
  @management_network_autostart = false if @management_network_autostart == UNSET_VALUE
602
708
  @management_network_pci_bus = nil if @management_network_pci_bus == UNSET_VALUE
603
709
  @management_network_pci_slot = nil if @management_network_pci_slot == UNSET_VALUE
710
+ @management_network_domain = nil if @management_network_domain == UNSET_VALUE
711
+ @system_uri = 'qemu:///system' if @system_uri == UNSET_VALUE
712
+
713
+ # If uri isn't set then let's build one from various sources.
714
+ # Default to passing false for qemu_use_session if it's not set.
715
+ if @uri == UNSET_VALUE
716
+ @uri = _generate_uri(@qemu_use_session == UNSET_VALUE ? false : @qemu_use_session)
717
+ end
604
718
 
605
- # generate a URI if none is supplied
606
- @uri = _generate_uri if @uri == UNSET_VALUE
719
+ # Set qemu_use_session based on the URI if it wasn't set by the user
720
+ if @qemu_use_session == UNSET_VALUE
721
+ uri = _parse_uri(@uri)
722
+ if (uri.scheme.start_with? "qemu") && (uri.path.include? "session")
723
+ @qemu_use_session = true
724
+ else
725
+ @qemu_use_session = false
726
+ end
727
+ end
607
728
 
608
729
  # Domain specific settings.
730
+ @title = '' if @title == UNSET_VALUE
731
+ @description = '' if @description == UNSET_VALUE
609
732
  @uuid = '' if @uuid == UNSET_VALUE
610
733
  @memory = 512 if @memory == UNSET_VALUE
734
+ @nodeset = nil if @nodeset == UNSET_VALUE
611
735
  @memory_backing = [] if @memory_backing == UNSET_VALUE
612
736
  @cpus = 1 if @cpus == UNSET_VALUE
737
+ @cpuset = nil if @cpuset == UNSET_VALUE
613
738
  @cpu_mode = 'host-model' if @cpu_mode == UNSET_VALUE
614
739
  @cpu_model = if (@cpu_model == UNSET_VALUE) && (@cpu_mode == 'custom')
615
740
  'qemu64'
616
741
  elsif @cpu_mode != 'custom'
617
742
  ''
743
+ else
744
+ @cpu_model
618
745
  end
619
746
  @cpu_topology = {} if @cpu_topology == UNSET_VALUE
620
747
  @cpu_fallback = 'allow' if @cpu_fallback == UNSET_VALUE
621
748
  @cpu_features = [] if @cpu_features == UNSET_VALUE
749
+ @shares = nil if @shares == UNSET_VALUE
622
750
  @features = ['acpi','apic','pae'] if @features == UNSET_VALUE
751
+ @features_hyperv = [] if @features_hyperv == UNSET_VALUE
623
752
  @numa_nodes = @numa_nodes == UNSET_VALUE ? nil : _generate_numa
624
753
  @loader = nil if @loader == UNSET_VALUE
754
+ @nvram = nil if @nvram == UNSET_VALUE
625
755
  @machine_type = nil if @machine_type == UNSET_VALUE
626
756
  @machine_arch = nil if @machine_arch == UNSET_VALUE
627
757
  @machine_virtual_size = nil if @machine_virtual_size == UNSET_VALUE
@@ -684,6 +814,9 @@ module VagrantPlugins
684
814
  # Watchdog device
685
815
  @watchdog_dev = {} if @watchdog_dev == UNSET_VALUE
686
816
 
817
+ # USB controller
818
+ @usbctl_dev = {} if @usbctl_dev == UNSET_VALUE
819
+
687
820
  # USB device passthrough
688
821
  @usbs = [] if @usbs == UNSET_VALUE
689
822
 
@@ -703,12 +836,24 @@ module VagrantPlugins
703
836
  # Attach mgmt network
704
837
  @mgmt_attach = true if @mgmt_attach == UNSET_VALUE
705
838
 
839
+ # Additional QEMU commandline arguments
706
840
  @qemu_args = [] if @qemu_args == UNSET_VALUE
841
+
842
+ # Additional QEMU commandline environment variables
843
+ @qemu_env = {} if @qemu_env == UNSET_VALUE
707
844
  end
708
845
 
709
846
  def validate(machine)
710
847
  errors = _detected_errors
711
848
 
849
+ # The @uri and @qemu_use_session should not conflict
850
+ uri = _parse_uri(@uri)
851
+ if (uri.scheme.start_with? "qemu") && (uri.path.include? "session")
852
+ if @qemu_use_session != true
853
+ errors << "the URI and qemu_use_session configuration conflict: uri:'#{@uri}' qemu_use_session:'#{@qemu_use_session}'"
854
+ end
855
+ end
856
+
712
857
  machine.provider_config.disks.each do |disk|
713
858
  if disk[:path] && (disk[:path][0] == '/')
714
859
  errors << "absolute volume paths like '#{disk[:path]}' not yet supported"
@@ -739,6 +884,10 @@ module VagrantPlugins
739
884
  c = cdroms.dup
740
885
  c += other.cdroms
741
886
  result.cdroms = c
887
+
888
+ c = qemu_env != UNSET_VALUE ? qemu_env.dup : {}
889
+ c.merge!(other.qemu_env) if other.qemu_env != UNSET_VALUE
890
+ result.qemu_env = c
742
891
  end
743
892
  end
744
893
  end