From 6bdff043a719ee6986a394e17a1934843377df0a Mon Sep 17 00:00:00 2001 From: Antonio Huete Jimenez Date: Wed, 21 Mar 2018 19:00:28 +0100 Subject: [PATCH] Allow specifying Hypervisor HyperV features (#870) --- README.md | 23 +++++++++++++++++++- lib/vagrant-libvirt/action/create_domain.rb | 4 ++++ lib/vagrant-libvirt/config.rb | 11 ++++++++++ lib/vagrant-libvirt/templates/domain.xml.erb | 7 ++++++ spec/unit/templates/domain_all_settings.xml | 3 +++ spec/unit/templates/domain_spec.rb | 1 + 6 files changed, 48 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 05d8e65..0a49240 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ can help a lot :-) - [Random number generator passthrough](#random-number-generator-passthrough) - [Watchdog·Device](#watchdog-device) - [Smartcard device](#smartcard-device) +- [Hypervisor Features](#hypervisor-features) - [CPU Features](#cpu-features) - [No box and PXE boot](#no-box-and-pxe-boot) - [SSH Access To VM](#ssh-access-to-vm) @@ -967,7 +968,7 @@ Vagrant.configure("2") do |config| end end ``` -## Features +## Hypervisor Features Hypervisor features can be specified via `libvirt.features` as a list. The default options that are enabled are `acpi`, `apic` and `pae`. If you define `libvirt.features` @@ -995,6 +996,26 @@ Vagrant.configure("2") do |config| end ``` +You can also specify a special set of features that help improve the behavior of guests +running Microsoft Windows. + +You can specify HyperV features via `libvirt.hyperv_feature`. Available +options are listed below. Note that both options are required: + +* `name` - The name of the feature Hypervisor feature (see libvirt doc) +* `state` - The state for this feature which can be either `on` or `off`. + +```ruby +Vagrant.configure("2") do |config| + config.vm.provider :libvirt do |libvirt| + # Relax constraints on timers + libvirt.hyperv_feature :name => 'relaxed', :state => 'on' + # Enable virtual APIC + libvirt.hyperv_feature :name => 'vapic', :state => 'on' + end +end +``` + ## CPU features You can specify CPU feature policies via `libvirt.cpu_feature`. Available diff --git a/lib/vagrant-libvirt/action/create_domain.rb b/lib/vagrant-libvirt/action/create_domain.rb index d9e8b6c..81d8499 100644 --- a/lib/vagrant-libvirt/action/create_domain.rb +++ b/lib/vagrant-libvirt/action/create_domain.rb @@ -36,6 +36,7 @@ module VagrantPlugins @cpu_features = config.cpu_features @cpu_topology = config.cpu_topology @features = config.features + @features_hyperv = config.features_hyperv @cpu_mode = config.cpu_mode @cpu_model = config.cpu_model @cpu_fallback = config.cpu_fallback @@ -192,6 +193,9 @@ module VagrantPlugins @features.each do |feature| env[:ui].info(" -- Feature: #{feature}") end + @features_hyperv.each do |feature| + env[:ui].info(" -- Feature (HyperV): name=#{feature[:name]}, state=#{feature[:state]}") + end env[:ui].info(" -- Memory: #{@memory_size / 1024}M") @memory_backing.each do |backing| env[:ui].info(" -- Memory Backing: #{backing[:name]}: #{backing[:config].map { |k,v| "#{k}='#{v}'"}.join(' ')}") diff --git a/lib/vagrant-libvirt/config.rb b/lib/vagrant-libvirt/config.rb index 37f6fcf..c1c4b02 100644 --- a/lib/vagrant-libvirt/config.rb +++ b/lib/vagrant-libvirt/config.rb @@ -74,6 +74,7 @@ module VagrantPlugins attr_accessor :cpu_features attr_accessor :cpu_topology attr_accessor :features + attr_accessor :features_hyperv attr_accessor :numa_nodes attr_accessor :loader attr_accessor :nvram @@ -194,6 +195,7 @@ module VagrantPlugins @cpu_features = UNSET_VALUE @cpu_topology = UNSET_VALUE @features = UNSET_VALUE + @features_hyperv = UNSET_VALUE @numa_nodes = UNSET_VALUE @loader = UNSET_VALUE @nvram = UNSET_VALUE @@ -342,6 +344,14 @@ module VagrantPlugins policy: options[:policy]) end + def hyperv_feature(options = {}) + if options[:name].nil? || options[:state].nil? + raise 'Feature name AND state must be specified' + end + + @features_hyperv = [{name: options[:name], state: options[:state]}] if @features_hyperv == UNSET_VALUE + end + def cputopology(options = {}) if options[:sockets].nil? || options[:cores].nil? || options[:threads].nil? raise 'CPU topology must have all of sockets, cores and threads specified' @@ -663,6 +673,7 @@ module VagrantPlugins @cpu_fallback = 'allow' if @cpu_fallback == UNSET_VALUE @cpu_features = [] if @cpu_features == UNSET_VALUE @features = ['acpi','apic','pae'] if @features == UNSET_VALUE + @features_hyperv = [] if @features_hyperv == UNSET_VALUE @numa_nodes = @numa_nodes == UNSET_VALUE ? nil : _generate_numa @loader = nil if @loader == UNSET_VALUE @nvram = nil if @nvram == UNSET_VALUE diff --git a/lib/vagrant-libvirt/templates/domain.xml.erb b/lib/vagrant-libvirt/templates/domain.xml.erb index a5cb1fb..5e0b91b 100644 --- a/lib/vagrant-libvirt/templates/domain.xml.erb +++ b/lib/vagrant-libvirt/templates/domain.xml.erb @@ -84,6 +84,13 @@ <% end %> + <% if !@features_hyperv.empty? %> + + <% @features_hyperv.each do |feature| %> + <<%= feature[:name] %> state='<%= feature[:state] %>' /> + <% end %> + + <% end %> diff --git a/spec/unit/templates/domain_all_settings.xml b/spec/unit/templates/domain_all_settings.xml index d87fa56..fc7a7e9 100644 --- a/spec/unit/templates/domain_all_settings.xml +++ b/spec/unit/templates/domain_all_settings.xml @@ -24,6 +24,9 @@ + + + diff --git a/spec/unit/templates/domain_spec.rb b/spec/unit/templates/domain_spec.rb index 561e686..c235d0a 100644 --- a/spec/unit/templates/domain_spec.rb +++ b/spec/unit/templates/domain_spec.rb @@ -31,6 +31,7 @@ describe 'templates/domain' do domain.instance_variable_set('@domain_type', 'kvm') domain.cpu_mode = 'custom' domain.cpu_feature(name: 'AAA', policy: 'required') + domain.hyperv_feature(name: 'BBB', state: 'on') domain.cputopology(sockets: '1', cores: '3', threads: '2') domain.machine_type = 'pc-compatible' domain.machine_arch = 'x86_64'