vagrant-libvirt 0.0.43 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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