mirror of
https://github.com/vagrant-libvirt/vagrant-libvirt.git
synced 2025-02-25 18:55:27 -06:00
Add action to resolve disk settings (#1502)
With multi volume boxes, need to ensure that disk settings such as the device assigned are resolved dynamically once it has been established which devices have already been assigned to the box volumes on either initial creation or subsequent boots. Otherwise users are forced to always explicitly define the device for additional storage instead of having it be automatically assigned the next available device. Consequently previous changes have broken the ability for machines with additional storage to be halted and restarted correctly. Include an integration test that for additional storage checks that the machine can be stopped and started again. Fixes: #1490
This commit is contained in:
@@ -35,6 +35,7 @@ module VagrantPlugins
|
||||
autoload :ReadMacAddresses, action_root.join('read_mac_addresses')
|
||||
autoload :RemoveLibvirtImage, action_root.join('remove_libvirt_image')
|
||||
autoload :RemoveStaleVolume, action_root.join('remove_stale_volume')
|
||||
autoload :ResolveDiskSettings, action_root.join('resolve_disk_settings')
|
||||
autoload :ResumeDomain, action_root.join('resume_domain')
|
||||
autoload :SetNameOfDomain, action_root.join('set_name_of_domain')
|
||||
autoload :SetBootOrder, action_root.join('set_boot_order')
|
||||
@@ -81,6 +82,7 @@ module VagrantPlugins
|
||||
b2.use SetNameOfDomain
|
||||
|
||||
if !env[:machine].config.vm.box
|
||||
b2.use ResolveDiskSettings
|
||||
b2.use CreateDomain
|
||||
b2.use CreateNetworks
|
||||
b2.use CreateNetworkInterfaces
|
||||
@@ -94,6 +96,7 @@ module VagrantPlugins
|
||||
b2.use HandleBox
|
||||
b2.use HandleBoxImage
|
||||
b2.use CreateDomainVolume
|
||||
b2.use ResolveDiskSettings
|
||||
b2.use CreateDomain
|
||||
b2.use CreateNetworks
|
||||
b2.use CreateNetworkInterfaces
|
||||
@@ -104,6 +107,7 @@ module VagrantPlugins
|
||||
end
|
||||
else
|
||||
env[:halt_on_error] = true
|
||||
b2.use ResolveDiskSettings
|
||||
b2.use CreateNetworks
|
||||
b2.use action_start
|
||||
end
|
||||
|
||||
@@ -16,20 +16,6 @@ module VagrantPlugins
|
||||
@app = app
|
||||
end
|
||||
|
||||
def _disk_name(name, disk)
|
||||
"#{name}-#{disk[:device]}.#{disk[:type]}" # disk name
|
||||
end
|
||||
|
||||
def _disks_print(disks)
|
||||
disks.collect do |x|
|
||||
"#{x[:device]}(#{x[:type]}, #{x[:bus]}, #{x[:size]})"
|
||||
end.join(', ')
|
||||
end
|
||||
|
||||
def _cdroms_print(cdroms)
|
||||
cdroms.collect { |x| x[:dev] }.join(', ')
|
||||
end
|
||||
|
||||
def call(env)
|
||||
# Get config.
|
||||
config = env[:machine].provider_config
|
||||
@@ -58,8 +44,6 @@ module VagrantPlugins
|
||||
@nvram = config.nvram
|
||||
@machine_type = config.machine_type
|
||||
@machine_arch = config.machine_arch
|
||||
@disk_bus = config.disk_bus
|
||||
@disk_device = config.disk_device
|
||||
@disk_driver_opts = config.disk_driver_opts
|
||||
@nested = config.nested
|
||||
@memory_size = config.memory.to_i * 1024
|
||||
@@ -94,9 +78,8 @@ module VagrantPlugins
|
||||
|
||||
# Storage
|
||||
@storage_pool_name = config.storage_pool_name
|
||||
@snapshot_pool_name = config.snapshot_pool_name
|
||||
@domain_volumes = []
|
||||
@disks = config.disks
|
||||
@domain_volumes = env[:domain_volumes] || []
|
||||
@disks = env[:disks] || []
|
||||
@cdroms = config.cdroms
|
||||
|
||||
# Input
|
||||
@@ -139,77 +122,19 @@ module VagrantPlugins
|
||||
@memballoon_pci_bus = config.memballoon_pci_bus
|
||||
@memballoon_pci_slot = config.memballoon_pci_slot
|
||||
|
||||
config = env[:machine].provider_config
|
||||
@domain_type = config.driver
|
||||
|
||||
@os_type = 'hvm'
|
||||
|
||||
resolver = ::VagrantPlugins::ProviderLibvirt::Util::DiskDeviceResolver.new(prefix=@disk_device[0..1])
|
||||
|
||||
# Get path to domain image from the storage pool selected if we have a box.
|
||||
if env[:machine].config.vm.box
|
||||
if @snapshot_pool_name != @storage_pool_name
|
||||
pool_name = @snapshot_pool_name
|
||||
else
|
||||
pool_name = @storage_pool_name
|
||||
end
|
||||
|
||||
# special handling for domain volume
|
||||
env[:box_volumes][0][:device] = env[:box_volumes][0].fetch(:device, @disk_device)
|
||||
|
||||
resolver.resolve!(env[:box_volumes])
|
||||
|
||||
@logger.debug "Search for volumes in pool: #{pool_name}"
|
||||
env[:box_volumes].each_index do |index|
|
||||
env[:domain_volumes].each_with_index do |vol, index|
|
||||
suffix_index = index > 0 ? "_#{index}" : ''
|
||||
domain_volume = env[:machine].provider.driver.connection.volumes.all(
|
||||
name: "#{@name}#{suffix_index}.img"
|
||||
).find { |x| x.pool_name == pool_name }
|
||||
raise Errors::DomainVolumeExists if domain_volume.nil?
|
||||
|
||||
@domain_volumes.push({
|
||||
:dev => env[:box_volumes][index][:device],
|
||||
:cache => @domain_volume_cache,
|
||||
:bus => @disk_bus,
|
||||
:path => domain_volume.path,
|
||||
:virtual_size => env[:box_volumes][index][:virtual_size]
|
||||
})
|
||||
).find { |x| x.pool_name == vol[:pool] }
|
||||
raise Errors::NoDomainVolume if domain_volume.nil?
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# If we have a box, take the path from the domain volume and set our storage_prefix.
|
||||
# If not, we dump the storage pool xml to get its defined path.
|
||||
# the default storage prefix is typically: /var/lib/libvirt/images/
|
||||
if env[:machine].config.vm.box
|
||||
storage_prefix = File.dirname(@domain_volumes[0][:path]) + '/' # steal
|
||||
else
|
||||
storage_prefix = get_disk_storage_prefix(env, @storage_pool_name)
|
||||
end
|
||||
|
||||
resolver.resolve!(@disks)
|
||||
|
||||
@disks.each do |disk|
|
||||
disk[:path] ||= _disk_name(@name, disk)
|
||||
|
||||
# On volume creation, the <path> element inside <target>
|
||||
# is oddly ignored; instead the path is taken from the
|
||||
# <name> element:
|
||||
# http://www.redhat.com/archives/libvir-list/2008-August/msg00329.html
|
||||
disk[:name] = disk[:path]
|
||||
|
||||
disk[:absolute_path] = storage_prefix + disk[:path]
|
||||
|
||||
if not disk[:pool].nil?
|
||||
disk_pool_name = disk[:pool]
|
||||
@logger.debug "Overriding pool name with: #{disk_pool_name}"
|
||||
disk_storage_prefix = get_disk_storage_prefix(env, disk_pool_name)
|
||||
disk[:absolute_path] = disk_storage_prefix + disk[:path]
|
||||
@logger.debug "Overriding disk path with: #{disk[:absolute_path]}"
|
||||
else
|
||||
disk_pool_name = @storage_pool_name
|
||||
end
|
||||
|
||||
# make the disk. equivalent to:
|
||||
# qemu-img create -f qcow2 <path> 5g
|
||||
begin
|
||||
@@ -221,13 +146,13 @@ module VagrantPlugins
|
||||
owner: storage_uid(env),
|
||||
group: storage_gid(env),
|
||||
#:allocation => ?,
|
||||
pool_name: disk_pool_name
|
||||
pool_name: disk[:pool],
|
||||
)
|
||||
rescue Libvirt::Error => e
|
||||
# It is hard to believe that e contains just a string
|
||||
# and no useful error code!
|
||||
msg = "Call to virStorageVolCreateXML failed: " +
|
||||
"storage volume '#{disk[:path]}' exists already"
|
||||
"storage volume '#{disk[:absolute_path]}' exists already"
|
||||
if e.message == msg and disk[:allow_existing]
|
||||
disk[:preexisting] = true
|
||||
else
|
||||
@@ -300,7 +225,7 @@ module VagrantPlugins
|
||||
end
|
||||
env[:ui].info(" -- Storage pool: #{@storage_pool_name}")
|
||||
@domain_volumes.each do |volume|
|
||||
env[:ui].info(" -- Image(#{volume[:dev]}): #{volume[:path]}, #{volume[:bus]}, #{volume[:virtual_size].to_GB}G")
|
||||
env[:ui].info(" -- Image(#{volume[:device]}): #{volume[:absolute_path]}, #{volume[:bus]}, #{volume[:virtual_size].to_GB}G")
|
||||
end
|
||||
|
||||
if not @disk_driver_opts.empty?
|
||||
@@ -466,11 +391,14 @@ module VagrantPlugins
|
||||
end
|
||||
|
||||
private
|
||||
def get_disk_storage_prefix(env, disk_pool_name)
|
||||
disk_storage_pool = env[:machine].provider.driver.connection.client.lookup_storage_pool_by_name(disk_pool_name)
|
||||
raise Errors::NoStoragePool if disk_storage_pool.nil?
|
||||
xml = Nokogiri::XML(disk_storage_pool.xml_desc)
|
||||
disk_storage_prefix = xml.xpath('/pool/target/path').inner_text.to_s + '/'
|
||||
def _disks_print(disks)
|
||||
disks.collect do |x|
|
||||
"#{x[:device]}(#{x[:type]}, #{x[:bus]}, #{x[:size]})"
|
||||
end.join(', ')
|
||||
end
|
||||
|
||||
def _cdroms_print(cdroms)
|
||||
cdroms.collect { |x| x[:dev] }.join(', ')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -62,7 +62,7 @@ module VagrantPlugins
|
||||
disks_xml = REXML::XPath.match(xml_descr, '/domain/devices/disk[@device="disk"]')
|
||||
have_aliases = !(REXML::XPath.match(disks_xml, './alias[@name="ua-box-volume-0"]').first).nil?
|
||||
if !have_aliases
|
||||
env[:ui].warn(I18n.t('vagrant_libvirt.destroy.obsolete_method'))
|
||||
env[:ui].warn(I18n.t('vagrant_libvirt.domain_xml.obsolete_method'))
|
||||
end
|
||||
|
||||
destroy_domain(domain, destroy_volumes: false, flags: undefine_flags)
|
||||
|
||||
@@ -104,6 +104,8 @@ module VagrantPlugins
|
||||
end
|
||||
# save for use by later actions
|
||||
env[:box_volumes][0][:virtual_size] = box_virtual_size
|
||||
# special handling for domain volume
|
||||
env[:box_volumes][0][:device] ||= config.disk_device
|
||||
|
||||
# while inside the synchronize block take care not to call the next
|
||||
# action in the chain, as must exit this block first to prevent
|
||||
|
||||
174
lib/vagrant-libvirt/action/resolve_disk_settings.rb
Normal file
174
lib/vagrant-libvirt/action/resolve_disk_settings.rb
Normal file
@@ -0,0 +1,174 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'log4r'
|
||||
require 'rexml'
|
||||
|
||||
require 'vagrant-libvirt/util/resolvers'
|
||||
|
||||
module VagrantPlugins
|
||||
module ProviderLibvirt
|
||||
module Action
|
||||
class ResolveDiskSettings
|
||||
def initialize(app, _env)
|
||||
@logger = Log4r::Logger.new('vagrant_libvirt::action::resolve_disk_devices')
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
# Get config.
|
||||
config = env[:machine].provider_config
|
||||
|
||||
domain_name = env[:domain_name] # only set on create
|
||||
disk_bus = config.disk_bus
|
||||
disk_device = config.disk_device
|
||||
domain_volume_cache = config.volume_cache || 'default'
|
||||
|
||||
# Storage
|
||||
storage_pool_name = config.storage_pool_name
|
||||
snapshot_pool_name = config.snapshot_pool_name
|
||||
domain_volumes = []
|
||||
disks = config.disks.dup
|
||||
|
||||
resolver = ::VagrantPlugins::ProviderLibvirt::Util::DiskDeviceResolver.new(disk_device[0..1])
|
||||
|
||||
# Get path to domain image from the storage pool selected if we have a box.
|
||||
if env[:machine].config.vm.box
|
||||
pool_name = if snapshot_pool_name == storage_pool_name
|
||||
storage_pool_name
|
||||
else
|
||||
snapshot_pool_name
|
||||
end
|
||||
|
||||
if env[:box_volumes].nil?
|
||||
# domain must be already created, need to read domain volumes from domain XML
|
||||
libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(
|
||||
env[:machine].id
|
||||
)
|
||||
domain_xml = libvirt_domain.xml_desc(1)
|
||||
xml_descr = REXML::Document.new(domain_xml)
|
||||
domain_name = xml_descr.elements['domain'].elements['name'].text
|
||||
disks_xml = REXML::XPath.match(xml_descr, '/domain/devices/disk[@device="disk"]')
|
||||
have_aliases = !REXML::XPath.match(disks_xml, './alias[@name="ua-box-volume-0"]').first.nil?
|
||||
env[:ui].warn(I18n.t('vagrant_libvirt.domain_xml.obsolete_method')) unless have_aliases
|
||||
|
||||
if have_aliases
|
||||
REXML::XPath.match(disks_xml,
|
||||
'./alias[contains(@name, "ua-box-volume-")]').each_with_index do |alias_xml, idx|
|
||||
domain_volumes.push(volume_from_xml(alias_xml.parent, domain_name, idx))
|
||||
end
|
||||
else
|
||||
# fallback to try and infer which boxes are box images, as they are listed first
|
||||
# as soon as there is no match, can exit
|
||||
disks_xml.each_with_index do |box_disk_xml, idx|
|
||||
diskname = box_disk_xml.elements['source'].attributes['file'].rpartition('/').last
|
||||
|
||||
break if volume_name(domain_name, idx) != diskname
|
||||
|
||||
domain_volumes.push(volume_from_xml(box_disk_xml, domain_name, idx))
|
||||
end
|
||||
end
|
||||
else
|
||||
|
||||
@logger.debug "Search for volumes in pool: #{pool_name}"
|
||||
env[:box_volumes].each_index do |index|
|
||||
domain_volume = env[:machine].provider.driver.connection.volumes.all(
|
||||
name: volume_name(domain_name, index)
|
||||
).find { |x| x.pool_name == pool_name }
|
||||
raise Errors::NoDomainVolume if domain_volume.nil?
|
||||
|
||||
domain_volumes.push(
|
||||
{
|
||||
name: volume_name(domain_name, index),
|
||||
device: env[:box_volumes][index][:device],
|
||||
cache: domain_volume_cache,
|
||||
bus: disk_bus,
|
||||
absolute_path: domain_volume.path,
|
||||
virtual_size: env[:box_volumes][index][:virtual_size],
|
||||
pool: pool_name,
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
resolver.resolve!(domain_volumes)
|
||||
|
||||
# If we have a box, take the path from the domain volume and set our storage_prefix.
|
||||
# If not, we dump the storage pool xml to get its defined path.
|
||||
# the default storage prefix is typically: /var/lib/libvirt/images/
|
||||
storage_prefix = "#{File.dirname(domain_volumes[0][:absolute_path])}/" # steal
|
||||
else
|
||||
# Ensure domain name is set for subsequent steps if restarting a machine without a box
|
||||
libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(
|
||||
env[:machine].id
|
||||
)
|
||||
domain_xml = libvirt_domain.xml_desc(1)
|
||||
xml_descr = REXML::Document.new(domain_xml)
|
||||
domain_name = xml_descr.elements['domain'].elements['name'].text
|
||||
|
||||
storage_prefix = get_disk_storage_prefix(env[:machine], storage_pool_name)
|
||||
end
|
||||
|
||||
resolver.resolve!(disks)
|
||||
|
||||
disks.each do |disk|
|
||||
disk[:path] ||= disk_name(domain_name, disk)
|
||||
|
||||
# On volume creation, the <path> element inside <target>
|
||||
# is oddly ignored; instead the path is taken from the
|
||||
# <name> element:
|
||||
# http://www.redhat.com/archives/libvir-list/2008-August/msg00329.html
|
||||
disk[:name] = disk[:path]
|
||||
|
||||
disk[:absolute_path] = storage_prefix + disk[:path]
|
||||
|
||||
if disk[:pool].nil?
|
||||
disk[:pool] = storage_pool_name
|
||||
else
|
||||
@logger.debug "Overriding pool name with: #{disk[:pool]}"
|
||||
disk_storage_prefix = get_disk_storage_prefix(env[:machine], disk[:pool])
|
||||
disk[:absolute_path] = disk_storage_prefix + disk[:path]
|
||||
@logger.debug "Overriding disk path with: #{disk[:absolute_path]}"
|
||||
end
|
||||
end
|
||||
|
||||
env[:domain_volumes] = domain_volumes
|
||||
env[:disks] = disks
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def disk_name(name, disk)
|
||||
"#{name}-#{disk[:device]}.#{disk[:type]}" # disk name
|
||||
end
|
||||
|
||||
def get_disk_storage_prefix(machine, disk_pool_name)
|
||||
disk_storage_pool = machine.provider.driver.connection.client.lookup_storage_pool_by_name(disk_pool_name)
|
||||
raise Errors::NoStoragePool if disk_storage_pool.nil?
|
||||
|
||||
xml = Nokogiri::XML(disk_storage_pool.xml_desc)
|
||||
"#{xml.xpath('/pool/target/path').inner_text}/"
|
||||
end
|
||||
|
||||
def volume_name(domain_name, index)
|
||||
domain_name + (index.zero? ? '.img' : "_#{index}.img")
|
||||
end
|
||||
|
||||
def volume_from_xml(device_xml, domain_name, index)
|
||||
driver = device_xml.elements['driver']
|
||||
source = device_xml.elements['source']
|
||||
target = device_xml.elements['target']
|
||||
|
||||
{
|
||||
name: volume_name(domain_name, index),
|
||||
device: target.attributes['dev'],
|
||||
cache: driver.attributes['cache'],
|
||||
bus: target.attributes['bus'],
|
||||
absolute_path: source.attributes['file'],
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -117,9 +117,9 @@
|
||||
@disk_driver_opts.reject { |k,v| v.nil? }
|
||||
.map { |k,v| "#{k}='#{v}'"}
|
||||
.join(' ') -%>/>
|
||||
<source file='<%= volume[:path] %>'/>
|
||||
<source file='<%= volume[:absolute_path] %>'/>
|
||||
<%# we need to ensure a unique target dev -%>
|
||||
<target dev='<%= volume[:dev] %>' bus='<%= volume[:bus] %>'/>
|
||||
<target dev='<%= volume[:device] %>' bus='<%= volume[:bus] %>'/>
|
||||
</disk>
|
||||
<%- end -%>
|
||||
<%# additional disks -%>
|
||||
|
||||
@@ -58,9 +58,11 @@ en:
|
||||
remove_stale_volume: |-
|
||||
Remove stale volume...
|
||||
|
||||
destroy:
|
||||
domain_xml:
|
||||
obsolete_method: |
|
||||
Destroying machine that was originally created without device aliases (pre 0.6.0), using fallback approach.
|
||||
Machine that was originally created without device aliases (pre 0.6.0), using fall-back approach for device identification.
|
||||
|
||||
destroy:
|
||||
unexpected_volumes: |
|
||||
Unexpected number of volumes detected, possibly additional volumes attached outside of vagrant-libvirt.
|
||||
Attempting to handle this correctly, however may experience unexpected behaviour in the domain destroy.
|
||||
|
||||
@@ -21,8 +21,6 @@ describe VagrantPlugins::ProviderLibvirt::Action::CreateDomain do
|
||||
let(:domain_volume) { instance_double(::Fog::Libvirt::Compute::Volume) }
|
||||
|
||||
let(:domain_xml) { File.read(File.join(File.dirname(__FILE__), File.basename(__FILE__, '.rb'), domain_xml_file)) }
|
||||
let(:storage_pool_xml) { File.read(File.join(File.dirname(__FILE__), File.basename(__FILE__, '.rb'), storage_pool_xml_file)) }
|
||||
let(:libvirt_storage_pool) { double('storage_pool') }
|
||||
|
||||
describe '#call' do
|
||||
before do
|
||||
@@ -39,15 +37,17 @@ describe VagrantPlugins::ProviderLibvirt::Action::CreateDomain do
|
||||
|
||||
env[:domain_name] = "vagrant-test_default"
|
||||
|
||||
env[:box_volumes] = []
|
||||
env[:box_volumes].push({
|
||||
env[:domain_volumes] = []
|
||||
env[:domain_volumes].push({
|
||||
:device=>'vda',
|
||||
:bus=>'virtio',
|
||||
:cache=>'default',
|
||||
:absolute_path=>'/var/lib/libvirt/images/vagrant-test_default.img',
|
||||
:path=>"/test/box.img",
|
||||
:name=>"test_vagrant_box_image_1.1.1_0.img",
|
||||
:name=>'test_vagrant_box_image_1.1.1_0.img',
|
||||
:virtual_size=> ByteNumber.new(5),
|
||||
:pool=>'default',
|
||||
})
|
||||
# should be ignored for system session and used for user session
|
||||
allow(Process).to receive(:uid).and_return(9999)
|
||||
allow(Process).to receive(:gid).and_return(9999)
|
||||
end
|
||||
|
||||
context 'connection => qemu:///system' do
|
||||
@@ -57,7 +57,6 @@ describe VagrantPlugins::ProviderLibvirt::Action::CreateDomain do
|
||||
allow(machine.provider_config).to receive(:qemu_use_session).and_return(false)
|
||||
end
|
||||
|
||||
context 'default pool' do
|
||||
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
|
||||
@@ -65,30 +64,21 @@ describe VagrantPlugins::ProviderLibvirt::Action::CreateDomain do
|
||||
expect(subject.call(env)).to be_nil
|
||||
end
|
||||
|
||||
context 'with no box' do
|
||||
let(:storage_pool_xml_file) { 'default_system_storage_pool.xml' }
|
||||
let(:vagrantfile) do
|
||||
<<-EOF
|
||||
Vagrant.configure('2') do |config|
|
||||
config.vm.define :test
|
||||
end
|
||||
EOF
|
||||
end
|
||||
|
||||
it 'should query for the storage pool path' do
|
||||
expect(libvirt_client).to receive(:lookup_storage_pool_by_name).and_return(libvirt_storage_pool)
|
||||
expect(libvirt_storage_pool).to receive(:xml_desc).and_return(storage_pool_xml)
|
||||
expect(servers).to receive(:create).and_return(machine)
|
||||
|
||||
expect(subject.call(env)).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'additional disks' do
|
||||
let(:vagrantfile_providerconfig) do
|
||||
<<-EOF
|
||||
libvirt.storage :file, :size => '20G'
|
||||
EOF
|
||||
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
|
||||
|
||||
before do
|
||||
env[:disks] = disks
|
||||
end
|
||||
|
||||
context 'volume create failed' do
|
||||
@@ -120,11 +110,10 @@ describe VagrantPlugins::ProviderLibvirt::Action::CreateDomain do
|
||||
|
||||
context 'with custom disk device setting' do
|
||||
let(:domain_xml_file) { 'custom_disk_settings.xml' }
|
||||
let(:vagrantfile_providerconfig) {
|
||||
<<-EOF
|
||||
libvirt.disk_device = 'sda'
|
||||
EOF
|
||||
}
|
||||
|
||||
before do
|
||||
env[:domain_volumes][0][:device] = 'sda'
|
||||
end
|
||||
|
||||
it 'should set the domain device' do
|
||||
expect(ui).to receive(:info).with(/ -- Image\(sda\):.*/)
|
||||
@@ -139,19 +128,23 @@ describe VagrantPlugins::ProviderLibvirt::Action::CreateDomain do
|
||||
let(:domain_volume_2) { double('domain_volume 2') }
|
||||
|
||||
before do
|
||||
expect(volumes).to receive(:all).and_return([domain_volume])
|
||||
expect(volumes).to receive(:all).and_return([domain_volume_2])
|
||||
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')
|
||||
expect(domain_volume_2).to receive(:path).and_return('/var/lib/libvirt/images/vagrant-test_default_1.img')
|
||||
|
||||
env[:box_volumes].push({
|
||||
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',
|
||||
})
|
||||
end
|
||||
|
||||
it 'should correctly assign device entries' do
|
||||
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)
|
||||
@@ -161,65 +154,43 @@ describe VagrantPlugins::ProviderLibvirt::Action::CreateDomain do
|
||||
end
|
||||
end
|
||||
|
||||
context 'no default pool' do
|
||||
let(:vagrantfile) do
|
||||
<<-EOF
|
||||
Vagrant.configure('2') do |config|
|
||||
config.vm.define :test
|
||||
end
|
||||
EOF
|
||||
end
|
||||
|
||||
it 'should raise an exception' do
|
||||
expect(libvirt_client).to receive(:lookup_storage_pool_by_name).and_return(nil)
|
||||
|
||||
expect{ subject.call(env) }.to raise_error(VagrantPlugins::ProviderLibvirt::Errors::NoStoragePool)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'connection => qemu:///session' do
|
||||
before do
|
||||
allow(machine.provider_config).to receive(:qemu_use_session).and_return(true)
|
||||
end
|
||||
|
||||
context 'default pool' do
|
||||
it 'should execute correctly' do
|
||||
expect(servers).to receive(:create).and_return(machine)
|
||||
|
||||
expect(subject.call(env)).to be_nil
|
||||
end
|
||||
|
||||
context 'with no box' do
|
||||
let(:storage_pool_xml_file) { 'default_user_storage_pool.xml' }
|
||||
let(:vagrantfile) do
|
||||
<<-EOF
|
||||
Vagrant.configure('2') do |config|
|
||||
config.vm.define :test
|
||||
config.vm.provider :libvirt do |libvirt|
|
||||
#{vagrantfile_providerconfig}
|
||||
end
|
||||
end
|
||||
EOF
|
||||
end
|
||||
|
||||
it 'should query for the storage pool path' do
|
||||
expect(libvirt_client).to receive(:lookup_storage_pool_by_name).and_return(libvirt_storage_pool)
|
||||
expect(libvirt_storage_pool).to receive(:xml_desc).and_return(storage_pool_xml)
|
||||
expect(servers).to receive(:create).and_return(machine)
|
||||
|
||||
expect(subject.call(env)).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'additional disks' do
|
||||
let(:vagrantfile_providerconfig) do
|
||||
<<-EOF
|
||||
libvirt.qemu_use_session = true
|
||||
libvirt.storage :file, :size => '20G'
|
||||
EOF
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
before do
|
||||
expect(Process).to receive(:uid).and_return(9999).at_least(:once)
|
||||
expect(Process).to receive(:gid).and_return(9999).at_least(:once)
|
||||
|
||||
env[:disks] = disks
|
||||
end
|
||||
|
||||
context 'volume create succeeded' do
|
||||
it 'should complete' do
|
||||
expect(volumes).to receive(:create).with(
|
||||
@@ -238,5 +209,4 @@ describe VagrantPlugins::ProviderLibvirt::Action::CreateDomain do
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -145,7 +145,7 @@ describe VagrantPlugins::ProviderLibvirt::Action::DestroyDomain do
|
||||
let(:domain_xml_file) { 'box_multiple_disks_and_additional_and_custom_disks_no_aliases.xml' }
|
||||
|
||||
it 'only destroys expected disks' do
|
||||
expect(ui).to receive(:warn).with(/Destroying machine that was originally created without device aliases.*/)
|
||||
expect(ui).to receive(:warn).with(/Machine that was originally created without device aliases.*/)
|
||||
expect(ui).to receive(:warn).with(/Unexpected number of volumes detected/)
|
||||
expect(ui).to receive(:warn).with(/box metadata not available to get volume list during destroy, assuming inferred list/)
|
||||
domain_disks.each do |disk, name|
|
||||
@@ -172,7 +172,7 @@ describe VagrantPlugins::ProviderLibvirt::Action::DestroyDomain do
|
||||
end
|
||||
|
||||
it 'only destroys expected disks' do
|
||||
expect(ui).to receive(:warn).with(/Destroying machine that was originally created without device aliases.*/)
|
||||
expect(ui).to receive(:warn).with(/Machine that was originally created without device aliases.*/)
|
||||
expect(ui).to receive(:warn).with(/Unexpected number of volumes detected/)
|
||||
domain_disks.each do |disk, name|
|
||||
expect(disk).to receive(:name).and_return(name).at_least(:once)
|
||||
|
||||
@@ -59,6 +59,7 @@ describe VagrantPlugins::ProviderLibvirt::Action::HandleBoxImage do
|
||||
allow(volumes).to receive(:all).and_return(all)
|
||||
allow(env[:ui]).to receive(:clear_line)
|
||||
|
||||
env[:machine].provider_config.disk_device = 'vda'
|
||||
end
|
||||
|
||||
context 'when one disk in metadata.json' do
|
||||
@@ -86,7 +87,8 @@ describe VagrantPlugins::ProviderLibvirt::Action::HandleBoxImage do
|
||||
:path=>"/test/box.img",
|
||||
:name=>"test_vagrant_box_image_1.1.1_box.img",
|
||||
:virtual_size=>byte_number_5G,
|
||||
:format=>"qcow2"
|
||||
:format=>"qcow2",
|
||||
:device=>'vda',
|
||||
}
|
||||
]
|
||||
)
|
||||
@@ -115,7 +117,8 @@ describe VagrantPlugins::ProviderLibvirt::Action::HandleBoxImage do
|
||||
:path=>"/test/box.img",
|
||||
:name=>"test_vagrant_box_image_0_#{box_mtime.to_i}_box.img",
|
||||
:virtual_size=>byte_number_5G,
|
||||
:format=>"qcow2"
|
||||
:format=>"qcow2",
|
||||
:device=>'vda',
|
||||
}
|
||||
]
|
||||
)
|
||||
@@ -124,7 +127,7 @@ describe VagrantPlugins::ProviderLibvirt::Action::HandleBoxImage do
|
||||
|
||||
context 'When config.machine_virtual_size is set and smaller than box_virtual_size' do
|
||||
before do
|
||||
allow(env[:machine]).to receive_message_chain("provider_config.machine_virtual_size").and_return(1)
|
||||
env[:machine].provider_config.machine_virtual_size = 1
|
||||
end
|
||||
it 'should warning must be raise' do
|
||||
expect(ui).to receive(:warn).with("Ignoring requested virtual disk size of '1' as it is below\nthe minimum box image size of '5'.")
|
||||
@@ -135,7 +138,8 @@ describe VagrantPlugins::ProviderLibvirt::Action::HandleBoxImage do
|
||||
:path=>"/test/box.img",
|
||||
:name=>"test_vagrant_box_image_1.1.1_box.img",
|
||||
:virtual_size=>byte_number_5G,
|
||||
:format=>"qcow2"
|
||||
:format=>"qcow2",
|
||||
:device=>'vda',
|
||||
}
|
||||
]
|
||||
)
|
||||
@@ -144,7 +148,7 @@ describe VagrantPlugins::ProviderLibvirt::Action::HandleBoxImage do
|
||||
|
||||
context 'When config.machine_virtual_size is set and higher than box_virtual_size' do
|
||||
before do
|
||||
allow(env[:machine]).to receive_message_chain("provider_config.machine_virtual_size").and_return(20)
|
||||
env[:machine].provider_config.machine_virtual_size = 20
|
||||
end
|
||||
it 'should be use' do
|
||||
expect(ui).to receive(:info).with("Created volume larger than box defaults, will require manual resizing of\nfilesystems to utilize.")
|
||||
@@ -155,7 +159,8 @@ describe VagrantPlugins::ProviderLibvirt::Action::HandleBoxImage do
|
||||
:path=>"/test/box.img",
|
||||
:name=>"test_vagrant_box_image_1.1.1_box.img",
|
||||
:virtual_size=>byte_number_20G,
|
||||
:format=>"qcow2"
|
||||
:format=>"qcow2",
|
||||
:device=>'vda',
|
||||
}
|
||||
]
|
||||
)
|
||||
@@ -246,7 +251,8 @@ describe VagrantPlugins::ProviderLibvirt::Action::HandleBoxImage do
|
||||
:path=>"/test/box.img",
|
||||
:name=>"test_vagrant_box_image_1.1.1_send_box_name.img",
|
||||
:virtual_size=>byte_number_5G,
|
||||
:format=>"qcow2"
|
||||
:format=>"qcow2",
|
||||
:device=>'vda',
|
||||
},
|
||||
{
|
||||
:path=>"/test/disk.qcow2",
|
||||
|
||||
361
spec/unit/action/resolve_disk_settings_spec.rb
Normal file
361
spec/unit/action/resolve_disk_settings_spec.rb
Normal file
@@ -0,0 +1,361 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
require 'fog/libvirt/models/compute/volume'
|
||||
|
||||
require 'vagrant-libvirt/action/resolve_disk_settings'
|
||||
|
||||
describe VagrantPlugins::ProviderLibvirt::Action::ResolveDiskSettings do
|
||||
subject { described_class.new(app, env) }
|
||||
|
||||
include_context 'unit'
|
||||
include_context 'libvirt'
|
||||
|
||||
let(:servers) { double('servers') }
|
||||
let(:volumes) { double('volumes') }
|
||||
let(:domain_volume) { instance_double(::Fog::Libvirt::Compute::Volume) }
|
||||
let(:libvirt_storage_pool) { double('storage_pool') }
|
||||
|
||||
let(:domain_xml) { File.read(File.join(File.dirname(__FILE__), File.basename(__FILE__, '.rb'), domain_xml_file)) }
|
||||
let(:storage_pool_xml) do
|
||||
File.read(File.join(File.dirname(__FILE__), File.basename(__FILE__, '.rb'), storage_pool_xml_file))
|
||||
end
|
||||
|
||||
before do
|
||||
allow(logger).to receive(:info)
|
||||
allow(logger).to receive(:debug)
|
||||
end
|
||||
|
||||
describe '#call' do
|
||||
before do
|
||||
allow(connection).to receive(:volumes).and_return(volumes)
|
||||
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')
|
||||
end
|
||||
|
||||
context 'when vm box is in use' do
|
||||
context 'when box metadata is available' do
|
||||
let(:box_volumes) do
|
||||
[
|
||||
{
|
||||
path: '/test/box.img',
|
||||
name: 'test_vagrant_box_image_1.1.1_box.img',
|
||||
},
|
||||
]
|
||||
end
|
||||
|
||||
before do
|
||||
env[:domain_name] = 'vagrant-test_default'
|
||||
env[:box_volumes] = box_volumes
|
||||
end
|
||||
|
||||
it 'should populate domain volume' do
|
||||
expect(subject.call(env)).to be_nil
|
||||
expect(env[:domain_volumes]).to match(
|
||||
[
|
||||
hash_including(
|
||||
device: 'vda',
|
||||
absolute_path: '/var/lib/libvirt/images/vagrant-test_default.img'
|
||||
),
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
context 'when additional storage specified' do
|
||||
let(:vagrantfile_providerconfig) do
|
||||
<<-EOF
|
||||
libvirt.storage :file, :size => '20G'
|
||||
EOF
|
||||
end
|
||||
|
||||
it 'should use the next device for storage' do
|
||||
expect(subject.call(env)).to be_nil
|
||||
expect(env[:disks]).to match(
|
||||
[
|
||||
hash_including(
|
||||
device: 'vdb',
|
||||
absolute_path: '/var/lib/libvirt/images/vagrant-test_default-vdb.qcow2'
|
||||
),
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when custom disk device setting' do
|
||||
before do
|
||||
machine.provider_config.disk_device = 'sda'
|
||||
end
|
||||
|
||||
it 'should set the domain device' do
|
||||
expect(subject.call(env)).to be_nil
|
||||
expect(env[:domain_volumes]).to match(
|
||||
[
|
||||
hash_including(
|
||||
device: 'sda',
|
||||
absolute_path: '/var/lib/libvirt/images/vagrant-test_default.img'
|
||||
),
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
context 'when additional storage specified' do
|
||||
let(:vagrantfile_providerconfig) do
|
||||
<<-EOF
|
||||
libvirt.storage :file, :size => '20G'
|
||||
EOF
|
||||
end
|
||||
|
||||
it 'should use the next custom disk device for storage' do
|
||||
expect(subject.call(env)).to be_nil
|
||||
expect(env[:disks]).to match(
|
||||
[
|
||||
hash_including(
|
||||
device: 'sdb',
|
||||
absolute_path: '/var/lib/libvirt/images/vagrant-test_default-sdb.qcow2'
|
||||
),
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when multiple box volumes' do
|
||||
let(:box_volumes) do
|
||||
[
|
||||
{
|
||||
path: '/test/box.img',
|
||||
name: 'test_vagrant_box_image_1.1.1_box.img',
|
||||
},
|
||||
{
|
||||
path: '/test/box_2.img',
|
||||
name: 'test_vagrant_box_image_1.1.1_box_2.img',
|
||||
},
|
||||
]
|
||||
end
|
||||
it 'should populate all domain volumes' do
|
||||
expect(subject.call(env)).to be_nil
|
||||
expect(env[:domain_volumes]).to match(
|
||||
[
|
||||
hash_including(
|
||||
device: 'vda',
|
||||
absolute_path: '/var/lib/libvirt/images/vagrant-test_default.img'
|
||||
),
|
||||
hash_including(
|
||||
device: 'vdb',
|
||||
absolute_path: '/var/lib/libvirt/images/vagrant-test_default.img'
|
||||
),
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
context 'when additional storage specified' do
|
||||
let(:vagrantfile_providerconfig) do
|
||||
<<-EOF
|
||||
libvirt.storage :file, :size => '20G'
|
||||
EOF
|
||||
end
|
||||
|
||||
it 'should use the next device for storage' do
|
||||
expect(subject.call(env)).to be_nil
|
||||
expect(env[:disks]).to match(
|
||||
[
|
||||
hash_including(
|
||||
device: 'vdc',
|
||||
absolute_path: '/var/lib/libvirt/images/vagrant-test_default-vdc.qcow2'
|
||||
),
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when box metadata is not available' do
|
||||
let(:domain_xml_file) { 'default_domain.xml' }
|
||||
|
||||
before do
|
||||
expect(libvirt_client).to receive(:lookup_domain_by_uuid).and_return(libvirt_domain)
|
||||
expect(libvirt_domain).to receive(:xml_desc).and_return(domain_xml)
|
||||
end
|
||||
|
||||
it 'should query the domain xml' do
|
||||
expect(subject.call(env)).to be_nil
|
||||
expect(env[:domain_volumes]).to match(
|
||||
[
|
||||
hash_including(
|
||||
device: 'vda',
|
||||
absolute_path: '/var/lib/libvirt/images/vagrant-test_default.img'
|
||||
),
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
context 'when multiple volumes in domain config' do
|
||||
let(:domain_xml_file) { 'multi_volume_box.xml' }
|
||||
|
||||
it 'should populate domain volumes with devices' do
|
||||
expect(subject.call(env)).to be_nil
|
||||
expect(env[:domain_volumes]).to match(
|
||||
[
|
||||
hash_including(
|
||||
device: 'vda',
|
||||
absolute_path: '/var/lib/libvirt/images/vagrant-test_default.img'
|
||||
),
|
||||
hash_including(
|
||||
device: 'vdb',
|
||||
absolute_path: '/var/lib/libvirt/images/vagrant-test_default_1.img'
|
||||
),
|
||||
hash_including(
|
||||
device: 'vdc',
|
||||
absolute_path: '/var/lib/libvirt/images/vagrant-test_default_2.img'
|
||||
),
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
context 'when additional storage in domain config' do
|
||||
let(:domain_xml_file) { 'multi_volume_box_additional_storage.xml' }
|
||||
let(:vagrantfile_providerconfig) do
|
||||
<<-EOF
|
||||
libvirt.storage :file, :size => '20G'
|
||||
libvirt.storage :file, :size => '20G'
|
||||
EOF
|
||||
end
|
||||
|
||||
it 'should populate disks with devices' do
|
||||
expect(subject.call(env)).to be_nil
|
||||
expect(env[:disks]).to match(
|
||||
[
|
||||
hash_including(
|
||||
device: 'vdd',
|
||||
absolute_path: '/var/lib/libvirt/images/vagrant-test_default-vdd.qcow2'
|
||||
),
|
||||
hash_including(
|
||||
device: 'vde',
|
||||
absolute_path: '/var/lib/libvirt/images/vagrant-test_default-vde.qcow2'
|
||||
),
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no aliases available' do
|
||||
let(:domain_xml_file) { 'default_no_aliases.xml' }
|
||||
|
||||
it 'should assume a single box volume' do
|
||||
expect(subject.call(env)).to be_nil
|
||||
expect(env[:domain_volumes]).to match(
|
||||
[
|
||||
hash_including(
|
||||
device: 'vda',
|
||||
absolute_path: '/var/lib/libvirt/images/vagrant-test_default.img'
|
||||
),
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
context 'when additional storage and a custom disk device attached' do
|
||||
let(:domain_xml_file) { 'multi_volume_box_additional_and_custom_no_aliases.xml' }
|
||||
let(:vagrantfile_providerconfig) do
|
||||
<<-EOF
|
||||
libvirt.storage :file, :size => '20G'
|
||||
libvirt.storage :file, :size => '20G'
|
||||
EOF
|
||||
end
|
||||
|
||||
it 'should detect the domain volumes and disks while ignoring the last one' do
|
||||
expect(subject.call(env)).to be_nil
|
||||
expect(env[:domain_volumes]).to match(
|
||||
[
|
||||
hash_including(
|
||||
device: 'vda',
|
||||
absolute_path: '/var/lib/libvirt/images/vagrant-test_default.img'
|
||||
),
|
||||
hash_including(
|
||||
device: 'vdb',
|
||||
absolute_path: '/var/lib/libvirt/images/vagrant-test_default_1.img'
|
||||
),
|
||||
hash_including(
|
||||
device: 'vdc',
|
||||
absolute_path: '/var/lib/libvirt/images/vagrant-test_default_2.img'
|
||||
),
|
||||
]
|
||||
)
|
||||
expect(env[:disks]).to match(
|
||||
[
|
||||
hash_including(
|
||||
device: 'vdd',
|
||||
absolute_path: '/var/lib/libvirt/images/vagrant-test_default-vdd.qcow2'
|
||||
),
|
||||
hash_including(
|
||||
device: 'vde',
|
||||
absolute_path: '/var/lib/libvirt/images/vagrant-test_default-vde.qcow2'
|
||||
),
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'no default pool' do
|
||||
let(:domain_xml_file) { 'default_domain.xml' }
|
||||
let(:vagrantfile) do
|
||||
<<-EOF
|
||||
Vagrant.configure('2') do |config|
|
||||
config.vm.define :test
|
||||
end
|
||||
EOF
|
||||
end
|
||||
|
||||
it 'should raise an exception' do
|
||||
expect(libvirt_client).to receive(:lookup_domain_by_uuid).and_return(libvirt_domain)
|
||||
expect(libvirt_domain).to receive(:xml_desc).and_return(domain_xml)
|
||||
expect(libvirt_client).to receive(:lookup_storage_pool_by_name).and_return(nil)
|
||||
|
||||
expect { subject.call(env) }.to raise_error(VagrantPlugins::ProviderLibvirt::Errors::NoStoragePool)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no box defined' do
|
||||
let(:domain_xml_file) { 'default_domain.xml' }
|
||||
let(:storage_pool_xml_file) { 'default_system_storage_pool.xml' }
|
||||
let(:vagrantfile) do
|
||||
<<-EOF
|
||||
Vagrant.configure('2') do |config|
|
||||
config.vm.define :test
|
||||
config.vm.provider :libvirt do |libvirt|
|
||||
libvirt.storage :file, :size => '20G'
|
||||
end
|
||||
end
|
||||
EOF
|
||||
end
|
||||
|
||||
it 'should query for domain name and storage pool path' do
|
||||
expect(libvirt_client).to receive(:lookup_domain_by_uuid).and_return(libvirt_domain)
|
||||
expect(libvirt_domain).to receive(:xml_desc).and_return(domain_xml)
|
||||
expect(libvirt_client).to receive(:lookup_storage_pool_by_name).and_return(libvirt_storage_pool)
|
||||
expect(libvirt_storage_pool).to receive(:xml_desc).and_return(storage_pool_xml)
|
||||
|
||||
expect(subject.call(env)).to be_nil
|
||||
expect(env[:disks]).to match(
|
||||
[
|
||||
hash_including(
|
||||
device: 'vda',
|
||||
cache: 'default',
|
||||
bus: 'virtio',
|
||||
path: 'vagrant-test_default-vda.qcow2',
|
||||
absolute_path: '/var/lib/libvirt/images/vagrant-test_default-vda.qcow2',
|
||||
size: '20G',
|
||||
pool: 'default'
|
||||
),
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,43 @@
|
||||
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
|
||||
<name>vagrant-test_default</name>
|
||||
<title></title>
|
||||
<description>Source: /rootpath/Vagrantfile</description>
|
||||
<uuid></uuid>
|
||||
<memory>524288</memory>
|
||||
<vcpu>1</vcpu>
|
||||
<cpu mode='host-model'>
|
||||
<model fallback='allow'></model>
|
||||
</cpu>
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
<kernel></kernel>
|
||||
<initrd></initrd>
|
||||
<cmdline></cmdline>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset='utc'>
|
||||
</clock>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<alias name='ua-box-volume-0'/>
|
||||
<driver name='qemu' type='qcow2' cache='default'/>
|
||||
<source file='/var/lib/libvirt/images/vagrant-test_default.img'/>
|
||||
<target dev='vda' bus='virtio'/>
|
||||
</disk>
|
||||
<serial type='pty'>
|
||||
<target port='0'/>
|
||||
</serial>
|
||||
<console type='pty'>
|
||||
<target port='0'/>
|
||||
</console>
|
||||
<input type='mouse' bus='ps2'/>
|
||||
<graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us'/>
|
||||
<video>
|
||||
<model type='cirrus' vram='16384' heads='1'/>
|
||||
</video>
|
||||
</devices>
|
||||
</domain>
|
||||
@@ -0,0 +1,42 @@
|
||||
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
|
||||
<name>vagrant-test_default</name>
|
||||
<title></title>
|
||||
<description>Source: /rootpath/Vagrantfile</description>
|
||||
<uuid></uuid>
|
||||
<memory>524288</memory>
|
||||
<vcpu>1</vcpu>
|
||||
<cpu mode='host-model'>
|
||||
<model fallback='allow'></model>
|
||||
</cpu>
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
<kernel></kernel>
|
||||
<initrd></initrd>
|
||||
<cmdline></cmdline>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset='utc'>
|
||||
</clock>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='qemu' type='qcow2' cache='default'/>
|
||||
<source file='/var/lib/libvirt/images/vagrant-test_default.img'/>
|
||||
<target dev='vda' bus='virtio'/>
|
||||
</disk>
|
||||
<serial type='pty'>
|
||||
<target port='0'/>
|
||||
</serial>
|
||||
<console type='pty'>
|
||||
<target port='0'/>
|
||||
</console>
|
||||
<input type='mouse' bus='ps2'/>
|
||||
<graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us'/>
|
||||
<video>
|
||||
<model type='cirrus' vram='16384' heads='1'/>
|
||||
</video>
|
||||
</devices>
|
||||
</domain>
|
||||
@@ -0,0 +1,55 @@
|
||||
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
|
||||
<name>vagrant-test_default</name>
|
||||
<title></title>
|
||||
<description>Source: /rootpath/Vagrantfile</description>
|
||||
<uuid></uuid>
|
||||
<memory>524288</memory>
|
||||
<vcpu>1</vcpu>
|
||||
<cpu mode='host-model'>
|
||||
<model fallback='allow'></model>
|
||||
</cpu>
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
<kernel></kernel>
|
||||
<initrd></initrd>
|
||||
<cmdline></cmdline>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset='utc'>
|
||||
</clock>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<alias name='ua-box-volume-0'/>
|
||||
<driver name='qemu' type='qcow2' cache='default'/>
|
||||
<source file='/var/lib/libvirt/images/vagrant-test_default.img'/>
|
||||
<target dev='vda' bus='virtio'/>
|
||||
</disk>
|
||||
<disk type='file' device='disk'>
|
||||
<alias name='ua-box-volume-1'/>
|
||||
<driver name='qemu' type='qcow2' cache='default'/>
|
||||
<source file='/var/lib/libvirt/images/vagrant-test_default_1.img'/>
|
||||
<target dev='vdb' bus='virtio'/>
|
||||
</disk>
|
||||
<disk type='file' device='disk'>
|
||||
<alias name='ua-box-volume-2'/>
|
||||
<driver name='qemu' type='qcow2' cache='default'/>
|
||||
<source file='/var/lib/libvirt/images/vagrant-test_default_2.img'/>
|
||||
<target dev='vdc' bus='virtio'/>
|
||||
</disk>
|
||||
<serial type='pty'>
|
||||
<target port='0'/>
|
||||
</serial>
|
||||
<console type='pty'>
|
||||
<target port='0'/>
|
||||
</console>
|
||||
<input type='mouse' bus='ps2'/>
|
||||
<graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us'/>
|
||||
<video>
|
||||
<model type='cirrus' vram='16384' heads='1'/>
|
||||
</video>
|
||||
</devices>
|
||||
</domain>
|
||||
@@ -0,0 +1,67 @@
|
||||
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
|
||||
<name>vagrant-test_default</name>
|
||||
<title></title>
|
||||
<description>Source: /rootpath/Vagrantfile</description>
|
||||
<uuid></uuid>
|
||||
<memory>524288</memory>
|
||||
<vcpu>1</vcpu>
|
||||
<cpu mode='host-model'>
|
||||
<model fallback='allow'></model>
|
||||
</cpu>
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
<kernel></kernel>
|
||||
<initrd></initrd>
|
||||
<cmdline></cmdline>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset='utc'>
|
||||
</clock>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='qemu' type='qcow2' cache='default'/>
|
||||
<source file='/var/lib/libvirt/images/vagrant-test_default.img'/>
|
||||
<target dev='vda' bus='virtio'/>
|
||||
</disk>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='qemu' type='qcow2' cache='default'/>
|
||||
<source file='/var/lib/libvirt/images/vagrant-test_default_1.img'/>
|
||||
<target dev='vdb' bus='virtio'/>
|
||||
</disk>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='qemu' type='qcow2' cache='default'/>
|
||||
<source file='/var/lib/libvirt/images/vagrant-test_default_2.img'/>
|
||||
<target dev='vdc' bus='virtio'/>
|
||||
</disk>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='qemu' type='qcow2' cache='default'/>
|
||||
<source file='/var/lib/libvirt/images/vagrant-test_default-vdd.qcow2'/>
|
||||
<target dev='vdd' bus='virtio'/>
|
||||
</disk>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='qemu' type='qcow2' cache='default'/>
|
||||
<source file='/var/lib/libvirt/images/vagrant-test_default-vde.qcow2'/>
|
||||
<target dev='vde' bus='virtio'/>
|
||||
</disk>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='qemu' type='qcow2' cache='default'/>
|
||||
<source file='/var/lib/libvirt/images/vagrant-test_default-vdf.qcow2'/>
|
||||
<target dev='vdf' bus='virtio'/>
|
||||
</disk>
|
||||
<serial type='pty'>
|
||||
<target port='0'/>
|
||||
</serial>
|
||||
<console type='pty'>
|
||||
<target port='0'/>
|
||||
</console>
|
||||
<input type='mouse' bus='ps2'/>
|
||||
<graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us'/>
|
||||
<video>
|
||||
<model type='cirrus' vram='16384' heads='1'/>
|
||||
</video>
|
||||
</devices>
|
||||
</domain>
|
||||
@@ -0,0 +1,67 @@
|
||||
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
|
||||
<name>vagrant-test_default</name>
|
||||
<title></title>
|
||||
<description>Source: /rootpath/Vagrantfile</description>
|
||||
<uuid></uuid>
|
||||
<memory>524288</memory>
|
||||
<vcpu>1</vcpu>
|
||||
<cpu mode='host-model'>
|
||||
<model fallback='allow'></model>
|
||||
</cpu>
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
<kernel></kernel>
|
||||
<initrd></initrd>
|
||||
<cmdline></cmdline>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset='utc'>
|
||||
</clock>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<alias name='ua-box-volume-0'/>
|
||||
<driver name='qemu' type='qcow2' cache='default'/>
|
||||
<source file='/var/lib/libvirt/images/vagrant-test_default.img'/>
|
||||
<target dev='vda' bus='virtio'/>
|
||||
</disk>
|
||||
<disk type='file' device='disk'>
|
||||
<alias name='ua-box-volume-1'/>
|
||||
<driver name='qemu' type='qcow2' cache='default'/>
|
||||
<source file='/var/lib/libvirt/images/vagrant-test_default_1.img'/>
|
||||
<target dev='vdb' bus='virtio'/>
|
||||
</disk>
|
||||
<disk type='file' device='disk'>
|
||||
<alias name='ua-box-volume-2'/>
|
||||
<driver name='qemu' type='qcow2' cache='default'/>
|
||||
<source file='/var/lib/libvirt/images/vagrant-test_default_2.img'/>
|
||||
<target dev='vdc' bus='virtio'/>
|
||||
</disk>
|
||||
<disk type='file' device='disk'>
|
||||
<alias name='ua-disk-volume-0'/>
|
||||
<driver name='qemu' type='qcow2' cache='default'/>
|
||||
<source file='/var/lib/libvirt/images/vagrant-test_default-vdd.qcow2'/>
|
||||
<target dev='vdd' bus='virtio'/>
|
||||
</disk>
|
||||
<disk type='file' device='disk'>
|
||||
<alias name='ua-disk-volume-1'/>
|
||||
<driver name='qemu' type='qcow2' cache='default'/>
|
||||
<source file='/var/lib/libvirt/images/vagrant-test_default-vde.qcow2'/>
|
||||
<target dev='vde' bus='virtio'/>
|
||||
</disk>
|
||||
<serial type='pty'>
|
||||
<target port='0'/>
|
||||
</serial>
|
||||
<console type='pty'>
|
||||
<target port='0'/>
|
||||
</console>
|
||||
<input type='mouse' bus='ps2'/>
|
||||
<graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us'/>
|
||||
<video>
|
||||
<model type='cirrus' vram='16384' heads='1'/>
|
||||
</video>
|
||||
</devices>
|
||||
</domain>
|
||||
@@ -62,13 +62,13 @@ describe 'templates/domain' do
|
||||
:dev => 'vda',
|
||||
:cache => 'unsafe',
|
||||
:bus => domain.disk_bus,
|
||||
:path => '/var/lib/libvirt/images/test.qcow2'
|
||||
:absolute_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'
|
||||
:absolute_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')
|
||||
|
||||
@@ -78,6 +78,14 @@ cleanup() {
|
||||
[ "$status" -eq 0 ]
|
||||
echo "${output}"
|
||||
[ $(expr "$output" : ".*second_disk_default-vdb.*") -ne 0 ]
|
||||
run ${VAGRANT_CMD} halt
|
||||
echo "${output}"
|
||||
echo "status = ${status}"
|
||||
[ "$status" -eq 0 ]
|
||||
run ${VAGRANT_CMD} up ${VAGRANT_OPT}
|
||||
echo "${output}"
|
||||
echo "status = ${status}"
|
||||
[ "$status" -eq 0 ]
|
||||
cleanup
|
||||
}
|
||||
|
||||
|
||||
1
tests/second_disk/Vagrantfile
vendored
1
tests/second_disk/Vagrantfile
vendored
@@ -6,6 +6,7 @@
|
||||
Vagrant.configure("2") do |config|
|
||||
config.vm.box = "infernix/tinycore"
|
||||
config.ssh.shell = "/bin/sh"
|
||||
config.ssh.insert_key = false # needed for testing halt as inserted key is persisted
|
||||
config.vm.synced_folder ".", "/vagrant", disabled: true
|
||||
|
||||
config.vm.provider :libvirt do |libvirt|
|
||||
|
||||
Reference in New Issue
Block a user