2021-06-30 13:27:03 +01:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
2022-11-08 16:28:32 +00:00
|
|
|
require_relative '../../spec_helper'
|
2020-10-23 14:31:29 +01:00
|
|
|
|
2021-12-11 14:58:59 +00:00
|
|
|
require 'fog/libvirt/models/compute/volume'
|
|
|
|
|
|
2020-10-23 14:31:29 +01:00
|
|
|
require 'vagrant-libvirt/errors'
|
2021-09-28 13:17:22 +01:00
|
|
|
require 'vagrant-libvirt/util/byte_number'
|
2020-10-23 14:31:29 +01:00
|
|
|
require 'vagrant-libvirt/action/create_domain'
|
|
|
|
|
|
|
|
|
|
describe VagrantPlugins::ProviderLibvirt::Action::CreateDomain do
|
|
|
|
|
subject { described_class.new(app, env) }
|
|
|
|
|
|
|
|
|
|
include_context 'unit'
|
|
|
|
|
include_context 'libvirt'
|
|
|
|
|
|
|
|
|
|
let(:servers) { double('servers') }
|
|
|
|
|
let(:volumes) { double('volumes') }
|
2021-12-11 14:58:59 +00:00
|
|
|
let(:domain_volume) { instance_double(::Fog::Libvirt::Compute::Volume) }
|
2020-10-23 14:31:29 +01:00
|
|
|
|
2021-05-28 14:46:57 +01:00
|
|
|
let(:domain_xml) { File.read(File.join(File.dirname(__FILE__), File.basename(__FILE__, '.rb'), domain_xml_file)) }
|
2020-10-23 14:31:29 +01:00
|
|
|
|
|
|
|
|
describe '#call' do
|
|
|
|
|
before do
|
|
|
|
|
allow(connection).to receive(:servers).and_return(servers)
|
|
|
|
|
allow(connection).to receive(:volumes).and_return(volumes)
|
2021-09-28 13:17:22 +01:00
|
|
|
allow(volumes).to receive(:all).and_return([domain_volume])
|
|
|
|
|
allow(domain_volume).to receive(:pool_name).and_return('default')
|
|
|
|
|
allow(domain_volume).to receive(:path).and_return('/var/lib/libvirt/images/vagrant-test_default.img')
|
|
|
|
|
allow(machine).to receive_message_chain("box.name") { 'vagrant-libvirt/test' }
|
2020-12-05 15:49:25 +00:00
|
|
|
|
2020-12-05 15:24:42 +00:00
|
|
|
allow(logger).to receive(:info)
|
2021-09-11 19:29:45 +01:00
|
|
|
allow(logger).to receive(:debug)
|
2021-09-28 13:17:22 +01:00
|
|
|
allow(ui).to receive(:info)
|
2020-12-05 15:49:25 +00:00
|
|
|
|
|
|
|
|
env[:domain_name] = "vagrant-test_default"
|
|
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
env[:domain_volumes] = []
|
|
|
|
|
env[:domain_volumes].push({
|
|
|
|
|
:device=>'vda',
|
|
|
|
|
:bus=>'virtio',
|
|
|
|
|
:cache=>'default',
|
|
|
|
|
:absolute_path=>'/var/lib/libvirt/images/vagrant-test_default.img',
|
Allow to use many disks in vagrant box for libvirt provider
Adds support for a new multi disk box format and handling to upload the
multiple disks to the storage pool.
New format is:
{
'disks': [
{
'name': 'disk1.img',
'virtual_size': 10,
'format': 'qcow2'
},
{
'name': 'disk2.img',
'virtual_size': 15,
'format': 'qcow2'
},
{
'name': 'disk3.img',
}
],
'provider': 'libvirt',
'format': 'qcow2'
}
It is expected to remove format from being set at the top level when
using the new format, with the assuming that qcow2 should be the default
format, and other formats should be permitted to be specified as needed.
Includes tests for handling the box images and creation of domain
volumes. Additionally includes an integration test to ensure a box with
2 disks will work as expected.
Partially fixes: #602
2020-09-10 10:03:00 +02:00
|
|
|
:path=>"/test/box.img",
|
2022-06-02 19:09:18 +01:00
|
|
|
:name=>'test_vagrant_box_image_1.1.1_0.img',
|
2021-09-28 13:17:22 +01:00
|
|
|
:virtual_size=> ByteNumber.new(5),
|
2022-06-02 19:09:18 +01:00
|
|
|
:pool=>'default',
|
Allow to use many disks in vagrant box for libvirt provider
Adds support for a new multi disk box format and handling to upload the
multiple disks to the storage pool.
New format is:
{
'disks': [
{
'name': 'disk1.img',
'virtual_size': 10,
'format': 'qcow2'
},
{
'name': 'disk2.img',
'virtual_size': 15,
'format': 'qcow2'
},
{
'name': 'disk3.img',
}
],
'provider': 'libvirt',
'format': 'qcow2'
}
It is expected to remove format from being set at the top level when
using the new format, with the assuming that qcow2 should be the default
format, and other formats should be permitted to be specified as needed.
Includes tests for handling the box images and creation of domain
volumes. Additionally includes an integration test to ensure a box with
2 disks will work as expected.
Partially fixes: #602
2020-09-10 10:03:00 +02:00
|
|
|
})
|
2020-10-23 14:31:29 +01:00
|
|
|
end
|
|
|
|
|
|
2020-12-05 15:49:25 +00:00
|
|
|
context 'connection => qemu:///system' do
|
2021-09-28 13:17:22 +01:00
|
|
|
let(:domain_xml_file) { 'default_domain.xml' }
|
2020-10-23 14:31:29 +01:00
|
|
|
|
2021-12-11 14:58:59 +00:00
|
|
|
before do
|
|
|
|
|
allow(machine.provider_config).to receive(:qemu_use_session).and_return(false)
|
|
|
|
|
end
|
|
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
it 'should execute correctly' do
|
|
|
|
|
expect(servers).to receive(:create).with(xml: domain_xml).and_return(machine)
|
|
|
|
|
expect(volumes).to_not receive(:create) # additional disks only
|
2020-10-23 14:31:29 +01:00
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
expect(subject.call(env)).to be_nil
|
|
|
|
|
end
|
2021-09-28 13:17:22 +01:00
|
|
|
|
2022-10-01 14:59:36 +01:00
|
|
|
context 'graphics autoport disabled' do
|
|
|
|
|
let(:vagrantfile_providerconfig) do
|
|
|
|
|
<<-EOF
|
|
|
|
|
libvirt.graphics_port = 5900
|
2022-11-21 12:05:51 +01:00
|
|
|
libvirt.graphics_websocket = 5700
|
2022-10-01 14:59:36 +01:00
|
|
|
EOF
|
|
|
|
|
end
|
|
|
|
|
|
2022-11-21 12:05:51 +01:00
|
|
|
it 'should emit the graphics port and websocket' do
|
2022-10-01 14:59:36 +01:00
|
|
|
expect(servers).to receive(:create).and_return(machine)
|
|
|
|
|
expect(volumes).to_not receive(:create) # additional disks only
|
|
|
|
|
expect(ui).to receive(:info).with(' -- Graphics Port: 5900')
|
2022-11-21 12:05:51 +01:00
|
|
|
expect(ui).to receive(:info).with(' -- Graphics Websocket: 5700')
|
2022-10-01 14:59:36 +01:00
|
|
|
|
|
|
|
|
expect(subject.call(env)).to be_nil
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
context 'additional disks' do
|
|
|
|
|
let(:disks) do
|
|
|
|
|
[
|
|
|
|
|
:device => 'vdb',
|
|
|
|
|
:cache => 'default',
|
|
|
|
|
:bus => 'virtio',
|
|
|
|
|
:type => 'qcow2',
|
|
|
|
|
:absolute_path => '/var/lib/libvirt/images/vagrant-test_default-vdb.qcow2',
|
|
|
|
|
:virtual_size => ByteNumber.new(20*1024*1024*1024),
|
|
|
|
|
:pool => 'default',
|
|
|
|
|
]
|
2021-09-28 13:17:22 +01:00
|
|
|
end
|
|
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
before do
|
|
|
|
|
env[:disks] = disks
|
|
|
|
|
end
|
2020-12-05 15:49:25 +00:00
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
context 'volume create failed' do
|
|
|
|
|
it 'should raise an exception' do
|
|
|
|
|
expect(volumes).to receive(:create).and_raise(Libvirt::Error)
|
2020-12-05 15:49:25 +00:00
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
expect{ subject.call(env) }.to raise_error(VagrantPlugins::ProviderLibvirt::Errors::FogCreateDomainVolumeError)
|
2020-10-23 14:31:29 +01:00
|
|
|
end
|
|
|
|
|
end
|
2021-11-22 10:02:18 +00:00
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
context 'volume create succeeded' do
|
|
|
|
|
let(:domain_xml_file) { 'additional_disks_domain.xml' }
|
2021-11-22 10:02:18 +00:00
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
it 'should complete' do
|
|
|
|
|
expect(volumes).to receive(:create).with(
|
|
|
|
|
hash_including(
|
|
|
|
|
:path => "/var/lib/libvirt/images/vagrant-test_default-vdb.qcow2",
|
|
|
|
|
:owner => 0,
|
|
|
|
|
:group => 0,
|
|
|
|
|
:pool_name => "default",
|
|
|
|
|
)
|
|
|
|
|
)
|
2021-11-22 10:02:18 +00:00
|
|
|
expect(servers).to receive(:create).with(xml: domain_xml).and_return(machine)
|
|
|
|
|
|
|
|
|
|
expect(subject.call(env)).to be_nil
|
|
|
|
|
end
|
|
|
|
|
end
|
2022-06-02 19:09:18 +01:00
|
|
|
end
|
2021-11-22 10:02:18 +00:00
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
context 'with custom disk device setting' do
|
|
|
|
|
let(:domain_xml_file) { 'custom_disk_settings.xml' }
|
2021-11-22 10:02:18 +00:00
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
before do
|
|
|
|
|
env[:domain_volumes][0][:device] = 'sda'
|
|
|
|
|
end
|
2021-11-22 10:02:18 +00:00
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
it 'should set the domain device' do
|
|
|
|
|
expect(ui).to receive(:info).with(/ -- Image\(sda\):.*/)
|
|
|
|
|
expect(servers).to receive(:create).with(xml: domain_xml).and_return(machine)
|
|
|
|
|
|
|
|
|
|
expect(subject.call(env)).to be_nil
|
2021-11-22 10:02:18 +00:00
|
|
|
end
|
2020-12-05 15:49:25 +00:00
|
|
|
end
|
2020-10-23 14:31:29 +01:00
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
context 'with two domain disks' do
|
|
|
|
|
let(:domain_xml_file) { 'two_disk_settings.xml' }
|
|
|
|
|
let(:domain_volume_2) { double('domain_volume 2') }
|
|
|
|
|
|
|
|
|
|
before do
|
|
|
|
|
expect(volumes).to receive(:all).with(name: 'vagrant-test_default.img').and_return([domain_volume])
|
|
|
|
|
expect(volumes).to receive(:all).with(name: 'vagrant-test_default_1.img').and_return([domain_volume_2])
|
|
|
|
|
expect(domain_volume_2).to receive(:pool_name).and_return('default')
|
|
|
|
|
|
|
|
|
|
env[:domain_volumes].push({
|
|
|
|
|
:device=>'vdb',
|
|
|
|
|
:bus=>'virtio',
|
|
|
|
|
:cache=>'default',
|
|
|
|
|
:absolute_path=>'/var/lib/libvirt/images/vagrant-test_default_1.img',
|
|
|
|
|
:path=>"/test/box_1.img",
|
|
|
|
|
:name=>"test_vagrant_box_image_1.1.1_1.img",
|
|
|
|
|
:virtual_size=> ByteNumber.new(5),
|
|
|
|
|
:pool=>'default',
|
|
|
|
|
})
|
2021-09-28 13:17:22 +01:00
|
|
|
end
|
|
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
it 'should list multiple device entries' do
|
|
|
|
|
expect(ui).to receive(:info).with(/ -- Image\(vda\):.*/)
|
|
|
|
|
expect(ui).to receive(:info).with(/ -- Image\(vdb\):.*/)
|
|
|
|
|
expect(servers).to receive(:create).with(xml: domain_xml).and_return(machine)
|
2020-10-23 14:31:29 +01:00
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
expect(subject.call(env)).to be_nil
|
2020-10-23 14:31:29 +01:00
|
|
|
end
|
|
|
|
|
end
|
2022-06-25 15:48:05 +01:00
|
|
|
|
|
|
|
|
context 'with disk controller model virtio-scsi' do
|
|
|
|
|
before do
|
|
|
|
|
allow(machine.provider_config).to receive(:disk_controller_model).and_return('virtio-scsi')
|
|
|
|
|
expect(volumes).to receive(:all).with(name: 'vagrant-test_default.img').and_return([domain_volume])
|
|
|
|
|
|
|
|
|
|
env[:domain_volumes][0][:bus] = 'scsi'
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'should add a virtio-scsi disk controller' do
|
|
|
|
|
expect(ui).to receive(:info).with(/ -- Image\(vda\):.*/)
|
|
|
|
|
expect(servers).to receive(:create) do |args|
|
|
|
|
|
expect(args[:xml]).to match(/<controller type='scsi' model='virtio-scsi' index='0'\/>/)
|
|
|
|
|
end.and_return(machine)
|
|
|
|
|
|
|
|
|
|
expect(subject.call(env)).to be_nil
|
|
|
|
|
end
|
|
|
|
|
end
|
2022-08-16 18:44:11 +02:00
|
|
|
|
2022-11-10 12:22:37 +00:00
|
|
|
context 'launchSecurity' do
|
|
|
|
|
let(:vagrantfile_providerconfig) do
|
|
|
|
|
<<-EOF
|
|
|
|
|
libvirt.launchsecurity :type => 'sev', :cbitpos => 47, :reducedPhysBits => 1, :policy => "0x0003"
|
|
|
|
|
EOF
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'should emit the settings to the ui' do
|
|
|
|
|
expect(ui).to receive(:info).with(/ -- Launch security: type=sev, cbitpos=47, reducedPhysBits=1, policy=0x0003/)
|
|
|
|
|
expect(servers).to receive(:create).and_return(machine)
|
|
|
|
|
|
|
|
|
|
expect(subject.call(env)).to be_nil
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'memtunes' do
|
|
|
|
|
let(:vagrantfile_providerconfig) do
|
|
|
|
|
<<-EOF
|
|
|
|
|
libvirt.memtune :type => 'hard_limit', :value => 250000
|
|
|
|
|
libvirt.memtune :type => 'soft_limit', :value => 200000
|
|
|
|
|
EOF
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'should emit the settings to the ui' do
|
|
|
|
|
expect(ui).to receive(:info).with(/ -- Memory Tuning: hard_limit: unit='KiB', value: 250000/)
|
|
|
|
|
expect(ui).to receive(:info).with(/ -- Memory Tuning: soft_limit: unit='KiB', value: 200000/)
|
|
|
|
|
expect(servers).to receive(:create).and_return(machine)
|
|
|
|
|
|
|
|
|
|
expect(subject.call(env)).to be_nil
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2022-08-16 18:44:11 +02:00
|
|
|
context 'sysinfo' do
|
|
|
|
|
let(:domain_xml_file) { 'sysinfo.xml' }
|
|
|
|
|
let(:vagrantfile_providerconfig) do
|
|
|
|
|
<<-EOF
|
|
|
|
|
libvirt.sysinfo = {
|
|
|
|
|
'bios': {
|
|
|
|
|
'vendor': 'Test Vendor',
|
|
|
|
|
'version': '',
|
|
|
|
|
},
|
|
|
|
|
'system': {
|
|
|
|
|
'manufacturer': 'Test Manufacturer',
|
|
|
|
|
'version': '0.1.0',
|
|
|
|
|
'serial': '',
|
|
|
|
|
},
|
|
|
|
|
'base board': {
|
|
|
|
|
'manufacturer': 'Test Manufacturer',
|
|
|
|
|
'version': '',
|
|
|
|
|
},
|
|
|
|
|
'chassis': {
|
|
|
|
|
'manufacturer': 'Test Manufacturer',
|
|
|
|
|
'serial': 'AABBCCDDEE',
|
|
|
|
|
'asset': '',
|
|
|
|
|
},
|
|
|
|
|
'oem strings': [
|
|
|
|
|
'app1: string1',
|
|
|
|
|
'app1: string2',
|
|
|
|
|
'app2: string1',
|
|
|
|
|
'app2: string2',
|
|
|
|
|
'',
|
|
|
|
|
'',
|
|
|
|
|
],
|
|
|
|
|
}
|
|
|
|
|
EOF
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'should populate sysinfo as expected' do
|
|
|
|
|
expect(servers).to receive(:create).with(xml: domain_xml).and_return(machine)
|
|
|
|
|
|
|
|
|
|
expect(subject.call(env)).to be_nil
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'with block of empty entries' do
|
|
|
|
|
let(:domain_xml_file) { 'sysinfo_only_required.xml' }
|
|
|
|
|
let(:vagrantfile_providerconfig) do
|
|
|
|
|
<<-EOF
|
|
|
|
|
libvirt.sysinfo = {
|
|
|
|
|
'bios': {
|
|
|
|
|
'vendor': 'Test Vendor',
|
|
|
|
|
},
|
|
|
|
|
'system': {
|
|
|
|
|
'serial': '',
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
EOF
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'should skip outputting the surrounding tags' do
|
|
|
|
|
expect(servers).to receive(:create).with(xml: domain_xml).and_return(machine)
|
|
|
|
|
|
|
|
|
|
expect(subject.call(env)).to be_nil
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2020-10-23 14:31:29 +01:00
|
|
|
end
|
|
|
|
|
|
2020-12-05 15:49:25 +00:00
|
|
|
context 'connection => qemu:///session' do
|
2021-12-11 14:58:59 +00:00
|
|
|
before do
|
|
|
|
|
allow(machine.provider_config).to receive(:qemu_use_session).and_return(true)
|
2020-12-05 15:49:25 +00:00
|
|
|
end
|
|
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
it 'should execute correctly' do
|
|
|
|
|
expect(servers).to receive(:create).and_return(machine)
|
2020-12-05 15:49:25 +00:00
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
expect(subject.call(env)).to be_nil
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'additional disks' do
|
|
|
|
|
let(:vagrantfile_providerconfig) do
|
|
|
|
|
<<-EOF
|
|
|
|
|
libvirt.qemu_use_session = true
|
|
|
|
|
EOF
|
2020-12-05 15:49:25 +00:00
|
|
|
end
|
2020-10-23 14:31:29 +01:00
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
let(:disks) do
|
|
|
|
|
[
|
|
|
|
|
:device => 'vdb',
|
|
|
|
|
:cache => 'default',
|
|
|
|
|
:bus => 'virtio',
|
|
|
|
|
:type => 'qcow2',
|
|
|
|
|
:absolute_path => '/var/lib/libvirt/images/vagrant-test_default-vdb.qcow2',
|
|
|
|
|
:virtual_size => ByteNumber.new(20*1024*1024*1024),
|
|
|
|
|
:pool => 'default',
|
|
|
|
|
]
|
|
|
|
|
end
|
2020-12-05 15:49:25 +00:00
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
before do
|
|
|
|
|
expect(Process).to receive(:uid).and_return(9999).at_least(:once)
|
|
|
|
|
expect(Process).to receive(:gid).and_return(9999).at_least(:once)
|
2021-09-28 13:17:22 +01:00
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
env[:disks] = disks
|
2021-09-28 13:17:22 +01:00
|
|
|
end
|
|
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
context 'volume create succeeded' do
|
|
|
|
|
it 'should complete' do
|
|
|
|
|
expect(volumes).to receive(:create).with(
|
|
|
|
|
hash_including(
|
|
|
|
|
:path => "/var/lib/libvirt/images/vagrant-test_default-vdb.qcow2",
|
|
|
|
|
:owner => 9999,
|
|
|
|
|
:group => 9999,
|
|
|
|
|
:pool_name => "default",
|
2020-12-05 15:49:25 +00:00
|
|
|
)
|
2022-06-02 19:09:18 +01:00
|
|
|
)
|
|
|
|
|
expect(servers).to receive(:create).and_return(machine)
|
2020-12-05 15:49:25 +00:00
|
|
|
|
2022-06-02 19:09:18 +01:00
|
|
|
expect(subject.call(env)).to be_nil
|
2020-12-05 15:49:25 +00:00
|
|
|
end
|
|
|
|
|
end
|
2020-10-23 14:31:29 +01:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|