vagrant-libvirt 0.10.8 → 0.11.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +44 -7
  3. data/lib/vagrant-libvirt/action/create_domain.rb +45 -22
  4. data/lib/vagrant-libvirt/action/create_domain_volume.rb +3 -0
  5. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +15 -5
  6. data/lib/vagrant-libvirt/action/create_networks.rb +2 -6
  7. data/lib/vagrant-libvirt/action/destroy_domain.rb +2 -10
  8. data/lib/vagrant-libvirt/action/forward_ports.rb +1 -1
  9. data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +7 -5
  10. data/lib/vagrant-libvirt/action/resolve_disk_settings.rb +2 -0
  11. data/lib/vagrant-libvirt/action/snapshot_delete.rb +1 -1
  12. data/lib/vagrant-libvirt/action/snapshot_restore.rb +1 -1
  13. data/lib/vagrant-libvirt/action/snapshot_save.rb +1 -2
  14. data/lib/vagrant-libvirt/action/start_domain.rb +149 -62
  15. data/lib/vagrant-libvirt/action/wait_till_up.rb +2 -2
  16. data/lib/vagrant-libvirt/action.rb +18 -13
  17. data/lib/vagrant-libvirt/cap/mount_9p.rb +9 -1
  18. data/lib/vagrant-libvirt/cap/snapshots.rb +1 -1
  19. data/lib/vagrant-libvirt/config.rb +198 -26
  20. data/lib/vagrant-libvirt/driver.rb +94 -55
  21. data/lib/vagrant-libvirt/provider.rb +4 -4
  22. data/lib/vagrant-libvirt/templates/domain.xml.erb +73 -27
  23. data/lib/vagrant-libvirt/templates/public_interface.xml.erb +6 -3
  24. data/lib/vagrant-libvirt/util/network_util.rb +5 -10
  25. data/lib/vagrant-libvirt/version +1 -1
  26. data/locales/en.yml +2 -0
  27. data/spec/acceptance/additional_storage_spec.rb +1 -4
  28. data/spec/acceptance/networking_spec.rb +41 -0
  29. data/spec/acceptance/package_domain_spec.rb +2 -2
  30. data/spec/acceptance/provider_settings_spec.rb +1 -1
  31. data/spec/acceptance/simple_vm_provision_via_shell_spec.rb +1 -1
  32. data/spec/acceptance/snapshots_spec.rb +1 -1
  33. data/spec/acceptance/two_disks_spec.rb +1 -1
  34. data/spec/acceptance/use_qemu_agent_for_connectivity_spec.rb +1 -1
  35. data/spec/spec_helper.rb +31 -8
  36. data/spec/support/acceptance/isolated_environment.rb +1 -1
  37. data/spec/support/environment_helper.rb +1 -1
  38. data/spec/support/libvirt_acceptance_context.rb +15 -1
  39. data/spec/support/{sharedcontext.rb → unit_context.rb} +20 -5
  40. data/spec/unit/action/clean_machine_folder_spec.rb +1 -2
  41. data/spec/unit/action/cleanup_on_failure_spec.rb +1 -2
  42. data/spec/unit/action/create_domain_spec/additional_disks_domain.xml +4 -2
  43. data/spec/unit/action/create_domain_spec/custom_disk_settings.xml +4 -2
  44. data/spec/unit/action/create_domain_spec/default_domain.xml +4 -2
  45. data/spec/unit/action/create_domain_spec/sysinfo.xml +4 -2
  46. data/spec/unit/action/create_domain_spec/sysinfo_only_required.xml +4 -2
  47. data/spec/unit/action/create_domain_spec/two_disk_settings.xml +4 -2
  48. data/spec/unit/action/create_domain_spec.rb +51 -3
  49. data/spec/unit/action/create_domain_volume_spec.rb +2 -4
  50. data/spec/unit/action/destroy_domain_spec/additional_disks_domain.xml +1 -0
  51. data/spec/unit/action/destroy_domain_spec/box_multiple_disks.xml +1 -0
  52. data/spec/unit/action/destroy_domain_spec/box_multiple_disks_and_additional_and_custom_disks.xml +1 -0
  53. data/spec/unit/action/destroy_domain_spec/box_multiple_disks_and_additional_and_custom_disks_no_aliases.xml +1 -0
  54. data/spec/unit/action/destroy_domain_spec/box_multiple_disks_and_additional_disks.xml +1 -0
  55. data/spec/unit/action/destroy_domain_spec/cdrom_domain.xml +1 -0
  56. data/spec/unit/action/destroy_domain_spec.rb +1 -18
  57. data/spec/unit/action/forward_ports_spec.rb +1 -3
  58. data/spec/unit/action/halt_domain_spec.rb +2 -3
  59. data/spec/unit/action/handle_box_image_spec.rb +3 -4
  60. data/spec/unit/action/package_domain_spec.rb +2 -3
  61. data/spec/unit/action/prepare_nfs_settings_spec.rb +25 -9
  62. data/spec/unit/action/remove_libvirt_image_spec.rb +1 -2
  63. data/spec/unit/action/resolve_disk_settings_spec/default_domain.xml +1 -0
  64. data/spec/unit/action/resolve_disk_settings_spec/default_no_aliases.xml +1 -0
  65. data/spec/unit/action/resolve_disk_settings_spec/multi_volume_box.xml +1 -0
  66. data/spec/unit/action/resolve_disk_settings_spec/multi_volume_box_additional_and_custom_no_aliases.xml +1 -0
  67. data/spec/unit/action/resolve_disk_settings_spec/multi_volume_box_additional_storage.xml +1 -0
  68. data/spec/unit/action/resolve_disk_settings_spec.rb +1 -1
  69. data/spec/unit/action/set_boot_order_spec/default.xml +1 -0
  70. data/spec/unit/action/set_boot_order_spec/explicit_boot_order.xml +1 -0
  71. data/spec/unit/action/set_boot_order_spec.rb +1 -3
  72. data/spec/unit/action/set_name_of_domain_spec.rb +3 -1
  73. data/spec/unit/action/shutdown_domain_spec.rb +4 -3
  74. data/spec/unit/action/start_domain_spec/clock_timer_removed.xml +1 -1
  75. data/spec/unit/action/start_domain_spec/clock_timer_rtc.xml +1 -1
  76. data/spec/unit/action/start_domain_spec/clock_timer_rtc_tsc.xml +1 -1
  77. data/spec/unit/action/start_domain_spec/default.xml +1 -1
  78. data/spec/unit/action/start_domain_spec/default_added_tpm_path.xml +1 -1
  79. data/spec/unit/action/start_domain_spec/default_added_tpm_version.xml +1 -1
  80. data/spec/unit/action/start_domain_spec/default_with_different_formatting.xml +1 -1
  81. data/spec/unit/action/start_domain_spec/existing.xml +2 -1
  82. data/spec/unit/action/start_domain_spec/existing_added_nvram.xml +2 -1
  83. data/spec/unit/action/start_domain_spec/existing_reordered.xml +2 -1
  84. data/spec/unit/action/start_domain_spec/nvram_domain.xml +1 -0
  85. data/spec/unit/action/start_domain_spec/nvram_domain_other_setting.xml +2 -1
  86. data/spec/unit/action/start_domain_spec/nvram_domain_removed.xml +2 -1
  87. data/spec/unit/action/start_domain_spec.rb +192 -3
  88. data/spec/unit/action/wait_till_up_spec.rb +3 -5
  89. data/spec/unit/action_spec.rb +403 -10
  90. data/spec/unit/cap/mount_9p_spec.rb +75 -0
  91. data/spec/unit/cap/synced_folder_9p_spec.rb +1 -2
  92. data/spec/unit/cap/synced_folder_virtiofs_spec.rb +1 -2
  93. data/spec/unit/config_spec.rb +365 -25
  94. data/spec/unit/driver_spec.rb +217 -80
  95. data/spec/unit/plugin_spec.rb +6 -3
  96. data/spec/unit/templates/domain_all_settings.xml +26 -4
  97. data/spec/unit/templates/domain_cpu_mode_passthrough.xml +4 -2
  98. data/spec/unit/templates/domain_custom_cpu_model.xml +4 -2
  99. data/spec/unit/templates/domain_defaults.xml +4 -2
  100. data/spec/unit/templates/domain_scsi_bus_storage.xml +4 -2
  101. data/spec/unit/templates/domain_scsi_device_storage.xml +4 -2
  102. data/spec/unit/templates/domain_scsi_multiple_controllers_storage.xml +4 -2
  103. data/spec/unit/templates/domain_spec.rb +11 -3
  104. data/spec/unit/templates/tpm/version_1.2.xml +4 -2
  105. data/spec/unit/templates/tpm/version_2.0.xml +4 -2
  106. data/spec/unit/util/byte_number_spec.rb +1 -1
  107. data/spec/unit/util/network_util_spec/default.xml +16 -0
  108. data/spec/unit/util/network_util_spec/hostdev.xml +6 -0
  109. data/spec/unit/util/network_util_spec/vagrant-libvirt.xml +16 -0
  110. data/spec/unit/util/network_util_spec.rb +59 -0
  111. data/spec/unit/util/resolvers_spec.rb +1 -1
  112. metadata +85 -73
@@ -3,6 +3,7 @@
3
3
  require 'cgi'
4
4
 
5
5
  require 'vagrant'
6
+ require 'vagrant/action/builtin/mixin_synced_folders'
6
7
 
7
8
  require 'vagrant-libvirt/errors'
8
9
  require 'vagrant-libvirt/util/resolvers'
@@ -10,6 +11,8 @@ require 'vagrant-libvirt/util/resolvers'
10
11
  module VagrantPlugins
11
12
  module ProviderLibvirt
12
13
  class Config < Vagrant.plugin('2', :config)
14
+ include Vagrant::Action::Builtin::MixinSyncedFolders
15
+
13
16
  # manually specify URI
14
17
  # will supersede most other options if provided
15
18
  attr_accessor :uri
@@ -19,6 +22,7 @@ module VagrantPlugins
19
22
 
20
23
  # The name of the server, where Libvirtd is running.
21
24
  attr_accessor :host
25
+ attr_accessor :port
22
26
 
23
27
  # If use ssh tunnel to connect to Libvirt.
24
28
  attr_accessor :connect_via_ssh
@@ -63,6 +67,7 @@ module VagrantPlugins
63
67
  attr_accessor :management_network_domain
64
68
  attr_accessor :management_network_mtu
65
69
  attr_accessor :management_network_keep
70
+ attr_accessor :management_network_driver_iommu
66
71
 
67
72
  # System connection information
68
73
  attr_accessor :system_uri
@@ -77,6 +82,7 @@ module VagrantPlugins
77
82
  attr_accessor :memory
78
83
  attr_accessor :nodeset
79
84
  attr_accessor :memory_backing
85
+ attr_accessor :memtunes
80
86
  attr_accessor :channel
81
87
  attr_accessor :cpus
82
88
  attr_accessor :cpuset
@@ -85,11 +91,13 @@ module VagrantPlugins
85
91
  attr_accessor :cpu_fallback
86
92
  attr_accessor :cpu_features
87
93
  attr_accessor :cpu_topology
94
+ attr_accessor :cpu_affinity
88
95
  attr_accessor :shares
89
96
  attr_accessor :features
90
97
  attr_accessor :features_hyperv
91
98
  attr_accessor :clock_offset
92
99
  attr_accessor :clock_timers
100
+ attr_accessor :launchsecurity_data
93
101
  attr_accessor :numa_nodes
94
102
  attr_accessor :loader
95
103
  attr_accessor :nvram
@@ -99,6 +107,7 @@ module VagrantPlugins
99
107
  attr_accessor :machine_virtual_size
100
108
  attr_accessor :disk_bus
101
109
  attr_accessor :disk_device
110
+ attr_accessor :disk_address_type
102
111
  attr_accessor :disk_controller_model
103
112
  attr_accessor :disk_driver_opts
104
113
  attr_accessor :nic_model_type
@@ -112,6 +121,7 @@ module VagrantPlugins
112
121
  attr_accessor :graphics_type
113
122
  attr_accessor :graphics_autoport
114
123
  attr_accessor :graphics_port
124
+ attr_accessor :graphics_websocket
115
125
  attr_accessor :graphics_passwd
116
126
  attr_accessor :graphics_ip
117
127
  attr_accessor :graphics_gl
@@ -146,6 +156,7 @@ module VagrantPlugins
146
156
  # Storage
147
157
  attr_accessor :disks
148
158
  attr_accessor :cdroms
159
+ attr_accessor :floppies
149
160
 
150
161
  # Inputs
151
162
  attr_accessor :inputs
@@ -202,6 +213,14 @@ module VagrantPlugins
202
213
  # internal helper attributes
203
214
  attr_accessor :host_device_exclude_prefixes
204
215
 
216
+ # list of architectures that support cpu based on https://github.com/libvirt/libvirt/tree/master/src/cpu
217
+ ARCH_SUPPORT_CPU = [
218
+ 'aarch64', 'armv6l', 'armv7b', 'armv7l',
219
+ 'i686', 'x86_64',
220
+ 'ppc64', 'ppc64le',
221
+ 's390', 's390x',
222
+ ]
223
+
205
224
  def initialize
206
225
  @uri = UNSET_VALUE
207
226
  @driver = UNSET_VALUE
@@ -229,6 +248,7 @@ module VagrantPlugins
229
248
  @management_network_domain = UNSET_VALUE
230
249
  @management_network_mtu = UNSET_VALUE
231
250
  @management_network_keep = UNSET_VALUE
251
+ @management_network_driver_iommu = UNSET_VALUE
232
252
 
233
253
  # System connection information
234
254
  @system_uri = UNSET_VALUE
@@ -240,6 +260,7 @@ module VagrantPlugins
240
260
  @memory = UNSET_VALUE
241
261
  @nodeset = UNSET_VALUE
242
262
  @memory_backing = UNSET_VALUE
263
+ @memtunes = {}
243
264
  @cpus = UNSET_VALUE
244
265
  @cpuset = UNSET_VALUE
245
266
  @cpu_mode = UNSET_VALUE
@@ -247,11 +268,13 @@ module VagrantPlugins
247
268
  @cpu_fallback = UNSET_VALUE
248
269
  @cpu_features = UNSET_VALUE
249
270
  @cpu_topology = UNSET_VALUE
271
+ @cpu_affinity = UNSET_VALUE
250
272
  @shares = UNSET_VALUE
251
273
  @features = UNSET_VALUE
252
274
  @features_hyperv = UNSET_VALUE
253
275
  @clock_offset = UNSET_VALUE
254
276
  @clock_timers = []
277
+ @launchsecurity_data = UNSET_VALUE
255
278
  @numa_nodes = UNSET_VALUE
256
279
  @loader = UNSET_VALUE
257
280
  @nvram = UNSET_VALUE
@@ -260,6 +283,7 @@ module VagrantPlugins
260
283
  @machine_virtual_size = UNSET_VALUE
261
284
  @disk_bus = UNSET_VALUE
262
285
  @disk_device = UNSET_VALUE
286
+ @disk_address_type = UNSET_VALUE
263
287
  @disk_controller_model = UNSET_VALUE
264
288
  @disk_driver_opts = {}
265
289
  @nic_model_type = UNSET_VALUE
@@ -273,6 +297,7 @@ module VagrantPlugins
273
297
  @graphics_type = UNSET_VALUE
274
298
  @graphics_autoport = UNSET_VALUE
275
299
  @graphics_port = UNSET_VALUE
300
+ @graphics_websocket = UNSET_VALUE
276
301
  @graphics_ip = UNSET_VALUE
277
302
  @graphics_passwd = UNSET_VALUE
278
303
  @graphics_gl = UNSET_VALUE
@@ -302,6 +327,7 @@ module VagrantPlugins
302
327
  # Storage
303
328
  @disks = []
304
329
  @cdroms = []
330
+ @floppies = []
305
331
 
306
332
  # Inputs
307
333
  @inputs = UNSET_VALUE
@@ -379,6 +405,25 @@ module VagrantPlugins
379
405
  raise 'Only four cdroms may be attached at a time'
380
406
  end
381
407
 
408
+
409
+ def _get_floppy_dev(floppies)
410
+ exist = Hash[floppies.collect { |x| [x[:dev], true] }]
411
+ # fda - fdb
412
+ curr = 'a'.ord
413
+ while curr <= 'b'.ord
414
+ dev = "fd#{curr.chr}"
415
+ if exist[dev]
416
+ curr += 1
417
+ next
418
+ else
419
+ return dev
420
+ end
421
+ end
422
+
423
+ # is it better to raise our own error, or let Libvirt cause the exception?
424
+ raise 'Only two floppies may be attached at a time'
425
+ end
426
+
382
427
  def _generate_numa
383
428
  @numa_nodes.collect { |x|
384
429
  # Perform some validation of cpu values
@@ -468,6 +513,16 @@ module VagrantPlugins
468
513
  @cpu_topology[:threads] = options[:threads]
469
514
  end
470
515
 
516
+ def cpuaffinitiy(affinity = {})
517
+ if @cpu_affinity == UNSET_VALUE
518
+ @cpu_affinity = {}
519
+ end
520
+
521
+ affinity.each do |vcpu, cpuset|
522
+ @cpu_affinity[vcpu] = cpuset
523
+ end
524
+ end
525
+
471
526
  def memorybacking(option, config = {})
472
527
  case option
473
528
  when :source
@@ -483,6 +538,37 @@ module VagrantPlugins
483
538
  config: config)
484
539
  end
485
540
 
541
+ def memtune(config={})
542
+ if config[:type].nil?
543
+ raise "Missing memtune type"
544
+ end
545
+
546
+ unless ['hard_limit', 'soft_limit', 'swap_hard_limit'].include? config[:type]
547
+ raise "Memtune type '#{config[:type]}' not allowed (hard_limit, soft_limit, swap_hard_limit are allowed)"
548
+ end
549
+
550
+ if config[:value].nil?
551
+ raise "Missing memtune value"
552
+ end
553
+
554
+ opts = config[:options] || {}
555
+ opts[:unit] = opts[:unit] || "KiB"
556
+
557
+ @memtunes[config[:type]] = { value: config[:value], config: opts }
558
+ end
559
+
560
+ def launchsecurity(options = {})
561
+ if options.fetch(:type) != 'sev'
562
+ raise "Launch security type only supports SEV. Explicitly set 'sev' as a type"
563
+ end
564
+
565
+ @launchsecurity_data = {}
566
+ @launchsecurity_data[:type] = options[:type]
567
+ @launchsecurity_data[:cbitpos] = options[:cbitpos] || 47
568
+ @launchsecurity_data[:reducedPhysBits] = options[:reducedPhysBits] || 1
569
+ @launchsecurity_data[:policy] = options[:policy] || "0x0003"
570
+ end
571
+
486
572
  def input(options = {})
487
573
  if options[:type].nil? || options[:bus].nil?
488
574
  raise 'Input type AND bus must be specified'
@@ -641,8 +727,11 @@ module VagrantPlugins
641
727
  # NOTE: this will run twice for each time it's needed- keep it idempotent
642
728
  def storage(storage_type, options = {})
643
729
  if storage_type == :file
644
- if options[:device] == :cdrom
730
+ case options[:device]
731
+ when :cdrom
645
732
  _handle_cdrom_storage(options)
733
+ when :floppy
734
+ _handle_floppy_storage(options)
646
735
  else
647
736
  _handle_disk_storage(options)
648
737
  end
@@ -676,6 +765,28 @@ module VagrantPlugins
676
765
  @cdroms << cdrom
677
766
  end
678
767
 
768
+ def _handle_floppy_storage(options = {})
769
+ # <disk type='file' device='floppy'>
770
+ # <source file='/var/lib/libvirt/images/floppy.vfd'/>
771
+ # <target dev='fda' bus='fdc'/>
772
+ # </disk>
773
+ #
774
+ # note the target dev will need to be changed with each floppy drive (fda or fdb)
775
+
776
+ options = {
777
+ bus: 'fdc',
778
+ path: nil
779
+ }.merge(options)
780
+
781
+ floppy = {
782
+ dev: options[:dev],
783
+ bus: options[:bus],
784
+ path: options[:path]
785
+ }
786
+
787
+ @floppies << floppy
788
+ end
789
+
679
790
  def _handle_disk_storage(options = {})
680
791
  options = {
681
792
  type: 'qcow2',
@@ -687,6 +798,7 @@ module VagrantPlugins
687
798
  disk = {
688
799
  device: options[:device],
689
800
  type: options[:type],
801
+ address_type: options[:address_type],
690
802
  size: options[:size],
691
803
  path: options[:path],
692
804
  bus: options[:bus],
@@ -846,17 +958,29 @@ module VagrantPlugins
846
958
  @management_network_domain = nil if @management_network_domain == UNSET_VALUE
847
959
  @management_network_mtu = nil if @management_network_mtu == UNSET_VALUE
848
960
  @management_network_keep = false if @management_network_keep == UNSET_VALUE
961
+ @management_network_driver_iommu = false if @management_network_driver_iommu == UNSET_VALUE
849
962
 
850
963
  # Domain specific settings.
851
964
  @title = '' if @title == UNSET_VALUE
852
965
  @description = '' if @description == UNSET_VALUE
853
966
  @uuid = '' if @uuid == UNSET_VALUE
967
+ @machine_type = nil if @machine_type == UNSET_VALUE
968
+ @machine_arch = nil if @machine_arch == UNSET_VALUE
854
969
  @memory = 512 if @memory == UNSET_VALUE
855
970
  @nodeset = nil if @nodeset == UNSET_VALUE
856
971
  @memory_backing = [] if @memory_backing == UNSET_VALUE
857
972
  @cpus = 1 if @cpus == UNSET_VALUE
858
973
  @cpuset = nil if @cpuset == UNSET_VALUE
859
- @cpu_mode = 'host-model' if @cpu_mode == UNSET_VALUE
974
+ @cpu_mode = if @cpu_mode == UNSET_VALUE
975
+ # only some architectures support the cpu element
976
+ if @machine_arch.nil? || ARCH_SUPPORT_CPU.include?(@machine_arch.downcase)
977
+ 'host-model'
978
+ else
979
+ nil
980
+ end
981
+ else
982
+ @cpu_mode
983
+ end
860
984
  @cpu_model = if (@cpu_model == UNSET_VALUE) && (@cpu_mode == 'custom')
861
985
  'qemu64'
862
986
  elsif @cpu_mode != 'custom'
@@ -865,6 +989,7 @@ module VagrantPlugins
865
989
  @cpu_model
866
990
  end
867
991
  @cpu_topology = {} if @cpu_topology == UNSET_VALUE
992
+ @cpu_affinity = {} if @cpu_affinity == UNSET_VALUE
868
993
  @cpu_fallback = 'allow' if @cpu_fallback == UNSET_VALUE
869
994
  @cpu_features = [] if @cpu_features == UNSET_VALUE
870
995
  @shares = nil if @shares == UNSET_VALUE
@@ -872,11 +997,10 @@ module VagrantPlugins
872
997
  @features_hyperv = [] if @features_hyperv == UNSET_VALUE
873
998
  @clock_offset = 'utc' if @clock_offset == UNSET_VALUE
874
999
  @clock_timers = [] if @clock_timers == UNSET_VALUE
1000
+ @launchsecurity_data = nil if @launchsecurity_data == UNSET_VALUE
875
1001
  @numa_nodes = @numa_nodes == UNSET_VALUE ? nil : _generate_numa
876
1002
  @loader = nil if @loader == UNSET_VALUE
877
1003
  @nvram = nil if @nvram == UNSET_VALUE
878
- @machine_type = nil if @machine_type == UNSET_VALUE
879
- @machine_arch = nil if @machine_arch == UNSET_VALUE
880
1004
  @machine_virtual_size = nil if @machine_virtual_size == UNSET_VALUE
881
1005
  @disk_device = @disk_bus == 'scsi' ? 'sda' : 'vda' if @disk_device == UNSET_VALUE
882
1006
  @disk_bus = @disk_device.start_with?('sd') ? 'scsi' : 'virtio' if @disk_bus == UNSET_VALUE
@@ -887,26 +1011,28 @@ module VagrantPlugins
887
1011
  @disk_controller_model = nil
888
1012
  end
889
1013
  end
1014
+ @disk_address_type = nil if @disk_address_type == UNSET_VALUE
890
1015
  @disk_driver_opts = {} if @disk_driver_opts == UNSET_VALUE
891
1016
  @nic_model_type = nil if @nic_model_type == UNSET_VALUE
892
1017
  @nested = false if @nested == UNSET_VALUE
893
1018
  @volume_cache = nil if @volume_cache == UNSET_VALUE
894
1019
  @kernel = nil if @kernel == UNSET_VALUE
895
1020
  @cmd_line = '' if @cmd_line == UNSET_VALUE
896
- @initrd = '' if @initrd == UNSET_VALUE
1021
+ @initrd = nil if @initrd == UNSET_VALUE
897
1022
  @dtb = nil if @dtb == UNSET_VALUE
898
1023
  @graphics_type = 'vnc' if @graphics_type == UNSET_VALUE
899
- @graphics_autoport = @graphics_port == UNSET_VALUE ? 'yes' : nil
1024
+ @graphics_autoport = @graphics_type != 'spice' && @graphics_port == UNSET_VALUE ? 'yes' : nil
900
1025
  if (@graphics_type != 'vnc' && @graphics_type != 'spice') ||
901
1026
  @graphics_passwd == UNSET_VALUE
902
1027
  @graphics_passwd = nil
903
1028
  end
904
- @graphics_port = -1 if @graphics_port == UNSET_VALUE
905
- @graphics_ip = '127.0.0.1' if @graphics_ip == UNSET_VALUE
906
- @video_type = 'cirrus' if @video_type == UNSET_VALUE
907
- @video_vram = 16384 if @video_vram == UNSET_VALUE
1029
+ @graphics_port = @graphics_type == 'spice' ? nil : -1 if @graphics_port == UNSET_VALUE
1030
+ @graphics_websocket = @graphics_type == 'spice' ? nil : -1 if @graphics_websocket == UNSET_VALUE
1031
+ @graphics_ip = @graphics_type == 'spice' ? nil : '127.0.0.1' if @graphics_ip == UNSET_VALUE
908
1032
  @video_accel3d = false if @video_accel3d == UNSET_VALUE
909
1033
  @graphics_gl = @video_accel3d if @graphics_gl == UNSET_VALUE
1034
+ @video_type = @video_accel3d ? 'virtio' : 'cirrus' if @video_type == UNSET_VALUE
1035
+ @video_vram = 16384 if @video_vram == UNSET_VALUE
910
1036
  @sound_type = nil if @sound_type == UNSET_VALUE
911
1037
  @keymap = 'en-us' if @keymap == UNSET_VALUE
912
1038
  @kvm_hidden = false if @kvm_hidden == UNSET_VALUE
@@ -933,17 +1059,25 @@ module VagrantPlugins
933
1059
  cdrom[:dev] = _get_cdrom_dev(@cdroms) if cdrom[:dev].nil?
934
1060
  cdrom
935
1061
  end
1062
+ @floppies = [] if @floppies == UNSET_VALUE
1063
+ @floppies.map! do |floppy|
1064
+ floppy[:dev] = _get_floppy_dev(@floppies) if floppy[:dev].nil?
1065
+ floppy
1066
+ end
936
1067
 
937
1068
  # Inputs
938
1069
  @inputs = [{ type: 'mouse', bus: 'ps2' }] if @inputs == UNSET_VALUE
939
1070
 
940
1071
  # Channels
941
- if @channels == UNSET_VALUE
942
- @channels = []
943
- if @qemu_use_agent == true
944
- if @channels.all? { |channel| !channel.fetch(:target_name, '').start_with?('org.qemu.guest_agent.') }
945
- channel(:type => 'unix', :target_name => 'org.qemu.guest_agent.0', :target_type => 'virtio')
946
- end
1072
+ @channels = [] if @channels == UNSET_VALUE
1073
+ if @qemu_use_agent == true
1074
+ if @channels.all? { |channel| !channel.fetch(:target_name, '').start_with?('org.qemu.guest_agent.') }
1075
+ channel(:type => 'unix', :target_name => 'org.qemu.guest_agent.0', :target_type => 'virtio')
1076
+ end
1077
+ end
1078
+ if @graphics_type == 'spice'
1079
+ if @channels.all? { |channel| !channel.fetch(:target_name, '').start_with?('com.redhat.spice.') }
1080
+ channel(:type => 'spicevmc', :target_name => 'com.redhat.spice.0', :target_type => 'virtio')
947
1081
  end
948
1082
  end
949
1083
 
@@ -1000,11 +1134,31 @@ module VagrantPlugins
1000
1134
  def validate(machine)
1001
1135
  errors = _detected_errors
1002
1136
 
1137
+ unless @machine_arch.nil? || ARCH_SUPPORT_CPU.include?(@machine_arch.downcase)
1138
+ unsupported = [:cpu_mode, :cpu_model, :nested, :cpu_features, :cpu_topology, :numa_nodes]
1139
+ cpu_support_required_by = unsupported.select { |x|
1140
+ value = instance_variable_get("@#{x.to_s}")
1141
+ next if value.nil? # not set
1142
+ is_bool = !!value == value
1143
+ next if is_bool && !value # boolean and set to false
1144
+ next if !is_bool && value.empty? # not boolean, but empty '', [], {}
1145
+ true
1146
+ }
1147
+
1148
+ unless cpu_support_required_by.empty?
1149
+ errors << "Architecture #{@machine_arch} does not support /domain/cpu XML, which is required when setting the config options #{cpu_support_required_by.join(", ")}"
1150
+ end
1151
+ end
1152
+
1003
1153
  # technically this shouldn't occur, but ensure that if somehow it does, it gets rejected.
1004
1154
  if @cpu_mode == 'host-passthrough' && @cpu_model != ''
1005
1155
  errors << "cannot set cpu_model with cpu_mode of 'host-passthrough'. leave model unset or switch mode."
1006
1156
  end
1007
1157
 
1158
+ unless @cpu_model != '' || @cpu_features.empty?
1159
+ errors << "cannot set cpu_features with cpu_model unset, please set a model or skip setting features."
1160
+ end
1161
+
1008
1162
  # The @uri and @qemu_use_session should not conflict
1009
1163
  uri = _parse_uri(@uri)
1010
1164
  if (uri.scheme.start_with? "qemu") && (uri.path.include? "session")
@@ -1067,8 +1221,9 @@ module VagrantPlugins
1067
1221
  # only interested in public networks where portgroup is nil, as then source will be a host device
1068
1222
  if type == :public_network && opts[:portgroup] == nil
1069
1223
  devices = host_devices(machine)
1070
- if !devices.include?(opts[:dev])
1071
- errors << "network configuration #{index} for machine #{machine.name} is a public_network referencing host device '#{opts[:dev]}' which does not exist, consider adding ':dev => ....' referencing one of #{devices.join(", ")}"
1224
+ hostdev = opts.fetch(:dev, 'eth0')
1225
+ if !devices.include?(hostdev)
1226
+ errors << "network configuration #{index} for machine #{machine.name} is a public_network referencing host device '#{hostdev}' which does not exist, consider adding ':dev => ....' referencing one of #{devices.join(", ")}"
1072
1227
  end
1073
1228
  end
1074
1229
  end
@@ -1081,6 +1236,20 @@ module VagrantPlugins
1081
1236
  end
1082
1237
  end
1083
1238
 
1239
+ # if run via a session, then qemu will be run with user permissions, make sure the user
1240
+ # has permissions to access the host paths otherwise there will be an error triggered
1241
+ if machine.provider_config.qemu_use_session
1242
+ synced_folders(machine).fetch(:"9p", []).each do |_, options|
1243
+ unless File.readable?(options[:hostpath])
1244
+ errors << "9p synced_folder cannot mount host path #{options[:hostpath]} into guest #{options[:guestpath]} when using qemu session as executing user does not have permissions to read the directory on the user."
1245
+ end
1246
+ end
1247
+
1248
+ unless synced_folders(machine)[:"virtiofs"].nil?
1249
+ machine.ui.warn("Note: qemu session may not support virtiofs for synced_folders, use 9p or enable use of qemu:///system context unless you know what you are doing")
1250
+ end
1251
+ end
1252
+
1084
1253
  errors = validate_sysinfo(machine, errors)
1085
1254
 
1086
1255
  { 'Libvirt Provider' => errors }
@@ -1098,8 +1267,16 @@ module VagrantPlugins
1098
1267
  c += other.cdroms
1099
1268
  result.cdroms = c
1100
1269
 
1270
+ c = floppies.dup
1271
+ c += other.floppies
1272
+ result.floppies = c
1273
+
1274
+ result.memtunes = memtunes.merge(other.memtunes)
1275
+
1101
1276
  result.disk_driver_opts = disk_driver_opts.merge(other.disk_driver_opts)
1102
1277
 
1278
+ result.inputs = inputs != UNSET_VALUE ? inputs.dup + (other.inputs != UNSET_VALUE ? other.inputs : []) : other.inputs
1279
+
1103
1280
  c = sysinfo == UNSET_VALUE ? {} : sysinfo.dup
1104
1281
  c.merge!(other.sysinfo) { |_k, x, y| x.respond_to?(:each_pair) ? x.merge(y) : x + y } if other.sysinfo != UNSET_VALUE
1105
1282
  result.sysinfo = c
@@ -1213,14 +1390,9 @@ module VagrantPlugins
1213
1390
  end
1214
1391
 
1215
1392
  def host_devices(machine)
1216
- @host_devices ||= begin
1217
- (
1218
- machine.provider.driver.list_host_devices.map { |iface| iface.name } +
1219
- machine.provider.driver.list_networks.map { |net| net.bridge_name }
1220
- ).uniq.select do |dev|
1221
- next if dev.empty?
1222
- dev != "lo" && !@host_device_exclude_prefixes.any? { |exclude| dev.start_with?(exclude) }
1223
- end
1393
+ machine.provider.driver.host_devices.select do |dev|
1394
+ next if dev.empty?
1395
+ dev != "lo" && !@host_device_exclude_prefixes.any? { |exclude| dev.start_with?(exclude) }
1224
1396
  end
1225
1397
  end
1226
1398