mirror of
https://github.com/vagrant-libvirt/vagrant-libvirt.git
synced 2025-02-25 18:55:27 -06:00
When cpu mode was set to host-passthrough the template would skip setting all other settings for the cpu, while it appears from the documentation that it supports use of feature elements, and testing confirms that it also supports the topology element. https://libvirt.org/formatdomain.html#cpu-model-and-topology Fixes: #975
234 lines
7.8 KiB
Ruby
234 lines
7.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'support/sharedcontext'
|
|
|
|
require 'vagrant-libvirt/config'
|
|
require 'vagrant-libvirt/util/erb_template'
|
|
|
|
describe 'templates/domain' do
|
|
include_context 'unit'
|
|
|
|
class DomainTemplateHelper < VagrantPlugins::ProviderLibvirt::Config
|
|
include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
|
|
|
|
attr_accessor :domain_volumes
|
|
|
|
def initialize
|
|
super
|
|
@domain_volumes = []
|
|
end
|
|
|
|
def finalize!
|
|
super
|
|
end
|
|
end
|
|
|
|
let(:domain) { DomainTemplateHelper.new }
|
|
let(:xml_expected) { File.read(File.join(File.dirname(__FILE__), test_file)) }
|
|
|
|
context 'when only defaults used' do
|
|
let(:test_file) { 'domain_defaults.xml' }
|
|
it 'renders template' do
|
|
domain.finalize!
|
|
expect(domain.to_xml('domain')).to eq xml_expected
|
|
end
|
|
end
|
|
|
|
context 'when all settings enabled' do
|
|
before do
|
|
domain.title = 'title'
|
|
domain.description = 'description'
|
|
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.clock_offset = 'variable'
|
|
domain.clock_timer(name: 't1')
|
|
domain.clock_timer(name: 't2', track: 'b', tickpolicy: 'c', frequency: 'd', mode: 'e', present: 'yes')
|
|
domain.hyperv_feature(name: 'spinlocks', state: 'on', retries: '4096')
|
|
domain.cputopology(sockets: '1', cores: '3', threads: '2')
|
|
domain.machine_type = 'pc-compatible'
|
|
domain.machine_arch = 'x86_64'
|
|
domain.loader = '/efi/loader'
|
|
domain.boot('network')
|
|
domain.boot('cdrom')
|
|
domain.boot('hd')
|
|
domain.emulator_path = '/usr/bin/kvm-spice'
|
|
domain.instance_variable_set('@domain_volume_cache', 'deprecated')
|
|
domain.disk_bus = 'ide'
|
|
domain.disk_device = 'vda'
|
|
domain.disk_driver(:cache => 'unsafe', :io => 'threads', :copy_on_read => 'on', :discard => 'unmap', :detect_zeroes => 'on')
|
|
domain.domain_volumes.push({
|
|
:dev => 'vda',
|
|
:cache => 'unsafe',
|
|
:bus => domain.disk_bus,
|
|
:path => '/var/lib/libvirt/images/test.qcow2'
|
|
})
|
|
domain.domain_volumes.push({
|
|
:dev => 'vdb',
|
|
:cache => 'unsafe',
|
|
:bus => domain.disk_bus,
|
|
:path => '/var/lib/libvirt/images/test2.qcow2'
|
|
})
|
|
domain.storage(:file, path: 'test-disk1.qcow2')
|
|
domain.storage(:file, path: 'test-disk2.qcow2', io: 'threads', copy_on_read: 'on', discard: 'unmap', detect_zeroes: 'on')
|
|
domain.disks.each do |disk|
|
|
disk[:absolute_path] = '/var/lib/libvirt/images/' + disk[:path]
|
|
end
|
|
domain.storage(:file, device: :cdrom)
|
|
domain.storage(:file, device: :cdrom)
|
|
domain.channel(type: 'unix',
|
|
target_name: 'org.qemu.guest_agent.0',
|
|
target_type: 'virtio')
|
|
domain.channel(type: 'spicevmc',
|
|
target_name: 'com.redhat.spice.0',
|
|
target_type: 'virtio')
|
|
domain.channel(type: 'unix',
|
|
target_type: 'guestfwd',
|
|
target_address: '192.0.2.42',
|
|
target_port: '4242',
|
|
source_path: '/tmp/foo')
|
|
domain.random(model: 'random')
|
|
domain.serial(:type => 'file', :source => {:path => '/var/log/vm_consoles/machine.log'})
|
|
domain.pci(bus: '0x06', slot: '0x12', function: '0x5')
|
|
domain.pci(domain: '0x0001', bus: '0x03', slot: '0x00', function: '0x0')
|
|
domain.usb_controller(model: 'nec-xhci', ports: '4')
|
|
domain.usb(bus: '1', device: '2', vendor: '0x1234', product: '0xabcd')
|
|
domain.redirdev(type: 'tcp', host: 'localhost', port: '4000')
|
|
domain.redirfilter(class: '0x0b', vendor: '0x08e6',
|
|
product: '0x3437', version: '2.00', allow: 'yes')
|
|
domain.watchdog(model: 'i6300esb', action: 'reset')
|
|
domain.smartcard(mode: 'passthrough')
|
|
domain.tpm_path = '/dev/tpm0'
|
|
|
|
domain.qemuargs(value: '-device')
|
|
domain.qemuargs(value: 'dummy-device')
|
|
|
|
domain.qemuenv(QEMU_AUDIO_DRV: 'pa')
|
|
domain.qemuenv(QEMU_AUDIO_TIMER_PERIOD: '150')
|
|
domain.qemuenv(QEMU_PA_SAMPLES: '1024')
|
|
domain.qemuenv(QEMU_PA_SERVER: '/run/user/1000/pulse/native')
|
|
|
|
domain.shares = '1024'
|
|
domain.cpuset = '1-4,^3,6'
|
|
domain.nodeset = '1-4,^3,6'
|
|
|
|
domain.video_accel3d = true
|
|
end
|
|
let(:test_file) { 'domain_all_settings.xml' }
|
|
it 'renders template' do
|
|
domain.finalize!
|
|
# resolving is now done during create domain, so need to recreate
|
|
# the same behaviour before calling the template until that
|
|
# is separated out from create domain.
|
|
resolver = ::VagrantPlugins::ProviderLibvirt::Util::DiskDeviceResolver.new(prefix=domain.disk_device[0..1])
|
|
resolver.resolve!(domain.domain_volumes.dup.each { |volume| volume[:device] = volume[:dev] })
|
|
resolver.resolve!(domain.disks)
|
|
|
|
expect(domain.to_xml('domain')).to eq xml_expected
|
|
end
|
|
end
|
|
|
|
context 'when cpu mode is set' do
|
|
context 'to host-passthrough' do
|
|
before do
|
|
domain.cpu_mode = 'host-passthrough'
|
|
domain.cpu_model = 'SandyBridge'
|
|
domain.cputopology :sockets => '1', :cores => '2', :threads => '1'
|
|
domain.nested = true
|
|
end
|
|
let(:test_file) { 'domain_cpu_mode_passthrough.xml' }
|
|
it 'should allow features and topology and ignore model' do
|
|
domain.finalize!
|
|
expect(domain.to_xml('domain')).to eq xml_expected
|
|
end
|
|
end
|
|
|
|
context 'to custom and model is set' do
|
|
before do
|
|
domain.cpu_mode = 'custom'
|
|
domain.cpu_model = 'SandyBridge'
|
|
end
|
|
let(:test_file) { 'domain_custom_cpu_model.xml' }
|
|
it 'renders template' do
|
|
domain.finalize!
|
|
expect(domain.to_xml('domain')).to eq xml_expected
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when tpm 2.0 device is specified' do
|
|
before do
|
|
domain.tpm_version = '2.0'
|
|
domain.tpm_type = 'emulator'
|
|
domain.tpm_model = 'tpm-crb'
|
|
end
|
|
let(:test_file) { 'tpm/version_2.0.xml' }
|
|
it 'renders template' do
|
|
domain.finalize!
|
|
expect(domain.to_xml('domain')).to eq xml_expected
|
|
end
|
|
end
|
|
|
|
context 'when tpm 1.2 device is implicitly used' do
|
|
before do
|
|
domain.tpm_path = '/dev/tpm0'
|
|
end
|
|
let(:test_file) { 'tpm/version_1.2.xml' }
|
|
it 'renders template' do
|
|
domain.finalize!
|
|
expect(domain.to_xml('domain')).to eq xml_expected
|
|
end
|
|
end
|
|
|
|
context 'memballoon' do
|
|
context 'default' do
|
|
it 'renders without specifying the xml tag' do
|
|
domain.finalize!
|
|
|
|
expect(domain.to_xml('domain')).to_not match(/memballoon/)
|
|
end
|
|
end
|
|
|
|
context 'memballon enabled' do
|
|
before do
|
|
domain.memballoon_enabled = true
|
|
end
|
|
|
|
it 'renders with memballon element' do
|
|
domain.finalize!
|
|
|
|
expect(domain.to_xml('domain')).to match(/<memballoon model='virtio'>/)
|
|
expect(domain.to_xml('domain')).to match(/<address type='pci' domain='0x0000' bus='0x00' slot='0x0f' function='0x0'\/>/)
|
|
end
|
|
|
|
context 'all settings specified' do
|
|
before do
|
|
domain.memballoon_model = "virtio-non-transitional"
|
|
domain.memballoon_pci_bus = "0x01"
|
|
domain.memballoon_pci_slot = "0x05"
|
|
end
|
|
|
|
it 'renders with specified values' do
|
|
domain.finalize!
|
|
|
|
expect(domain.to_xml('domain')).to match(/<memballoon model='virtio-non-transitional'>/)
|
|
expect(domain.to_xml('domain')).to match(/<address type='pci' domain='0x0000' bus='0x01' slot='0x05' function='0x0'\/>/)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'memballon disabled' do
|
|
before do
|
|
domain.memballoon_enabled = false
|
|
end
|
|
|
|
it 'renders the memballoon element with model none' do
|
|
domain.finalize!
|
|
|
|
expect(domain.to_xml('domain')).to match(/<memballoon model='none'\/>/)
|
|
end
|
|
end
|
|
end
|
|
end
|